@housekit/orm 0.1.47 → 0.1.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -5
- package/dist/builders/delete.js +112 -0
- package/dist/builders/insert.d.ts +0 -91
- package/dist/builders/insert.js +393 -0
- package/dist/builders/prepared.d.ts +1 -2
- package/dist/builders/prepared.js +30 -0
- package/dist/builders/select.d.ts +0 -161
- package/dist/builders/select.js +562 -0
- package/dist/builders/select.types.js +1 -0
- package/dist/builders/update.js +136 -0
- package/dist/client.d.ts +0 -6
- package/dist/client.js +140 -0
- package/dist/codegen/zod.js +107 -0
- package/dist/column.d.ts +1 -25
- package/dist/column.js +133 -0
- package/dist/compiler.d.ts +0 -7
- package/dist/compiler.js +513 -0
- package/dist/core.js +6 -0
- package/dist/data-types.d.ts +0 -61
- package/dist/data-types.js +127 -0
- package/dist/dictionary.d.ts +0 -149
- package/dist/dictionary.js +158 -0
- package/dist/engines.d.ts +0 -385
- package/dist/engines.js +292 -0
- package/dist/expressions.d.ts +0 -10
- package/dist/expressions.js +268 -0
- package/dist/external.d.ts +0 -112
- package/dist/external.js +224 -0
- package/dist/index.d.ts +0 -51
- package/dist/index.js +139 -6853
- package/dist/logger.js +36 -0
- package/dist/materialized-views.d.ts +0 -188
- package/dist/materialized-views.js +380 -0
- package/dist/metadata.js +59 -0
- package/dist/modules/aggregates.d.ts +0 -164
- package/dist/modules/aggregates.js +121 -0
- package/dist/modules/array.d.ts +0 -98
- package/dist/modules/array.js +71 -0
- package/dist/modules/conditional.d.ts +0 -84
- package/dist/modules/conditional.js +138 -0
- package/dist/modules/conversion.d.ts +0 -147
- package/dist/modules/conversion.js +109 -0
- package/dist/modules/geo.d.ts +0 -164
- package/dist/modules/geo.js +112 -0
- package/dist/modules/hash.js +4 -0
- package/dist/modules/index.js +12 -0
- package/dist/modules/json.d.ts +0 -106
- package/dist/modules/json.js +76 -0
- package/dist/modules/math.d.ts +0 -16
- package/dist/modules/math.js +16 -0
- package/dist/modules/string.d.ts +0 -136
- package/dist/modules/string.js +89 -0
- package/dist/modules/time.d.ts +0 -123
- package/dist/modules/time.js +91 -0
- package/dist/modules/types.d.ts +0 -133
- package/dist/modules/types.js +114 -0
- package/dist/modules/window.js +140 -0
- package/dist/relational.d.ts +0 -82
- package/dist/relational.js +290 -0
- package/dist/relations.js +21 -0
- package/dist/schema-builder.d.ts +0 -90
- package/dist/schema-builder.js +140 -0
- package/dist/table.d.ts +0 -42
- package/dist/table.js +406 -0
- package/dist/utils/background-batcher.js +75 -0
- package/dist/utils/batch-transform.js +51 -0
- package/dist/utils/binary-reader.d.ts +0 -6
- package/dist/utils/binary-reader.js +334 -0
- package/dist/utils/binary-serializer.d.ts +0 -125
- package/dist/utils/binary-serializer.js +637 -0
- package/dist/utils/binary-worker-code.js +1 -0
- package/dist/utils/binary-worker-pool.d.ts +0 -34
- package/dist/utils/binary-worker-pool.js +206 -0
- package/dist/utils/binary-worker.d.ts +0 -11
- package/dist/utils/binary-worker.js +63 -0
- package/dist/utils/insert-processing.d.ts +0 -2
- package/dist/utils/insert-processing.js +163 -0
- package/dist/utils/lru-cache.js +30 -0
- package/package.json +68 -3
package/README.md
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
**The high-performance, type-safe ClickHouse ORM for Node.js and Bun.**
|
|
4
4
|
|
|
5
|
-
> ⚠️ **Public Beta**: This package is currently in public beta. Feedback is highly appreciated as we polish
|
|
5
|
+
> ⚠️ **Public Beta**: This package is currently in public beta. Feedback is highly appreciated as we polish API for v1.0.
|
|
6
6
|
|
|
7
|
-
> 💡 **Interactive Docs**: Use [RepoGrep](https://app.ami.dev/repogrep?repo=https://github.com/pablofdezr/housekit) to search and query
|
|
7
|
+
> 💡 **Interactive Docs**: Use [RepoGrep](https://app.ami.dev/repogrep?repo=https://github.com/pablofdezr/housekit) to search and query entire codebase and documentation for free (Updated instantly).
|
|
8
8
|
|
|
9
|
-
> 💡 **Ask ZRead**: Need deep insights? [Ask ZRead](https://zread.ai/pablofdezr/housekit) for AI-powered understanding of
|
|
9
|
+
> 💡 **Ask ZRead**: Need deep insights? [Ask ZRead](https://zread.ai/pablofdezr/housekit) for AI-powered understanding of codebase (Updated weekly).
|
|
10
10
|
|
|
11
|
-
> 💡 **Ask Devin AI**: Have questions about integrating HouseKit? [Ask
|
|
11
|
+
> 💡 **Ask Devin AI**: Have questions about integrating HouseKit? [Ask Wiki](https://deepwiki.com/pablofdezr/housekit) for AI-powered assistance (Updated weekly).
|
|
12
12
|
|
|
13
|
-
HouseKit ORM is a modern database toolkit designed specifically for ClickHouse. It bridges
|
|
13
|
+
HouseKit ORM is a modern database toolkit designed specifically for ClickHouse. It bridges gap between ergonomic developer experiences and extreme performance requirements of high-volume OLAP workloads.
|
|
14
14
|
|
|
15
|
+
[](https://www.npmjs.com/package/@housekit/orm)
|
|
15
16
|
[](https://www.npmjs.com/package/@housekit/orm)
|
|
16
17
|
[](https://opensource.org/licenses/MIT)
|
|
17
18
|
[](https://app.ami.dev/repogrep?repo=https://github.com/pablofdezr/housekit)
|
|
@@ -127,6 +128,86 @@ const [user] = await db
|
|
|
127
128
|
|
|
128
129
|
---
|
|
129
130
|
|
|
131
|
+
## 🎯 The `housekit()` Client
|
|
132
|
+
|
|
133
|
+
The `housekit()` function creates a fully-featured ClickHouse client with query builders for all operations.
|
|
134
|
+
|
|
135
|
+
### Client Methods
|
|
136
|
+
|
|
137
|
+
| Method | Description |
|
|
138
|
+
|--------|-------------|
|
|
139
|
+
| **`db.select()`** | Creates a SELECT query builder |
|
|
140
|
+
| **`db.insert(table)`** | Inserts data into a table |
|
|
141
|
+
| **`db.insertMany(table, data, opts)`** | Bulk inserts with configuration |
|
|
142
|
+
| **`db.update(table)`** | Updates rows in a table |
|
|
143
|
+
| **`db.delete(table)`** | Deletes rows from a table |
|
|
144
|
+
| **`db.raw(sql, params)`** | Executes raw SQL queries |
|
|
145
|
+
| **`db.command({query, query_params})`** | Executes ClickHouse commands |
|
|
146
|
+
| **`db.close()`** | Closes the connection |
|
|
147
|
+
|
|
148
|
+
### Client Properties
|
|
149
|
+
|
|
150
|
+
| Property | Description |
|
|
151
|
+
|----------|-------------|
|
|
152
|
+
| **`db.rawClient`** | Raw `@clickhouse/client` instance (direct access) |
|
|
153
|
+
| **`db.query`** ⭐ | **Relational API** - only available if `{ schema }` is passed |
|
|
154
|
+
| **`db.schema`** | Your defined table schema |
|
|
155
|
+
|
|
156
|
+
### ⭐ The Relational API (`db.query`)
|
|
157
|
+
|
|
158
|
+
**Only available when you pass a schema:**
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const db = housekit({ url: 'http://localhost:8123' }, {
|
|
162
|
+
schema: { users, events }
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Then you can query using ORM-style methods:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// Find by ID
|
|
170
|
+
db.query.users.findById('uuid-here');
|
|
171
|
+
|
|
172
|
+
// Find many with conditions
|
|
173
|
+
db.query.users.findMany({ where: { role: 'admin' } });
|
|
174
|
+
|
|
175
|
+
// Find first with columns
|
|
176
|
+
db.query.users.findFirst({ columns: { id: true, email: true } });
|
|
177
|
+
|
|
178
|
+
// Find with relations (automatic JOIN)
|
|
179
|
+
db.query.users.findMany({
|
|
180
|
+
with: { posts: true }
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Complete Example
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
const db = housekit({ url: 'http://localhost:8123' }, { schema });
|
|
188
|
+
|
|
189
|
+
// 1. Insert using builder
|
|
190
|
+
await db.insert(schema.users).values({ email: 'a@b.com', role: 'admin' });
|
|
191
|
+
|
|
192
|
+
// 2. Regular SELECT
|
|
193
|
+
const result = await db.select().from(schema.users).where(eq(schema.users.role, 'admin'));
|
|
194
|
+
|
|
195
|
+
// 3. Relational query (automatic JOIN)
|
|
196
|
+
const user = await db.query.users.findById('uuid-here', {
|
|
197
|
+
with: { posts: true }
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// 4. Raw SQL
|
|
201
|
+
const data = await db.raw('SELECT * FROM users LIMIT 10');
|
|
202
|
+
|
|
203
|
+
// 5. Close connection
|
|
204
|
+
await db.close();
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
130
211
|
## 🔍 Relational Query API
|
|
131
212
|
|
|
132
213
|
### findMany / findFirst
|
|
@@ -326,6 +407,40 @@ await db.select()
|
|
|
326
407
|
|
|
327
408
|
---
|
|
328
409
|
|
|
410
|
+
## 📦 Bundle Size & Performance
|
|
411
|
+
|
|
412
|
+
HouseKit is optimized for minimal bundle impact in your applications:
|
|
413
|
+
|
|
414
|
+
| Metric | Value |
|
|
415
|
+
|--------|-------|
|
|
416
|
+
| **Tarball Size** | 96KB |
|
|
417
|
+
| **Unpacked Size** | 644KB |
|
|
418
|
+
| **Tree Shaking** | ✅ Enabled |
|
|
419
|
+
| **Granular Exports** | 17 paths for precise imports |
|
|
420
|
+
|
|
421
|
+
### Optimizations
|
|
422
|
+
|
|
423
|
+
- **Modular Build**: 46 separate JS files vs 1 monolithic bundle
|
|
424
|
+
- **Tree-Shakable**: Consumers can eliminate unused code automatically
|
|
425
|
+
- **Granular Exports**: Import only what you need
|
|
426
|
+
- **No Runtime Overhead**: Zero runtime dependency overhead
|
|
427
|
+
|
|
428
|
+
### Import Examples
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
// Import everything (full bundle)
|
|
432
|
+
import { housekit, Engine, t } from '@housekit/orm';
|
|
433
|
+
|
|
434
|
+
// Import specific modules only (recommended for tree-shaking)
|
|
435
|
+
import { Engine } from '@housekit/orm/engines';
|
|
436
|
+
import { defineTable, t } from '@housekit/orm/schema-builder';
|
|
437
|
+
import { ClickHouseColumn } from '@housekit/orm/column';
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
**Note**: While HouseKit includes advanced features like binary serialization, engines, and relations (96KB), the modular structure ensures your bundle only includes what you actually use.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
329
444
|
## 🛠 SQL Utilities
|
|
330
445
|
|
|
331
446
|
### Dynamic Queries
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { eq } from '../expressions';
|
|
2
|
+
import { and } from '../modules/conditional';
|
|
3
|
+
export class ClickHouseDeleteBuilder {
|
|
4
|
+
client;
|
|
5
|
+
table;
|
|
6
|
+
_where = null;
|
|
7
|
+
_lastMutationId = null;
|
|
8
|
+
constructor(client, table) {
|
|
9
|
+
this.client = client;
|
|
10
|
+
this.table = table;
|
|
11
|
+
}
|
|
12
|
+
where(expression) {
|
|
13
|
+
if (!expression)
|
|
14
|
+
return this;
|
|
15
|
+
if (typeof expression === 'object' && 'toSQL' in expression) {
|
|
16
|
+
this._where = expression;
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
if (typeof expression === 'object') {
|
|
20
|
+
const chunks = [];
|
|
21
|
+
for (const [key, value] of Object.entries(expression)) {
|
|
22
|
+
const column = this.table.$columns[key];
|
|
23
|
+
if (column && value !== undefined) {
|
|
24
|
+
chunks.push(eq(column, value));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (chunks.length > 0) {
|
|
28
|
+
const combined = chunks.length === 1 ? chunks[0] : and(...chunks);
|
|
29
|
+
if (combined)
|
|
30
|
+
this._where = combined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
toSQL() {
|
|
36
|
+
if (this.table.$options.appendOnly !== false) {
|
|
37
|
+
throw new Error(`DELETE is blocked for append-only table ${this.table.$table}. Set appendOnly: false to allow.`);
|
|
38
|
+
}
|
|
39
|
+
if (!this._where) {
|
|
40
|
+
throw new Error("❌ DELETE requires a WHERE clause in ClickHouse (safety first!)");
|
|
41
|
+
}
|
|
42
|
+
const { sql, params } = this._where.toSQL({ ignoreTablePrefix: true });
|
|
43
|
+
const tableName = this.table.$table;
|
|
44
|
+
return {
|
|
45
|
+
query: `ALTER TABLE \`${tableName}\` DELETE WHERE ${sql}`,
|
|
46
|
+
params
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async execute() {
|
|
50
|
+
const { query, params } = this.toSQL();
|
|
51
|
+
await this.client.command({
|
|
52
|
+
query,
|
|
53
|
+
query_params: params,
|
|
54
|
+
});
|
|
55
|
+
this._lastMutationId = await fetchLatestMutationId(this.client, this.table.$table);
|
|
56
|
+
}
|
|
57
|
+
async wait(options) {
|
|
58
|
+
if (!this._lastMutationId) {
|
|
59
|
+
await this.execute();
|
|
60
|
+
}
|
|
61
|
+
if (!this._lastMutationId)
|
|
62
|
+
return;
|
|
63
|
+
await waitForMutationCompletion(this.client, this.table.$table, this._lastMutationId, options);
|
|
64
|
+
}
|
|
65
|
+
async then(onfulfilled, onrejected) {
|
|
66
|
+
try {
|
|
67
|
+
await this.execute();
|
|
68
|
+
if (onfulfilled) {
|
|
69
|
+
return Promise.resolve(onfulfilled());
|
|
70
|
+
}
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (onrejected) {
|
|
75
|
+
return Promise.resolve(onrejected(error));
|
|
76
|
+
}
|
|
77
|
+
return Promise.reject(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function fetchLatestMutationId(client, tableName) {
|
|
82
|
+
const result = await client.query({
|
|
83
|
+
query: `SELECT mutation_id FROM system.mutations WHERE database = currentDatabase() AND table = {table:String} ORDER BY create_time DESC LIMIT 1 FORMAT JSONEachRow`,
|
|
84
|
+
query_params: { table: tableName }
|
|
85
|
+
});
|
|
86
|
+
const rows = await result.json();
|
|
87
|
+
return rows[0]?.mutation_id ?? null;
|
|
88
|
+
}
|
|
89
|
+
async function waitForMutationCompletion(client, tableName, mutationId, options) {
|
|
90
|
+
const pollInterval = options?.pollIntervalMs ?? 500;
|
|
91
|
+
const timeout = options?.timeoutMs ?? 60_000;
|
|
92
|
+
const start = Date.now();
|
|
93
|
+
while (true) {
|
|
94
|
+
const result = await client.query({
|
|
95
|
+
query: `SELECT is_done, latest_failed_part, latest_fail_reason FROM system.mutations WHERE database = currentDatabase() AND table = {table:String} AND mutation_id = {mid:String} FORMAT JSONEachRow`,
|
|
96
|
+
query_params: { table: tableName, mid: mutationId }
|
|
97
|
+
});
|
|
98
|
+
const rows = await result.json();
|
|
99
|
+
const row = rows[0];
|
|
100
|
+
if (!row)
|
|
101
|
+
return;
|
|
102
|
+
if (row.latest_fail_reason) {
|
|
103
|
+
throw new Error(`Mutation ${mutationId} failed: ${row.latest_fail_reason}`);
|
|
104
|
+
}
|
|
105
|
+
if (row.is_done === 1)
|
|
106
|
+
return;
|
|
107
|
+
if (Date.now() - start > timeout) {
|
|
108
|
+
throw new Error(`Mutation ${mutationId} not completed after ${timeout}ms`);
|
|
109
|
+
}
|
|
110
|
+
await new Promise(res => setTimeout(res, pollInterval));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -8,7 +8,6 @@ export interface BinaryInsertConfig {
|
|
|
8
8
|
username: string;
|
|
9
9
|
password: string;
|
|
10
10
|
database: string;
|
|
11
|
-
/** Skip validation for maximum performance */
|
|
12
11
|
skipValidation?: boolean;
|
|
13
12
|
}
|
|
14
13
|
export declare class ClickHouseInsertBuilder<TTable extends TableRuntime<any, any>, TReturn = any> {
|
|
@@ -26,116 +25,26 @@ export declare class ClickHouseInsertBuilder<TTable extends TableRuntime<any, an
|
|
|
26
25
|
private _isSingle;
|
|
27
26
|
private _skipValidation;
|
|
28
27
|
constructor(client: ClickHouseClient, table: TTable, connectionConfig?: BinaryInsertConfig | undefined);
|
|
29
|
-
/**
|
|
30
|
-
* Skip enum validation for maximum performance.
|
|
31
|
-
* Use in production when you trust your data source.
|
|
32
|
-
*/
|
|
33
28
|
skipValidation(): this;
|
|
34
29
|
values(value: CleanInsert<TTable> | Array<CleanInsert<TTable>> | Iterable<CleanInsert<TTable>> | AsyncIterable<CleanInsert<TTable>> | Readable): ClickHouseInsertBuilder<TTable, TReturn>;
|
|
35
|
-
/** @template [T = CleanInsert<TTable>] */
|
|
36
30
|
insert(data: CleanInsert<TTable> | CleanInsert<TTable>[]): Promise<TReturn>;
|
|
37
|
-
/**
|
|
38
|
-
* Return inserted data as an array.
|
|
39
|
-
* Use when inserting multiple rows.
|
|
40
|
-
*/
|
|
41
31
|
returning(): ClickHouseInsertBuilder<TTable, CleanSelect<TTable>[]>;
|
|
42
|
-
/**
|
|
43
|
-
* Return the single inserted row directly (not wrapped in array).
|
|
44
|
-
* Use when inserting a single value for cleaner syntax.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* const user = await db.insert(users).values({ email: 'a@b.com' }).returningOne();
|
|
48
|
-
*/
|
|
49
32
|
returningOne(): ClickHouseInsertBuilder<TTable, CleanSelect<TTable>>;
|
|
50
|
-
/**
|
|
51
|
-
* Disable the default returning() behavior.
|
|
52
|
-
* Useful when you don't need the inserted data back and want to avoid the overhead.
|
|
53
|
-
*/
|
|
54
33
|
noReturning(): ClickHouseInsertBuilder<TTable, void>;
|
|
55
|
-
/**
|
|
56
|
-
* Force synchronous insert (disables async_insert).
|
|
57
|
-
* This is already the default in HouseKit for best performance.
|
|
58
|
-
*/
|
|
59
34
|
syncInsert(): this;
|
|
60
|
-
/**
|
|
61
|
-
* Enable asynchronous inserts on the server (not the default).
|
|
62
|
-
* ClickHouse will batch multiple small inserts into a single disk operation.
|
|
63
|
-
*
|
|
64
|
-
* Note: Sync insert is faster for most use cases. Use async only when
|
|
65
|
-
* you need server-side batching for very high-frequency writes.
|
|
66
|
-
*/
|
|
67
35
|
asyncInsert(waitForCompletion?: boolean): this;
|
|
68
|
-
/**
|
|
69
|
-
* Activate Background Batching (Client-side buffering).
|
|
70
|
-
*
|
|
71
|
-
* Instead of sending request immediately, rows are buffered in memory
|
|
72
|
-
* and sent when limit is reached or interval passes.
|
|
73
|
-
*
|
|
74
|
-
* @param options Batch configuration
|
|
75
|
-
*/
|
|
76
36
|
batch(options?: Partial<BatchConfig>): this;
|
|
77
|
-
/** Configure batch processing options */
|
|
78
37
|
batchOptions(options: BatchTransformOptions): this;
|
|
79
|
-
/**
|
|
80
|
-
* Set the batch size for streaming inserts.
|
|
81
|
-
* Larger batches = better throughput, higher memory usage.
|
|
82
|
-
* Default: 1000
|
|
83
|
-
*/
|
|
84
38
|
batchSize(size: number): this;
|
|
85
|
-
/**
|
|
86
|
-
* Add a row to the background batcher.
|
|
87
|
-
*
|
|
88
|
-
* If batching is not yet configured, it will use default settings
|
|
89
|
-
* (10,000 rows or 5 seconds).
|
|
90
|
-
*
|
|
91
|
-
* Note: This method is "fire-and-forget" and does not wait for
|
|
92
|
-
* the database to acknowledge the insert.
|
|
93
|
-
*/
|
|
94
39
|
append(row: CleanInsert<TTable>): Promise<void>;
|
|
95
|
-
/**
|
|
96
|
-
* Use JSON format explicitly (this is already the default).
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* await db.insert(events)
|
|
101
|
-
* .values(rows)
|
|
102
|
-
* .useJsonFormat()
|
|
103
|
-
* .execute();
|
|
104
|
-
* ```
|
|
105
|
-
*/
|
|
106
40
|
useJsonFormat(): this;
|
|
107
|
-
/**
|
|
108
|
-
* Use JSONCompactEachRow format (smaller payload than JSON).
|
|
109
|
-
*/
|
|
110
41
|
useCompactFormat(): this;
|
|
111
|
-
/**
|
|
112
|
-
* Force RowBinary format.
|
|
113
|
-
* Uses direct HTTP request (bypasses official client).
|
|
114
|
-
*/
|
|
115
42
|
useBinaryFormat(): this;
|
|
116
|
-
/**
|
|
117
|
-
* Alias for useBinaryFormat().
|
|
118
|
-
* @deprecated Binary format is not faster than JSON with the official client.
|
|
119
|
-
*/
|
|
120
43
|
turbo(): this;
|
|
121
44
|
execute(): Promise<TReturn>;
|
|
122
|
-
/**
|
|
123
|
-
* Resolve the actual format to use based on settings.
|
|
124
|
-
* Default is JSON (most reliable and well-optimized by the official client).
|
|
125
|
-
*/
|
|
126
45
|
private resolveFormat;
|
|
127
|
-
/**
|
|
128
|
-
* Execute insert using JSON format
|
|
129
|
-
*/
|
|
130
46
|
private executeJsonInsert;
|
|
131
|
-
/**
|
|
132
|
-
* Execute insert using RowBinary format (fastest)
|
|
133
|
-
* Uses direct HTTP request since the official client doesn't support RowBinary yet
|
|
134
|
-
*/
|
|
135
47
|
private executeBinaryInsert;
|
|
136
|
-
/**
|
|
137
|
-
* Process rows and yield them with column names mapped and defaults applied
|
|
138
|
-
*/
|
|
139
48
|
private processRows;
|
|
140
49
|
private collectReturningRows;
|
|
141
50
|
private assertReturningRow;
|