rado 0.0.0 → 0.1.1

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/dist/Formatter.js CHANGED
@@ -65,6 +65,12 @@ var Formatter = class {
65
65
  return this.formatDelete(query, ctx);
66
66
  case QueryType.CreateTable:
67
67
  return this.formatCreateTable(query, ctx);
68
+ case QueryType.CreateIndex:
69
+ return this.formatCreateIndex(query, ctx);
70
+ case QueryType.DropIndex:
71
+ return this.formatDropIndex(query, ctx);
72
+ case QueryType.AlterTable:
73
+ return this.formatAlterTable(query, ctx);
68
74
  case QueryType.Transaction:
69
75
  return this.formatTransaction(query, ctx);
70
76
  case QueryType.Batch:
@@ -114,6 +120,29 @@ var Formatter = class {
114
120
  })
115
121
  );
116
122
  }
123
+ formatCreateIndex(query, ctx = {}) {
124
+ return raw("create index").addIf(query.ifNotExists, "if not exists").addIdentifier(query.index.name).add("on").addIdentifier(query.table.name).parenthesis(
125
+ separated(
126
+ query.index.on.map(
127
+ (expr) => this.formatExprValue(expr, { ...ctx, skipTableName: true })
128
+ )
129
+ )
130
+ ).add(this.formatWhere(query.where, ctx));
131
+ }
132
+ formatDropIndex(query, ctx) {
133
+ return raw("drop index").addIf(query.ifExists, "if exists").addIdentifier(query.index.name);
134
+ }
135
+ formatAlterTable(query, ctx) {
136
+ let stmt = raw("alter table").addIdentifier(query.table.name);
137
+ if (query.addColumn) {
138
+ stmt = stmt.add("add column").add(this.formatColumn(query.addColumn));
139
+ } else if (query.dropColumn) {
140
+ stmt = stmt.add("drop column").addIdentifier(query.dropColumn);
141
+ } else if (query.alterColumn) {
142
+ throw new Error(`Not available in this formatter: alter column`);
143
+ }
144
+ return stmt;
145
+ }
117
146
  formatTransaction({ op, id }, ctx) {
118
147
  switch (op) {
119
148
  case Query.TransactionOperation.Begin:
@@ -131,23 +160,32 @@ var Formatter = class {
131
160
  );
132
161
  }
133
162
  formatRaw({ strings, params }, ctx) {
134
- return Statement.ofTemplate(strings, params);
163
+ return Statement.tag(strings, ...params);
135
164
  }
136
165
  formatColumn(column) {
137
166
  return identifier(column.name).add(this.formatType(column.type)).addIf(column.unique, "unique").addIf(column.autoIncrement, "autoincrement").addIf(column.primaryKey, "primary key").addIf(!column.nullable, "not null").addIf(
138
167
  column.defaultValue !== void 0,
139
- raw("default").value(column.defaultValue)
140
- );
168
+ raw("default").add(this.formatInlineValue(column.defaultValue))
169
+ ).addIf(column.references, () => {
170
+ return this.formatContraintReference(column.references);
171
+ });
172
+ }
173
+ formatContraintReference(reference) {
174
+ if (reference.type !== ExprType.Field || reference.expr.type !== ExprType.Row)
175
+ throw new Error("not supported");
176
+ const from = reference.expr.target;
177
+ return raw("references").addIdentifier(Target.source(from).name).parenthesis(identifier(reference.field));
141
178
  }
142
179
  formatType(type) {
143
180
  switch (type) {
144
181
  case ColumnType.String:
145
- case ColumnType.Object:
146
- case ColumnType.Array:
147
182
  return raw("text");
183
+ case ColumnType.Json:
184
+ return raw("json");
148
185
  case ColumnType.Number:
149
- case ColumnType.Boolean:
150
186
  return raw("numeric");
187
+ case ColumnType.Boolean:
188
+ return raw("boolean");
151
189
  case ColumnType.Integer:
152
190
  return raw("integer");
153
191
  }
@@ -184,14 +222,10 @@ var Formatter = class {
184
222
  if (typeof columnValue !== "boolean")
185
223
  throw new TypeError(`Expected boolean for column ${column.name}`);
186
224
  return value(columnValue);
187
- case ColumnType.Object:
225
+ case ColumnType.Json:
188
226
  if (typeof columnValue !== "object")
189
227
  throw new TypeError(`Expected object for column ${column.name}`);
190
228
  return value(JSON.stringify(columnValue));
191
- case ColumnType.Array:
192
- if (!Array.isArray(columnValue))
193
- throw new TypeError(`Expected array for column ${column.name}`);
194
- return value(JSON.stringify(columnValue));
195
229
  }
196
230
  }
197
231
  formatTarget(target, ctx) {
@@ -283,13 +317,10 @@ var Formatter = class {
283
317
  case ExprType.Row:
284
318
  switch (expr.target.type) {
285
319
  case TargetType.Table:
286
- const selection = identifier(
287
- expr.target.table.alias || expr.target.table.name
288
- ).raw(".").identifier(field);
320
+ const selection = ctx.skipTableName ? identifier(field) : identifier(expr.target.table.alias || expr.target.table.name).raw(".").identifier(field);
289
321
  const column = expr.target.table.columns[field];
290
322
  switch (column?.type) {
291
- case ColumnType.Array:
292
- case ColumnType.Object:
323
+ case ColumnType.Json:
293
324
  return call("json", selection);
294
325
  default:
295
326
  return selection;
@@ -306,6 +337,18 @@ var Formatter = class {
306
337
  formatString(input) {
307
338
  return raw(this.escapeValue(String(input)));
308
339
  }
340
+ formatInlineValue(rawValue) {
341
+ switch (true) {
342
+ case (rawValue === null || rawValue === void 0):
343
+ return raw("null");
344
+ case typeof rawValue === "boolean":
345
+ return rawValue ? raw("true") : raw("false");
346
+ case (typeof rawValue === "string" || typeof rawValue === "number"):
347
+ return this.formatString(rawValue);
348
+ default:
349
+ return this.formatString(JSON.stringify(rawValue));
350
+ }
351
+ }
309
352
  formatValue(rawValue, formatAsJson) {
310
353
  switch (true) {
311
354
  case (rawValue === null || rawValue === void 0):
@@ -407,7 +450,7 @@ var Formatter = class {
407
450
  return call(
408
451
  "json_object",
409
452
  ...Object.entries(expr.fields).map(([key, value2]) => {
410
- return this.formatString(key).raw(",").newline().concat(this.formatExpr(value2, { ...ctx, formatAsJson: true }));
453
+ return this.formatString(key).raw(", ").concat(this.formatExpr(value2, { ...ctx, formatAsJson: true }));
411
454
  })
412
455
  );
413
456
  case ExprType.Filter: {
package/dist/Ops.js CHANGED
@@ -2,38 +2,37 @@
2
2
  import { Cursor } from "./Cursor.js";
3
3
  import { ExprData } from "./Expr.js";
4
4
  import { Query } from "./Query.js";
5
+ import { Schema } from "./Schema.js";
5
6
  import { Target } from "./Target.js";
6
7
  function selectAll(table) {
7
8
  return new Cursor.SelectMultiple(
8
9
  Query.Select({
9
- from: Target.Table(table.data()),
10
- selection: ExprData.Row(Target.Table(table.data()))
10
+ from: Target.Table(table.schema()),
11
+ selection: ExprData.Row(Target.Table(table.schema()))
11
12
  })
12
13
  );
13
14
  }
14
15
  function selectFirst(table) {
15
16
  return new Cursor.SelectSingle(
16
17
  Query.Select({
17
- from: Target.Table(table.data()),
18
- selection: ExprData.Row(Target.Table(table.data())),
18
+ from: Target.Table(table.schema()),
19
+ selection: ExprData.Row(Target.Table(table.schema())),
19
20
  singleResult: true
20
21
  })
21
22
  );
22
23
  }
23
24
  function update(table) {
24
- return new Cursor.Update(Query.Update({ table: table.data() }));
25
+ return new Cursor.Update(Query.Update({ table: table.schema() }));
25
26
  }
26
27
  function insertInto(table) {
27
- return new Cursor.Insert(table.data());
28
+ return new Cursor.Insert(table.schema());
28
29
  }
29
30
  function deleteFrom(table) {
30
- return new Cursor.Delete(Query.Delete({ table: table.data() }));
31
+ return new Cursor.Delete(Query.Delete({ table: table.schema() }));
31
32
  }
32
33
  function create(...tables) {
33
34
  return new Cursor.Batch(
34
- tables.map(
35
- (table) => Query.CreateTable({ table: table.data(), ifNotExists: true })
36
- )
35
+ tables.flatMap((table) => Schema.create(table.schema()).queries)
37
36
  );
38
37
  }
39
38
  export {
package/dist/Query.d.ts CHANGED
@@ -1,6 +1,7 @@
1
+ import { ColumnData } from './Column';
1
2
  import { ExprData } from './Expr';
2
3
  import { OrderBy } from './OrderBy';
3
- import { TableData } from './Table';
4
+ import { Index, Schema } from './Schema';
4
5
  import { Target } from './Target';
5
6
  export declare const enum QueryType {
6
7
  Insert = "Insert",
@@ -8,11 +9,14 @@ export declare const enum QueryType {
8
9
  Update = "Update",
9
10
  Delete = "Delete",
10
11
  CreateTable = "CreateTable",
12
+ CreateIndex = "CreateIndex",
13
+ DropIndex = "DropIndex",
14
+ AlterTable = "AlterTable",
11
15
  Batch = "Batch",
12
16
  Transaction = "Transaction",
13
17
  Raw = "Raw"
14
18
  }
15
- export type Query<T = any> = Query.Insert | Query.Select | Query.Update | Query.Delete | Query.CreateTable | Query.Batch | Query.Transaction | Query.Raw;
19
+ export type Query<T = any> = Query.Insert | Query.Select | Query.Update | Query.Delete | Query.CreateTable | Query.CreateIndex | Query.DropIndex | Query.AlterTable | Query.Batch | Query.Transaction | Query.Raw;
16
20
  export declare namespace Query {
17
21
  interface QueryBase {
18
22
  limit?: number;
@@ -27,42 +31,52 @@ export declare namespace Query {
27
31
  }
28
32
  interface Insert extends QueryBase {
29
33
  type: QueryType.Insert;
30
- into: TableData;
34
+ into: Schema;
31
35
  data: Array<any>;
32
36
  }
33
- function Insert<T>(insert: Omit<Insert, 'type'>): Query<T>;
37
+ function Insert(insert: Omit<Insert, 'type'>): Query.Insert;
34
38
  interface Select extends QueryBase {
35
39
  type: QueryType.Select;
36
40
  selection: ExprData;
37
41
  from: Target;
38
42
  }
39
- function Select<T>(select: Omit<Select, 'type'>): Query<T>;
43
+ function Select(select: Omit<Select, 'type'>): Query.Select;
40
44
  interface Update extends QueryBase {
41
45
  type: QueryType.Update;
42
- table: TableData;
46
+ table: Schema;
43
47
  set?: Record<string, any>;
44
48
  }
45
- function Update<T>(update: Omit<Update, 'type'>): Query<{
46
- rowsAffected: number;
47
- }>;
49
+ function Update(update: Omit<Update, 'type'>): Query.Update;
48
50
  interface Delete extends QueryBase {
49
51
  type: QueryType.Delete;
50
- table: TableData;
52
+ table: Schema;
51
53
  }
52
- function Delete<T>(del: Omit<Delete, 'type'>): Query<{
53
- rowsAffected: number;
54
- }>;
54
+ function Delete(del: Omit<Delete, 'type'>): Query.Delete;
55
55
  interface CreateTable extends QueryBase {
56
56
  type: QueryType.CreateTable;
57
- table: TableData;
57
+ table: Schema;
58
58
  ifNotExists?: boolean;
59
59
  }
60
- function CreateTable<T>(create: Omit<CreateTable, 'type'>): Query<void>;
60
+ function CreateTable(create: Omit<CreateTable, 'type'>): Query.CreateTable;
61
+ interface CreateIndex extends QueryBase {
62
+ type: QueryType.CreateIndex;
63
+ table: Schema;
64
+ index: Index;
65
+ ifNotExists?: boolean;
66
+ }
67
+ function CreateIndex(create: Omit<CreateIndex, 'type'>): Query.CreateIndex;
68
+ interface DropIndex extends QueryBase {
69
+ type: QueryType.DropIndex;
70
+ table: Schema;
71
+ index: Index;
72
+ ifExists?: boolean;
73
+ }
74
+ function DropIndex(drop: Omit<DropIndex, 'type'>): Query.DropIndex;
61
75
  interface Batch extends QueryBase {
62
76
  type: QueryType.Batch;
63
77
  queries: Array<Query<any>>;
64
78
  }
65
- function Batch<T>(batch: Omit<Batch, 'type'>): Query<void>;
79
+ function Batch(batch: Omit<Batch, 'type'>): Query.Batch;
66
80
  enum TransactionOperation {
67
81
  Begin = "Begin",
68
82
  Commit = "Commit",
@@ -73,7 +87,7 @@ export declare namespace Query {
73
87
  id: string;
74
88
  op: TransactionOperation;
75
89
  }
76
- function Transaction<T>(transaction: Omit<Transaction, 'type'>): Query<T>;
90
+ function Transaction(transaction: Omit<Transaction, 'type'>): Query.Transaction;
77
91
  type RawReturn = 'row' | 'rows' | undefined;
78
92
  interface Raw extends QueryBase {
79
93
  type: QueryType.Raw;
@@ -81,5 +95,13 @@ export declare namespace Query {
81
95
  strings: ReadonlyArray<string>;
82
96
  params: Array<any>;
83
97
  }
84
- function Raw<T>(raw: Omit<Raw, 'type'>): Query<T>;
98
+ function Raw(raw: Omit<Raw, 'type'>): Query.Raw;
99
+ interface AlterTable extends QueryBase {
100
+ type: QueryType.AlterTable;
101
+ table: Schema;
102
+ alterColumn?: ColumnData;
103
+ addColumn?: ColumnData;
104
+ dropColumn?: string;
105
+ }
106
+ function AlterTable(alter: Omit<AlterTable, 'type'>): Query.AlterTable;
85
107
  }
package/dist/Query.js CHANGED
@@ -5,6 +5,9 @@ var QueryType = /* @__PURE__ */ ((QueryType2) => {
5
5
  QueryType2["Update"] = "Update";
6
6
  QueryType2["Delete"] = "Delete";
7
7
  QueryType2["CreateTable"] = "CreateTable";
8
+ QueryType2["CreateIndex"] = "CreateIndex";
9
+ QueryType2["DropIndex"] = "DropIndex";
10
+ QueryType2["AlterTable"] = "AlterTable";
8
11
  QueryType2["Batch"] = "Batch";
9
12
  QueryType2["Transaction"] = "Transaction";
10
13
  QueryType2["Raw"] = "Raw";
@@ -32,6 +35,14 @@ var Query;
32
35
  return { type: "CreateTable" /* CreateTable */, ...create };
33
36
  }
34
37
  Query2.CreateTable = CreateTable;
38
+ function CreateIndex(create) {
39
+ return { type: "CreateIndex" /* CreateIndex */, ...create };
40
+ }
41
+ Query2.CreateIndex = CreateIndex;
42
+ function DropIndex(drop) {
43
+ return { type: "DropIndex" /* DropIndex */, ...drop };
44
+ }
45
+ Query2.DropIndex = DropIndex;
35
46
  function Batch(batch) {
36
47
  return { type: "Batch" /* Batch */, ...batch };
37
48
  }
@@ -50,6 +61,10 @@ var Query;
50
61
  return { type: "Raw" /* Raw */, ...raw };
51
62
  }
52
63
  Query2.Raw = Raw;
64
+ function AlterTable(alter) {
65
+ return { type: "AlterTable" /* AlterTable */, ...alter };
66
+ }
67
+ Query2.AlterTable = AlterTable;
53
68
  })(Query || (Query = {}));
54
69
  export {
55
70
  Query,
@@ -1,4 +1,4 @@
1
1
  export interface Sanitizer {
2
2
  escapeValue(value: any): string;
3
- escapeIdent(ident: string): string;
3
+ escapeIdentifier(ident: string): string;
4
4
  }
@@ -0,0 +1,23 @@
1
+ import { ColumnData } from './Column';
2
+ import { ExprData } from './Expr';
3
+ import { Formatter } from './Formatter';
4
+ import { Query } from './Query';
5
+ export interface Index {
6
+ name: string;
7
+ on: Array<ExprData>;
8
+ where?: ExprData;
9
+ }
10
+ export interface Schema {
11
+ name: string;
12
+ alias?: string;
13
+ columns: Record<string, ColumnData>;
14
+ indexes: Record<string, Index>;
15
+ }
16
+ export interface SchemaInstructions {
17
+ columns: Record<string, string>;
18
+ indexes: Record<string, string>;
19
+ }
20
+ export declare namespace Schema {
21
+ function create(schema: Schema): Query.Batch;
22
+ function upgrade(formatter: Formatter, local: SchemaInstructions, schema: Schema): Array<Query>;
23
+ }
package/dist/Schema.js ADDED
@@ -0,0 +1,60 @@
1
+ // src/Schema.ts
2
+ import { Query } from "./Query.js";
3
+ var Schema;
4
+ ((Schema2) => {
5
+ function create(schema) {
6
+ const queries = [];
7
+ queries.push(Query.CreateTable({ table: schema, ifNotExists: true }));
8
+ for (const index of Object.values(schema.indexes))
9
+ queries.push(Query.CreateIndex({ table: schema, index, ifNotExists: true }));
10
+ return Query.Batch({ queries });
11
+ }
12
+ Schema2.create = create;
13
+ function upgrade(formatter, local, schema) {
14
+ const columnNames = /* @__PURE__ */ new Set([
15
+ ...Object.keys(local.columns),
16
+ ...Object.keys(schema.columns)
17
+ ]);
18
+ const res = [];
19
+ for (const columnName of columnNames) {
20
+ const localInstruction = local.columns[columnName];
21
+ const schemaCol = schema.columns[columnName];
22
+ if (!localInstruction) {
23
+ res.push(Query.AlterTable({ table: schema, addColumn: schemaCol }));
24
+ } else if (!schemaCol) {
25
+ res.push(Query.AlterTable({ table: schema, dropColumn: columnName }));
26
+ } else {
27
+ const [instruction] = formatter.formatColumn({ ...schemaCol, references: void 0 }).compile(formatter);
28
+ if (localInstruction !== instruction) {
29
+ res.push(Query.AlterTable({ table: schema, alterColumn: schemaCol }));
30
+ }
31
+ }
32
+ }
33
+ const indexNames = /* @__PURE__ */ new Set([
34
+ ...Object.keys(local.indexes),
35
+ ...Object.keys(schema.indexes)
36
+ ]);
37
+ for (const indexName of indexNames) {
38
+ const localInstruction = local.indexes[indexName];
39
+ const schemaIndex = schema.indexes[indexName];
40
+ if (!localInstruction) {
41
+ res.push(Query.CreateIndex({ table: schema, index: schemaIndex }));
42
+ } else if (!schemaIndex) {
43
+ res.push(Query.DropIndex({ table: schema, index: schemaIndex }));
44
+ } else {
45
+ const [instruction] = formatter.formatCreateIndex(
46
+ Query.CreateIndex({ table: schema, index: schemaIndex })
47
+ ).compile(formatter);
48
+ if (localInstruction !== instruction) {
49
+ res.push(Query.DropIndex({ table: schema, index: schemaIndex }));
50
+ res.push(Query.CreateIndex({ table: schema, index: schemaIndex }));
51
+ }
52
+ }
53
+ }
54
+ return res;
55
+ }
56
+ Schema2.upgrade = upgrade;
57
+ })(Schema || (Schema = {}));
58
+ export {
59
+ Schema
60
+ };
@@ -21,7 +21,7 @@ export declare class Statement {
21
21
  constructor(tokens: Array<Token>);
22
22
  concat(...tokens: Array<Token | Statement>): Statement;
23
23
  static create(from: string | Statement): Statement;
24
- static ofTemplate(strings: ReadonlyArray<string>, params: Array<any>): Statement;
24
+ static tag(strings: ReadonlyArray<string>, ...params: Array<any>): Statement;
25
25
  space(): Statement;
26
26
  call(method: string, ...args: Array<Statement>): Statement;
27
27
  addCall(method: string, ...args: Array<Statement>): Statement;
@@ -41,7 +41,10 @@ export declare class Statement {
41
41
  separated(input: Array<Statement>, separator?: string): Statement;
42
42
  addSeparated(input: Array<Statement>, separator?: string): Statement;
43
43
  isEmpty(): boolean;
44
- compile(sanitizer: Sanitizer, formatInline?: boolean): [string, Array<any>];
44
+ compile(sanitizer: Sanitizer, formatInline?: boolean): Statement.Compiled;
45
+ }
46
+ export declare namespace Statement {
47
+ type Compiled = [sql: string, params: Array<any>];
45
48
  }
46
49
  export declare function newline(): Statement;
47
50
  export declare function raw(raw: string): Statement;
package/dist/Statement.js CHANGED
@@ -37,7 +37,7 @@ var Statement = class {
37
37
  static create(from) {
38
38
  return typeof from === "string" ? raw(from) : from;
39
39
  }
40
- static ofTemplate(strings, params) {
40
+ static tag(strings, ...params) {
41
41
  return new Statement(
42
42
  strings.flatMap((s, i) => [Token.Raw(s), Token.Value(params[i])]).slice(0, -1)
43
43
  );
@@ -126,7 +126,7 @@ var Statement = class {
126
126
  sql += token.data;
127
127
  break;
128
128
  case "Identifier" /* Identifier */:
129
- sql += sanitizer.escapeIdent(token.data);
129
+ sql += sanitizer.escapeIdentifier(token.data);
130
130
  break;
131
131
  case "Value" /* Value */:
132
132
  if (formatInline) {
package/dist/Table.d.ts CHANGED
@@ -1,18 +1,13 @@
1
- import { Column, ColumnData } from './Column';
1
+ import { Column } from './Column';
2
2
  import { Cursor } from './Cursor';
3
3
  import { Expr } from './Expr';
4
4
  import { Fields } from './Fields';
5
+ import { Schema } from './Schema';
5
6
  import { Update } from './Update';
6
- export interface TableData {
7
- name: string;
8
- alias?: string;
9
- columns: Record<string, ColumnData>;
10
- indexes?: Record<string, Array<Expr<any>>>;
11
- }
12
7
  export declare class Table<T> extends Cursor.SelectMultiple<T> {
13
8
  /** @internal */
14
9
  protected __tableType: T;
15
- constructor(data: TableData);
10
+ constructor(schema: Schema);
16
11
  insertOne(record: Table.Insert<T>): Cursor.Batch<T>;
17
12
  insertAll(data: Array<Table.Insert<T>>): Cursor.InsertValues;
18
13
  set(data: Update<T>): Cursor.Update<T>;
@@ -20,8 +15,7 @@ export declare class Table<T> extends Cursor.SelectMultiple<T> {
20
15
  as(alias: string): Table<T> & Fields<T>;
21
16
  get(name: string): Expr<any>;
22
17
  toExpr(): Expr<T>;
23
- /** @internal */
24
- data(): TableData;
18
+ schema(): Schema;
25
19
  }
26
20
  export declare namespace Table {
27
21
  type Intersection<A, B> = A & B extends infer U ? {
@@ -45,6 +39,10 @@ export interface TableOptions<T> {
45
39
  columns: {
46
40
  [K in keyof T]: Column<T[K]>;
47
41
  };
42
+ indexes?: (this: Fields<T>) => Record<string, {
43
+ on: Array<Expr<any>>;
44
+ where?: Expr<boolean>;
45
+ }>;
48
46
  }
49
47
  export declare function table<T extends {}>(options: TableOptions<T>): Table<T> & Fields<T>;
50
48
  export declare namespace table {
package/dist/Table.js CHANGED
@@ -4,19 +4,19 @@ import { Expr, ExprData } from "./Expr.js";
4
4
  import { Query } from "./Query.js";
5
5
  import { Target } from "./Target.js";
6
6
  var Table = class extends Cursor.SelectMultiple {
7
- constructor(data) {
7
+ constructor(schema) {
8
8
  super(
9
9
  Query.Select({
10
- from: Target.Table(data),
11
- selection: ExprData.Row(Target.Table(data))
10
+ from: Target.Table(schema),
11
+ selection: ExprData.Row(Target.Table(schema))
12
12
  })
13
13
  );
14
- Object.defineProperty(this, "data", {
14
+ Object.defineProperty(this, "schema", {
15
15
  enumerable: false,
16
- value: () => data
16
+ value: () => schema
17
17
  });
18
- if (data.columns)
19
- for (const column of Object.keys(data.columns)) {
18
+ if (schema.columns)
19
+ for (const column of Object.keys(schema.columns)) {
20
20
  Object.defineProperty(this, column, {
21
21
  enumerable: true,
22
22
  get: () => this.get(column)
@@ -31,49 +31,65 @@ var Table = class extends Cursor.SelectMultiple {
31
31
  insertOne(record) {
32
32
  return new Cursor.Batch([
33
33
  Query.Insert({
34
- into: this.data(),
34
+ into: this.schema(),
35
35
  data: [record],
36
- selection: ExprData.Row(Target.Table(this.data())),
36
+ selection: ExprData.Row(Target.Table(this.schema())),
37
37
  singleResult: true
38
38
  })
39
39
  ]);
40
40
  }
41
41
  insertAll(data) {
42
- return new Cursor.Insert(this.data()).values(...data);
42
+ return new Cursor.Insert(this.schema()).values(...data);
43
43
  }
44
44
  set(data) {
45
45
  return new Cursor.Update(
46
46
  Query.Update({
47
- table: this.data()
47
+ table: this.schema()
48
48
  })
49
49
  ).set(data);
50
50
  }
51
51
  createTable() {
52
- return new Cursor.Create(this.data());
52
+ return new Cursor.Create(this.schema());
53
53
  }
54
54
  as(alias) {
55
- return new Table({ ...this.data(), alias });
55
+ return new Table({ ...this.schema(), alias });
56
56
  }
57
57
  get(name) {
58
58
  return new Expr(ExprData.Field(this.toExpr().expr, name));
59
59
  }
60
60
  toExpr() {
61
- return new Expr(ExprData.Row(Target.Table(this.data())));
61
+ return new Expr(ExprData.Row(Target.Table(this.schema())));
62
62
  }
63
- /** @internal */
64
- data() {
63
+ schema() {
65
64
  throw new Error("Not implemented");
66
65
  }
67
66
  };
68
67
  function table(options) {
69
- return new Table({
68
+ const schema = {
70
69
  ...options,
71
70
  columns: Object.fromEntries(
72
71
  Object.entries(options.columns).map(([key, column]) => {
73
72
  const { data } = column;
74
73
  return [key, { ...data, name: data.name || key }];
75
74
  })
76
- )
75
+ ),
76
+ indexes: {}
77
+ };
78
+ const indexes = Object.fromEntries(
79
+ Object.entries(
80
+ options.indexes ? options.indexes.call(
81
+ new Expr(ExprData.Row(Target.Table(schema)))
82
+ ) : {}
83
+ ).map(([key, index]) => {
84
+ return [
85
+ key,
86
+ { name: key, on: index.on.map(ExprData.create), where: index.where?.expr }
87
+ ];
88
+ })
89
+ );
90
+ return new Table({
91
+ ...schema,
92
+ indexes
77
93
  });
78
94
  }
79
95
  export {
package/dist/Target.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ExprData } from './Expr';
2
- import { TableData } from './Table';
2
+ import { Schema } from './Schema';
3
3
  export declare const enum TargetType {
4
4
  Each = "Each",
5
5
  Table = "Table",
@@ -15,9 +15,9 @@ export declare namespace Target {
15
15
  function Each(expr: ExprData, alias: string): Each;
16
16
  interface Table {
17
17
  type: TargetType.Table;
18
- table: TableData;
18
+ table: Schema;
19
19
  }
20
- function Table(table: TableData): Table;
20
+ function Table(table: Schema): Table;
21
21
  interface Join {
22
22
  type: TargetType.Join;
23
23
  left: Target;
@@ -26,5 +26,5 @@ export declare namespace Target {
26
26
  on: ExprData;
27
27
  }
28
28
  function Join(left: Target, right: Target, joinType: 'left' | 'inner', on: ExprData): Join;
29
- function source(from: Target): TableData | undefined;
29
+ function source(from: Target): Schema | undefined;
30
30
  }
@@ -1,12 +1,17 @@
1
1
  import type { Database } from 'better-sqlite3';
2
2
  import { Driver } from '../Driver';
3
- import { Query } from '../Query';
4
- import { SqliteFormatter } from '../sqlite/SqliteFormatter';
3
+ import { SchemaInstructions } from '../Schema';
4
+ import { Statement } from '../Statement';
5
5
  export declare class BetterSqlite3Driver extends Driver.Sync {
6
- private db;
7
- formatter: SqliteFormatter;
6
+ db: Database;
8
7
  constructor(db: Database);
9
- execute(query: Query): any;
8
+ rows<T extends object = object>([sql, params]: Statement.Compiled): Array<T>;
9
+ values([sql, params]: Statement.Compiled): Array<Array<any>>;
10
+ execute([sql, params]: Statement.Compiled): void;
11
+ mutate([sql, params]: Statement.Compiled): {
12
+ rowsAffected: number;
13
+ };
14
+ schemaInstructions(tableName: string): SchemaInstructions | undefined;
10
15
  export(): Uint8Array;
11
16
  }
12
17
  export declare function connect(db: Database): BetterSqlite3Driver;