remult 0.25.8-exp.10 → 0.25.8-exp.12

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.
@@ -0,0 +1,47 @@
1
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
2
+ export class BetterSqlite3DataProvider extends SqliteCoreDataProvider {
3
+ constructor(db) {
4
+ super(() => new BetterSqlite3Command(db), async () => { db.close(); });
5
+ }
6
+ }
7
+ class BetterSqlite3Command {
8
+ db;
9
+ values = {};
10
+ i = 0;
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ async execute(sql) {
15
+ const s = this.db.prepare(sql);
16
+ if (s.reader) {
17
+ return new BetterSqlite3SqlResult(s.all(this.values));
18
+ }
19
+ else {
20
+ const result = s.run(this.values);
21
+ return new BetterSqlite3SqlResult([]);
22
+ }
23
+ }
24
+ addParameterAndReturnSqlToken(val) {
25
+ return this.param(val);
26
+ }
27
+ param(val) {
28
+ if (val instanceof Date)
29
+ val = val.valueOf();
30
+ if (typeof val === "boolean")
31
+ val = val ? 1 : 0;
32
+ const key = ':' + (this.i++);
33
+ this.values[key.substring(1)] = (val);
34
+ return key;
35
+ }
36
+ }
37
+ export class BetterSqlite3SqlResult {
38
+ result;
39
+ constructor(result) {
40
+ this.result = result;
41
+ this.rows = result;
42
+ }
43
+ rows;
44
+ getColumnKeyInResultForIndexInSelect(index) {
45
+ return Object.keys(this.result[0])[index];
46
+ }
47
+ }
@@ -0,0 +1,41 @@
1
+ import { SqliteCoreDataProvider } from "./remult-sqlite-core.js";
2
+ export class BunSqliteDataProvider extends SqliteCoreDataProvider {
3
+ constructor(db) {
4
+ super(() => new BunSqliteCommand(db), async () => { db.close(); });
5
+ }
6
+ }
7
+ class BunSqliteCommand {
8
+ db;
9
+ values = {};
10
+ i = 0;
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ async execute(sql) {
15
+ const s = this.db.query(sql);
16
+ return new BunSqliteSqlResult(s.all(this.values));
17
+ }
18
+ addParameterAndReturnSqlToken(val) {
19
+ return this.param(val);
20
+ }
21
+ param(val) {
22
+ if (val instanceof Date)
23
+ val = val.valueOf();
24
+ if (typeof val === "boolean")
25
+ val = val ? 1 : 0;
26
+ const key = ':' + (this.i++);
27
+ this.values[key] = (val);
28
+ return key;
29
+ }
30
+ }
31
+ class BunSqliteSqlResult {
32
+ result;
33
+ constructor(result) {
34
+ this.result = result;
35
+ this.rows = result;
36
+ }
37
+ rows;
38
+ getColumnKeyInResultForIndexInSelect(index) {
39
+ return Object.keys(this.result[0])[index];
40
+ }
41
+ }
@@ -539,15 +539,17 @@ class KnexBridgeToSQLCommand {
539
539
  constructor(source) {
540
540
  this.source = source;
541
541
  }
542
- values = [];
542
+ values = {};
543
+ i = 0;
543
544
  addParameterAndReturnSqlToken(val) {
544
545
  return this.param(val);
545
546
  }
546
547
  param(val) {
547
548
  if (Array.isArray(val))
548
549
  val = JSON.stringify(val);
549
- this.values.push(val);
550
- return '?';
550
+ const key = ':' + (this.i++);
551
+ this.values[key.substring(1)] = val;
552
+ return key;
551
553
  }
552
554
  async execute(sql) {
553
555
  return await this.source.raw(sql, this.values).then((r) => {
@@ -1,87 +1,7 @@
1
- import { SqlDatabase } from './src/data-providers/sql-database.js';
2
- import { dbNamesOf, shouldNotCreateField, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
3
- import { isAutoIncrement } from './src/remult3/RepositoryImplementation.js';
4
- export class SqlJsDataProvider {
5
- db;
1
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
2
+ export class SqlJsDataProvider extends SqliteCoreDataProvider {
6
3
  constructor(db) {
7
- this.db = db;
8
- }
9
- orderByNullsFirst;
10
- async end() {
11
- ;
12
- (await this.db).close();
13
- }
14
- getLimitSqlSyntax(limit, offset) {
15
- return ' limit ' + limit + ' offset ' + offset;
16
- }
17
- afterMutation;
18
- createCommand() {
19
- return new SqlJsCommand(this.db);
20
- }
21
- transaction(action) {
22
- throw new Error('Method not implemented.');
23
- }
24
- async entityIsUsedForTheFirstTime(entity) {
25
- await this.createTable(entity);
26
- }
27
- async ensureSchema(entities) {
28
- for (const entity of entities) {
29
- await this.createTable(entity);
30
- }
31
- }
32
- async dropTable(entity) {
33
- let e = await dbNamesOf(entity);
34
- let sql = 'drop table if exists ' + e.$entityName;
35
- if (SqlDatabase.LogToConsole)
36
- console.info(sql);
37
- await this.createCommand().execute(sql);
38
- }
39
- addColumnSqlSyntax(x, dbName) {
40
- let result = dbName;
41
- const nullNumber = x.allowNull ? '' : ' default 0 not null';
42
- if (x.valueType == Date)
43
- result += ' integer';
44
- else if (x.valueType == Boolean)
45
- result += ' integer ' + nullNumber;
46
- else if (x.valueType == Number) {
47
- if (!x.valueConverter.fieldTypeInDb)
48
- result += ' real ' + nullNumber;
49
- else
50
- result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
51
- }
52
- else
53
- result += ' text' + (x.allowNull ? ' ' : " default '' not null ");
54
- return result;
55
- }
56
- async createTable(entity) {
57
- let result = '';
58
- let e = await dbNamesOf(entity);
59
- for (const x of entity.fields) {
60
- if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
61
- if (result.length != 0)
62
- result += ',';
63
- result += '\r\n ';
64
- if (isAutoIncrement(x)) {
65
- if (x.key != entity.idMetadata.field.key)
66
- throw 'in web sql, autoincrement is only allowed for primary key';
67
- result += e.$dbNameOf(x) + ' integer primary key autoincrement';
68
- }
69
- else {
70
- result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
71
- if (x.key == entity.idMetadata.field.key) {
72
- result += ' primary key';
73
- }
74
- }
75
- }
76
- }
77
- let sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
78
- if (SqlDatabase.LogToConsole)
79
- console.log(sql);
80
- await this.createCommand().execute(sql);
81
- }
82
- supportsJsonColumnType;
83
- wrapIdentifier(name) {
84
- return name;
4
+ super(() => new SqlJsCommand(db), async () => (await db).close());
85
5
  }
86
6
  }
87
7
  class SqlJsCommand {
@@ -0,0 +1,105 @@
1
+ import { SqlDatabase } from './src/data-providers/sql-database.js';
2
+ import { dbNamesOf, shouldNotCreateField, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
3
+ import { isAutoIncrement } from './src/remult3/RepositoryImplementation.js';
4
+ export class SqliteCoreDataProvider {
5
+ createCommand;
6
+ end;
7
+ constructor(createCommand, end) {
8
+ this.createCommand = createCommand;
9
+ this.end = end;
10
+ }
11
+ orderByNullsFirst;
12
+ getLimitSqlSyntax(limit, offset) {
13
+ return ' limit ' + limit + ' offset ' + offset;
14
+ }
15
+ afterMutation;
16
+ provideMigrationBuilder(builder) {
17
+ let self = this;
18
+ return {
19
+ createTable: async (entity) => {
20
+ builder.addSql(await self.getCreateTableSql(entity));
21
+ },
22
+ addColumn: async (entity, field) => {
23
+ let e = await dbNamesOf(entity);
24
+ let sql = `alter table ${e.$entityName} add column ${self.addColumnSqlSyntax(field, e.$dbNameOf(field))}`;
25
+ builder.addSql(sql);
26
+ }
27
+ };
28
+ }
29
+ async transaction(action) {
30
+ this.createCommand().execute("Begin Transaction");
31
+ try {
32
+ await action(this);
33
+ this.createCommand().execute("Commit");
34
+ }
35
+ catch (err) {
36
+ this.createCommand().execute("Rollback");
37
+ throw err;
38
+ }
39
+ }
40
+ async entityIsUsedForTheFirstTime(entity) {
41
+ }
42
+ async ensureSchema(entities) {
43
+ for (const entity of entities) {
44
+ await this.createTable(entity);
45
+ }
46
+ }
47
+ async dropTable(entity) {
48
+ let e = await dbNamesOf(entity);
49
+ let sql = 'drop table if exists ' + e.$entityName;
50
+ if (SqlDatabase.LogToConsole)
51
+ console.info(sql);
52
+ await this.createCommand().execute(sql);
53
+ }
54
+ addColumnSqlSyntax(x, dbName) {
55
+ let result = dbName;
56
+ const nullNumber = x.allowNull ? '' : ' default 0 not null';
57
+ if (x.valueType == Date)
58
+ result += ' integer';
59
+ else if (x.valueType == Boolean)
60
+ result += ' integer ' + nullNumber;
61
+ else if (x.valueType == Number) {
62
+ if (!x.valueConverter.fieldTypeInDb)
63
+ result += ' numeric ' + nullNumber;
64
+ else
65
+ result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
66
+ }
67
+ else
68
+ result += ' text' + (x.allowNull ? ' ' : " default '' not null ");
69
+ return result;
70
+ }
71
+ async createTable(entity) {
72
+ let sql = await this.getCreateTableSql(entity);
73
+ if (SqlDatabase.LogToConsole)
74
+ console.log(sql);
75
+ await this.createCommand().execute(sql);
76
+ }
77
+ supportsJsonColumnType;
78
+ async getCreateTableSql(entity) {
79
+ let result = '';
80
+ let e = await dbNamesOf(entity);
81
+ for (const x of entity.fields) {
82
+ if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
83
+ if (result.length != 0)
84
+ result += ',';
85
+ result += '\r\n ';
86
+ if (isAutoIncrement(x)) {
87
+ if (x.key != entity.idMetadata.field.key)
88
+ throw 'in web sql, autoincrement is only allowed for primary key';
89
+ result += e.$dbNameOf(x) + ' integer primary key autoincrement';
90
+ }
91
+ else {
92
+ result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
93
+ if (x.key == entity.idMetadata.field.key) {
94
+ result += ' primary key';
95
+ }
96
+ }
97
+ }
98
+ }
99
+ let sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
100
+ return sql;
101
+ }
102
+ wrapIdentifier(name) {
103
+ return name;
104
+ }
105
+ }
@@ -120,7 +120,7 @@ export class SqlDatabase {
120
120
  if (sql.wrapIdentifier)
121
121
  this.wrapIdentifier = (x) => sql.wrapIdentifier(x);
122
122
  if (isOfType(sql, 'provideMigrationBuilder')) {
123
- this.provideMigrationBuilder = sql.provideMigrationBuilder;
123
+ this.provideMigrationBuilder = x => sql.provideMigrationBuilder(x);
124
124
  }
125
125
  if (isOfType(sql, 'end'))
126
126
  this.end = () => sql.end();
@@ -347,6 +347,8 @@ class ActualSQLServerDataProvider {
347
347
  statement += ' returning ' + select;
348
348
  return r.execute(statement).then((sqlResult) => {
349
349
  this.sql._getSourceSql().afterMutation?.();
350
+ if (sqlResult.rows.length != 1)
351
+ throw new Error('Failed to update row with id ' + id + ", rows updated: " + sqlResult.rows.length);
350
352
  return this.buildResultRow(colKeys, sqlResult.rows[0], sqlResult);
351
353
  });
352
354
  }
@@ -1,11 +1,13 @@
1
1
  export {};
2
+ //p1 - implement generic sqlite support better-sqlite3/ bun sqlite
2
3
  //p1 - `preprocessApiFindOptions`, naming - allow find options preprocessor for api calls, to use for authorization
3
4
  //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
4
- //p1 - Make async hooks gracefully handle non async hooks environment
5
- //p1 - implement generic sqlite support better-sqlite3/ bun sqlite
5
+ //p1 - document new sqlite providers
6
6
  //p1 - article auth.js with express
7
7
  //p1 - document offline support
8
+ //p1 - fix getting started article
8
9
  //y2 - should we validate relations
10
+ //y1 - dependency of live query tables
9
11
  //y1 - consider replacing all errors with error classes that extend the base Error class
10
12
  //y2 - should enforce integer - currently we probably round / truncate it
11
13
  /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.25.8-exp.10",
3
+ "version": "0.25.8-exp.12",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -101,6 +101,21 @@
101
101
  "import": "./esm/remult-sql-js.js",
102
102
  "types": "./remult-sql-js.d.ts"
103
103
  },
104
+ "./remult-sqlite-core-js": {
105
+ "require": "./remult-sqlite-core.js",
106
+ "import": "./esm/remult-sqlite-core.js",
107
+ "types": "./remult-sqlite-core.d.ts"
108
+ },
109
+ "./remult-better-sqlite3": {
110
+ "require": "./remult-better-sqlite3.js",
111
+ "import": "./esm/remult-better-sqlite3.js",
112
+ "types": "./remult-better-sqlite3.d.ts"
113
+ },
114
+ "./remult-bun-sqlite": {
115
+ "require": "./remult-bun-sqlite.js",
116
+ "import": "./esm/remult-bun-sqlite.js",
117
+ "types": "./remult-bun-sqlite.d.ts"
118
+ },
104
119
  "./migrations": {
105
120
  "require": "./migrations/index.js",
106
121
  "import": "./esm/migrations/index.js",
@@ -0,0 +1,12 @@
1
+ import type { Database } from 'better-sqlite3';
2
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
3
+ import type { SqlResult } from './src/sql-command.js';
4
+ export declare class BetterSqlite3DataProvider extends SqliteCoreDataProvider {
5
+ constructor(db: Database);
6
+ }
7
+ export declare class BetterSqlite3SqlResult implements SqlResult {
8
+ private result;
9
+ constructor(result: any[]);
10
+ rows: any[];
11
+ getColumnKeyInResultForIndexInSelect(index: number): string;
12
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BetterSqlite3SqlResult = exports.BetterSqlite3DataProvider = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
6
+ var BetterSqlite3DataProvider = /** @class */ (function (_super) {
7
+ tslib_1.__extends(BetterSqlite3DataProvider, _super);
8
+ function BetterSqlite3DataProvider(db) {
9
+ var _this = _super.call(this, function () { return new BetterSqlite3Command(db); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
10
+ db.close();
11
+ return [2 /*return*/];
12
+ }); }); }) || this;
13
+ return _this;
14
+ }
15
+ return BetterSqlite3DataProvider;
16
+ }(remult_sqlite_core_js_1.SqliteCoreDataProvider));
17
+ exports.BetterSqlite3DataProvider = BetterSqlite3DataProvider;
18
+ var BetterSqlite3Command = /** @class */ (function () {
19
+ function BetterSqlite3Command(db) {
20
+ this.db = db;
21
+ this.values = {};
22
+ this.i = 0;
23
+ }
24
+ BetterSqlite3Command.prototype.execute = function (sql) {
25
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
26
+ var s, result;
27
+ return tslib_1.__generator(this, function (_a) {
28
+ s = this.db.prepare(sql);
29
+ if (s.reader) {
30
+ return [2 /*return*/, new BetterSqlite3SqlResult(s.all(this.values))];
31
+ }
32
+ else {
33
+ result = s.run(this.values);
34
+ return [2 /*return*/, new BetterSqlite3SqlResult([])];
35
+ }
36
+ return [2 /*return*/];
37
+ });
38
+ });
39
+ };
40
+ BetterSqlite3Command.prototype.addParameterAndReturnSqlToken = function (val) {
41
+ return this.param(val);
42
+ };
43
+ BetterSqlite3Command.prototype.param = function (val) {
44
+ if (val instanceof Date)
45
+ val = val.valueOf();
46
+ if (typeof val === "boolean")
47
+ val = val ? 1 : 0;
48
+ var key = ':' + (this.i++);
49
+ this.values[key.substring(1)] = (val);
50
+ return key;
51
+ };
52
+ return BetterSqlite3Command;
53
+ }());
54
+ var BetterSqlite3SqlResult = /** @class */ (function () {
55
+ function BetterSqlite3SqlResult(result) {
56
+ this.result = result;
57
+ this.rows = result;
58
+ }
59
+ BetterSqlite3SqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
60
+ return Object.keys(this.result[0])[index];
61
+ };
62
+ return BetterSqlite3SqlResult;
63
+ }());
64
+ exports.BetterSqlite3SqlResult = BetterSqlite3SqlResult;
@@ -0,0 +1,11 @@
1
+ import { SqliteCoreDataProvider } from "./remult-sqlite-core.js";
2
+ type Database = {
3
+ close(): void;
4
+ query(sql: string): {
5
+ all(args?: any): any[];
6
+ };
7
+ };
8
+ export declare class BunSqliteDataProvider extends SqliteCoreDataProvider {
9
+ constructor(db: Database);
10
+ }
11
+ export {};
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BunSqliteDataProvider = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
6
+ var BunSqliteDataProvider = /** @class */ (function (_super) {
7
+ tslib_1.__extends(BunSqliteDataProvider, _super);
8
+ function BunSqliteDataProvider(db) {
9
+ var _this = _super.call(this, function () { return new BunSqliteCommand(db); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
10
+ db.close();
11
+ return [2 /*return*/];
12
+ }); }); }) || this;
13
+ return _this;
14
+ }
15
+ return BunSqliteDataProvider;
16
+ }(remult_sqlite_core_js_1.SqliteCoreDataProvider));
17
+ exports.BunSqliteDataProvider = BunSqliteDataProvider;
18
+ var BunSqliteCommand = /** @class */ (function () {
19
+ function BunSqliteCommand(db) {
20
+ this.db = db;
21
+ this.values = {};
22
+ this.i = 0;
23
+ }
24
+ BunSqliteCommand.prototype.execute = function (sql) {
25
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
26
+ var s;
27
+ return tslib_1.__generator(this, function (_a) {
28
+ s = this.db.query(sql);
29
+ return [2 /*return*/, new BunSqliteSqlResult(s.all(this.values))];
30
+ });
31
+ });
32
+ };
33
+ BunSqliteCommand.prototype.addParameterAndReturnSqlToken = function (val) {
34
+ return this.param(val);
35
+ };
36
+ BunSqliteCommand.prototype.param = function (val) {
37
+ if (val instanceof Date)
38
+ val = val.valueOf();
39
+ if (typeof val === "boolean")
40
+ val = val ? 1 : 0;
41
+ var key = ':' + (this.i++);
42
+ this.values[key] = (val);
43
+ return key;
44
+ };
45
+ return BunSqliteCommand;
46
+ }());
47
+ var BunSqliteSqlResult = /** @class */ (function () {
48
+ function BunSqliteSqlResult(result) {
49
+ this.result = result;
50
+ this.rows = result;
51
+ }
52
+ BunSqliteSqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
53
+ return Object.keys(this.result[0])[index];
54
+ };
55
+ return BunSqliteSqlResult;
56
+ }());
@@ -1030,7 +1030,8 @@ function translateValueAndHandleArrayAndHandleArray(field, val) {
1030
1030
  var KnexBridgeToSQLCommand = /** @class */ (function () {
1031
1031
  function KnexBridgeToSQLCommand(source) {
1032
1032
  this.source = source;
1033
- this.values = [];
1033
+ this.values = {};
1034
+ this.i = 0;
1034
1035
  }
1035
1036
  KnexBridgeToSQLCommand.prototype.addParameterAndReturnSqlToken = function (val) {
1036
1037
  return this.param(val);
@@ -1038,8 +1039,9 @@ var KnexBridgeToSQLCommand = /** @class */ (function () {
1038
1039
  KnexBridgeToSQLCommand.prototype.param = function (val) {
1039
1040
  if (Array.isArray(val))
1040
1041
  val = JSON.stringify(val);
1041
- this.values.push(val);
1042
- return '?';
1042
+ var key = ':' + (this.i++);
1043
+ this.values[key.substring(1)] = val;
1044
+ return key;
1043
1045
  };
1044
1046
  KnexBridgeToSQLCommand.prototype.execute = function (sql) {
1045
1047
  return tslib_1.__awaiter(this, void 0, void 0, function () {
@@ -1,20 +1,5 @@
1
- import type { EntityMetadata } from './src/remult3/remult3.js';
2
- import type { SqlCommand, SqlImplementation } from './src/sql-command.js';
3
1
  import type { Database } from 'sql.js';
4
- export declare class SqlJsDataProvider implements SqlImplementation {
5
- private db;
2
+ import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
3
+ export declare class SqlJsDataProvider extends SqliteCoreDataProvider {
6
4
  constructor(db: Promise<Database>);
7
- orderByNullsFirst?: boolean;
8
- end(): Promise<void>;
9
- getLimitSqlSyntax(limit: number, offset: number): string;
10
- afterMutation?: VoidFunction;
11
- createCommand(): SqlCommand;
12
- transaction(action: (sql: SqlImplementation) => Promise<void>): Promise<void>;
13
- entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
14
- ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
15
- dropTable(entity: EntityMetadata): Promise<void>;
16
- private addColumnSqlSyntax;
17
- createTable(entity: EntityMetadata<any>): Promise<void>;
18
- supportsJsonColumnType?: boolean;
19
- wrapIdentifier?(name: string): string;
20
5
  }
package/remult-sql-js.js CHANGED
@@ -2,175 +2,20 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqlJsDataProvider = void 0;
4
4
  var tslib_1 = require("tslib");
5
- var sql_database_js_1 = require("./src/data-providers/sql-database.js");
6
- var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
7
- var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
8
- var SqlJsDataProvider = /** @class */ (function () {
5
+ var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
6
+ var SqlJsDataProvider = /** @class */ (function (_super) {
7
+ tslib_1.__extends(SqlJsDataProvider, _super);
9
8
  function SqlJsDataProvider(db) {
10
- this.db = db;
9
+ var _this = _super.call(this, function () { return new SqlJsCommand(db); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
10
+ switch (_a.label) {
11
+ case 0: return [4 /*yield*/, db];
12
+ case 1: return [2 /*return*/, (_a.sent()).close()];
13
+ }
14
+ }); }); }) || this;
15
+ return _this;
11
16
  }
12
- SqlJsDataProvider.prototype.end = function () {
13
- return tslib_1.__awaiter(this, void 0, void 0, function () {
14
- return tslib_1.__generator(this, function (_a) {
15
- switch (_a.label) {
16
- case 0:
17
- ;
18
- return [4 /*yield*/, this.db];
19
- case 1:
20
- (_a.sent()).close();
21
- return [2 /*return*/];
22
- }
23
- });
24
- });
25
- };
26
- SqlJsDataProvider.prototype.getLimitSqlSyntax = function (limit, offset) {
27
- return ' limit ' + limit + ' offset ' + offset;
28
- };
29
- SqlJsDataProvider.prototype.createCommand = function () {
30
- return new SqlJsCommand(this.db);
31
- };
32
- SqlJsDataProvider.prototype.transaction = function (action) {
33
- throw new Error('Method not implemented.');
34
- };
35
- SqlJsDataProvider.prototype.entityIsUsedForTheFirstTime = function (entity) {
36
- return tslib_1.__awaiter(this, void 0, void 0, function () {
37
- return tslib_1.__generator(this, function (_a) {
38
- switch (_a.label) {
39
- case 0: return [4 /*yield*/, this.createTable(entity)];
40
- case 1:
41
- _a.sent();
42
- return [2 /*return*/];
43
- }
44
- });
45
- });
46
- };
47
- SqlJsDataProvider.prototype.ensureSchema = function (entities) {
48
- return tslib_1.__awaiter(this, void 0, void 0, function () {
49
- var entities_1, entities_1_1, entity, e_1_1;
50
- var e_1, _a;
51
- return tslib_1.__generator(this, function (_b) {
52
- switch (_b.label) {
53
- case 0:
54
- _b.trys.push([0, 5, 6, 7]);
55
- entities_1 = tslib_1.__values(entities), entities_1_1 = entities_1.next();
56
- _b.label = 1;
57
- case 1:
58
- if (!!entities_1_1.done) return [3 /*break*/, 4];
59
- entity = entities_1_1.value;
60
- return [4 /*yield*/, this.createTable(entity)];
61
- case 2:
62
- _b.sent();
63
- _b.label = 3;
64
- case 3:
65
- entities_1_1 = entities_1.next();
66
- return [3 /*break*/, 1];
67
- case 4: return [3 /*break*/, 7];
68
- case 5:
69
- e_1_1 = _b.sent();
70
- e_1 = { error: e_1_1 };
71
- return [3 /*break*/, 7];
72
- case 6:
73
- try {
74
- if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
75
- }
76
- finally { if (e_1) throw e_1.error; }
77
- return [7 /*endfinally*/];
78
- case 7: return [2 /*return*/];
79
- }
80
- });
81
- });
82
- };
83
- SqlJsDataProvider.prototype.dropTable = function (entity) {
84
- return tslib_1.__awaiter(this, void 0, void 0, function () {
85
- var e, sql;
86
- return tslib_1.__generator(this, function (_a) {
87
- switch (_a.label) {
88
- case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
89
- case 1:
90
- e = _a.sent();
91
- sql = 'drop table if exists ' + e.$entityName;
92
- if (sql_database_js_1.SqlDatabase.LogToConsole)
93
- console.info(sql);
94
- return [4 /*yield*/, this.createCommand().execute(sql)];
95
- case 2:
96
- _a.sent();
97
- return [2 /*return*/];
98
- }
99
- });
100
- });
101
- };
102
- SqlJsDataProvider.prototype.addColumnSqlSyntax = function (x, dbName) {
103
- var result = dbName;
104
- var nullNumber = x.allowNull ? '' : ' default 0 not null';
105
- if (x.valueType == Date)
106
- result += ' integer';
107
- else if (x.valueType == Boolean)
108
- result += ' integer ' + nullNumber;
109
- else if (x.valueType == Number) {
110
- if (!x.valueConverter.fieldTypeInDb)
111
- result += ' real ' + nullNumber;
112
- else
113
- result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
114
- }
115
- else
116
- result += ' text' + (x.allowNull ? ' ' : " default '' not null ");
117
- return result;
118
- };
119
- SqlJsDataProvider.prototype.createTable = function (entity) {
120
- return tslib_1.__awaiter(this, void 0, void 0, function () {
121
- var result, e, _a, _b, x, sql;
122
- var e_2, _c;
123
- return tslib_1.__generator(this, function (_d) {
124
- switch (_d.label) {
125
- case 0:
126
- result = '';
127
- return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
128
- case 1:
129
- e = _d.sent();
130
- try {
131
- for (_a = tslib_1.__values(entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
132
- x = _b.value;
133
- if (!(0, filter_consumer_bridge_to_sql_request_js_1.shouldNotCreateField)(x, e) || (0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
134
- if (result.length != 0)
135
- result += ',';
136
- result += '\r\n ';
137
- if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
138
- if (x.key != entity.idMetadata.field.key)
139
- throw 'in web sql, autoincrement is only allowed for primary key';
140
- result += e.$dbNameOf(x) + ' integer primary key autoincrement';
141
- }
142
- else {
143
- result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
144
- if (x.key == entity.idMetadata.field.key) {
145
- result += ' primary key';
146
- }
147
- }
148
- }
149
- }
150
- }
151
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
152
- finally {
153
- try {
154
- if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
155
- }
156
- finally { if (e_2) throw e_2.error; }
157
- }
158
- sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
159
- if (sql_database_js_1.SqlDatabase.LogToConsole)
160
- console.log(sql);
161
- return [4 /*yield*/, this.createCommand().execute(sql)];
162
- case 2:
163
- _d.sent();
164
- return [2 /*return*/];
165
- }
166
- });
167
- });
168
- };
169
- SqlJsDataProvider.prototype.wrapIdentifier = function (name) {
170
- return name;
171
- };
172
17
  return SqlJsDataProvider;
173
- }());
18
+ }(remult_sqlite_core_js_1.SqliteCoreDataProvider));
174
19
  exports.SqlJsDataProvider = SqlJsDataProvider;
175
20
  var SqlJsCommand = /** @class */ (function () {
176
21
  function SqlJsCommand(db) {
@@ -0,0 +1,21 @@
1
+ import type { EntityMetadata } from './src/remult3/remult3.js';
2
+ import type { SqlCommand, SqlImplementation } from './src/sql-command.js';
3
+ import type { CanBuildMigrations, MigrationBuilder, MigrationCode } from './migrations/migration-types.js';
4
+ export declare class SqliteCoreDataProvider implements SqlImplementation, CanBuildMigrations {
5
+ createCommand: () => SqlCommand;
6
+ end: () => Promise<void>;
7
+ constructor(createCommand: () => SqlCommand, end: () => Promise<void>);
8
+ orderByNullsFirst?: boolean;
9
+ getLimitSqlSyntax(limit: number, offset: number): string;
10
+ afterMutation?: VoidFunction;
11
+ provideMigrationBuilder(builder: MigrationCode): MigrationBuilder;
12
+ transaction(action: (sql: SqlImplementation) => Promise<void>): Promise<void>;
13
+ entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
14
+ ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
15
+ dropTable(entity: EntityMetadata): Promise<void>;
16
+ private addColumnSqlSyntax;
17
+ createTable(entity: EntityMetadata<any>): Promise<void>;
18
+ supportsJsonColumnType?: boolean;
19
+ private getCreateTableSql;
20
+ wrapIdentifier?(name: string): string;
21
+ }
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqliteCoreDataProvider = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var sql_database_js_1 = require("./src/data-providers/sql-database.js");
6
+ var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
7
+ var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
8
+ var SqliteCoreDataProvider = /** @class */ (function () {
9
+ function SqliteCoreDataProvider(createCommand, end) {
10
+ this.createCommand = createCommand;
11
+ this.end = end;
12
+ }
13
+ SqliteCoreDataProvider.prototype.getLimitSqlSyntax = function (limit, offset) {
14
+ return ' limit ' + limit + ' offset ' + offset;
15
+ };
16
+ SqliteCoreDataProvider.prototype.provideMigrationBuilder = function (builder) {
17
+ var _this = this;
18
+ var self = this;
19
+ return {
20
+ createTable: function (entity) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
21
+ var _a, _b;
22
+ return tslib_1.__generator(this, function (_c) {
23
+ switch (_c.label) {
24
+ case 0:
25
+ _b = (_a = builder).addSql;
26
+ return [4 /*yield*/, self.getCreateTableSql(entity)];
27
+ case 1:
28
+ _b.apply(_a, [_c.sent()]);
29
+ return [2 /*return*/];
30
+ }
31
+ });
32
+ }); },
33
+ addColumn: function (entity, field) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
34
+ var e, sql;
35
+ return tslib_1.__generator(this, function (_a) {
36
+ switch (_a.label) {
37
+ case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
38
+ case 1:
39
+ e = _a.sent();
40
+ sql = "alter table ".concat(e.$entityName, " add column ").concat(self.addColumnSqlSyntax(field, e.$dbNameOf(field)));
41
+ builder.addSql(sql);
42
+ return [2 /*return*/];
43
+ }
44
+ });
45
+ }); }
46
+ };
47
+ };
48
+ SqliteCoreDataProvider.prototype.transaction = function (action) {
49
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
50
+ var err_1;
51
+ return tslib_1.__generator(this, function (_a) {
52
+ switch (_a.label) {
53
+ case 0:
54
+ this.createCommand().execute("Begin Transaction");
55
+ _a.label = 1;
56
+ case 1:
57
+ _a.trys.push([1, 3, , 4]);
58
+ return [4 /*yield*/, action(this)];
59
+ case 2:
60
+ _a.sent();
61
+ this.createCommand().execute("Commit");
62
+ return [3 /*break*/, 4];
63
+ case 3:
64
+ err_1 = _a.sent();
65
+ this.createCommand().execute("Rollback");
66
+ throw err_1;
67
+ case 4: return [2 /*return*/];
68
+ }
69
+ });
70
+ });
71
+ };
72
+ SqliteCoreDataProvider.prototype.entityIsUsedForTheFirstTime = function (entity) {
73
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
74
+ return tslib_1.__generator(this, function (_a) {
75
+ return [2 /*return*/];
76
+ });
77
+ });
78
+ };
79
+ SqliteCoreDataProvider.prototype.ensureSchema = function (entities) {
80
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
81
+ var entities_1, entities_1_1, entity, e_1_1;
82
+ var e_1, _a;
83
+ return tslib_1.__generator(this, function (_b) {
84
+ switch (_b.label) {
85
+ case 0:
86
+ _b.trys.push([0, 5, 6, 7]);
87
+ entities_1 = tslib_1.__values(entities), entities_1_1 = entities_1.next();
88
+ _b.label = 1;
89
+ case 1:
90
+ if (!!entities_1_1.done) return [3 /*break*/, 4];
91
+ entity = entities_1_1.value;
92
+ return [4 /*yield*/, this.createTable(entity)];
93
+ case 2:
94
+ _b.sent();
95
+ _b.label = 3;
96
+ case 3:
97
+ entities_1_1 = entities_1.next();
98
+ return [3 /*break*/, 1];
99
+ case 4: return [3 /*break*/, 7];
100
+ case 5:
101
+ e_1_1 = _b.sent();
102
+ e_1 = { error: e_1_1 };
103
+ return [3 /*break*/, 7];
104
+ case 6:
105
+ try {
106
+ if (entities_1_1 && !entities_1_1.done && (_a = entities_1.return)) _a.call(entities_1);
107
+ }
108
+ finally { if (e_1) throw e_1.error; }
109
+ return [7 /*endfinally*/];
110
+ case 7: return [2 /*return*/];
111
+ }
112
+ });
113
+ });
114
+ };
115
+ SqliteCoreDataProvider.prototype.dropTable = function (entity) {
116
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
117
+ var e, sql;
118
+ return tslib_1.__generator(this, function (_a) {
119
+ switch (_a.label) {
120
+ case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
121
+ case 1:
122
+ e = _a.sent();
123
+ sql = 'drop table if exists ' + e.$entityName;
124
+ if (sql_database_js_1.SqlDatabase.LogToConsole)
125
+ console.info(sql);
126
+ return [4 /*yield*/, this.createCommand().execute(sql)];
127
+ case 2:
128
+ _a.sent();
129
+ return [2 /*return*/];
130
+ }
131
+ });
132
+ });
133
+ };
134
+ SqliteCoreDataProvider.prototype.addColumnSqlSyntax = function (x, dbName) {
135
+ var result = dbName;
136
+ var nullNumber = x.allowNull ? '' : ' default 0 not null';
137
+ if (x.valueType == Date)
138
+ result += ' integer';
139
+ else if (x.valueType == Boolean)
140
+ result += ' integer ' + nullNumber;
141
+ else if (x.valueType == Number) {
142
+ if (!x.valueConverter.fieldTypeInDb)
143
+ result += ' numeric ' + nullNumber;
144
+ else
145
+ result += ' ' + x.valueConverter.fieldTypeInDb + ' ' + nullNumber;
146
+ }
147
+ else
148
+ result += ' text' + (x.allowNull ? ' ' : " default '' not null ");
149
+ return result;
150
+ };
151
+ SqliteCoreDataProvider.prototype.createTable = function (entity) {
152
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
153
+ var sql;
154
+ return tslib_1.__generator(this, function (_a) {
155
+ switch (_a.label) {
156
+ case 0: return [4 /*yield*/, this.getCreateTableSql(entity)];
157
+ case 1:
158
+ sql = _a.sent();
159
+ if (sql_database_js_1.SqlDatabase.LogToConsole)
160
+ console.log(sql);
161
+ return [4 /*yield*/, this.createCommand().execute(sql)];
162
+ case 2:
163
+ _a.sent();
164
+ return [2 /*return*/];
165
+ }
166
+ });
167
+ });
168
+ };
169
+ SqliteCoreDataProvider.prototype.getCreateTableSql = function (entity) {
170
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
171
+ var result, e, _a, _b, x, sql;
172
+ var e_2, _c;
173
+ return tslib_1.__generator(this, function (_d) {
174
+ switch (_d.label) {
175
+ case 0:
176
+ result = '';
177
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity)];
178
+ case 1:
179
+ e = _d.sent();
180
+ try {
181
+ for (_a = tslib_1.__values(entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
182
+ x = _b.value;
183
+ if (!(0, filter_consumer_bridge_to_sql_request_js_1.shouldNotCreateField)(x, e) || (0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
184
+ if (result.length != 0)
185
+ result += ',';
186
+ result += '\r\n ';
187
+ if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
188
+ if (x.key != entity.idMetadata.field.key)
189
+ throw 'in web sql, autoincrement is only allowed for primary key';
190
+ result += e.$dbNameOf(x) + ' integer primary key autoincrement';
191
+ }
192
+ else {
193
+ result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
194
+ if (x.key == entity.idMetadata.field.key) {
195
+ result += ' primary key';
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
202
+ finally {
203
+ try {
204
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
205
+ }
206
+ finally { if (e_2) throw e_2.error; }
207
+ }
208
+ sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
209
+ return [2 /*return*/, sql];
210
+ }
211
+ });
212
+ });
213
+ };
214
+ SqliteCoreDataProvider.prototype.wrapIdentifier = function (name) {
215
+ return name;
216
+ };
217
+ return SqliteCoreDataProvider;
218
+ }());
219
+ exports.SqliteCoreDataProvider = SqliteCoreDataProvider;
@@ -20,7 +20,7 @@ var SqlDatabase = /** @class */ (function () {
20
20
  if (sql.wrapIdentifier)
21
21
  this.wrapIdentifier = function (x) { return sql.wrapIdentifier(x); };
22
22
  if ((0, isOfType_js_1.isOfType)(sql, 'provideMigrationBuilder')) {
23
- this.provideMigrationBuilder = sql.provideMigrationBuilder;
23
+ this.provideMigrationBuilder = function (x) { return sql.provideMigrationBuilder(x); };
24
24
  }
25
25
  if ((0, isOfType_js_1.isOfType)(sql, 'end'))
26
26
  this.end = function () { return sql.end(); };
@@ -523,6 +523,8 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
523
523
  return [2 /*return*/, r.execute(statement).then(function (sqlResult) {
524
524
  var _a, _b;
525
525
  (_b = (_a = _this.sql._getSourceSql()).afterMutation) === null || _b === void 0 ? void 0 : _b.call(_a);
526
+ if (sqlResult.rows.length != 1)
527
+ throw new Error('Failed to update row with id ' + id + ", rows updated: " + sqlResult.rows.length);
526
528
  return _this.buildResultRow(colKeys, sqlResult.rows[0], sqlResult);
527
529
  })];
528
530
  }
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ //p1 - implement generic sqlite support better-sqlite3/ bun sqlite
3
4
  //p1 - `preprocessApiFindOptions`, naming - allow find options preprocessor for api calls, to use for authorization
4
5
  //p1 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string}
5
- //p1 - Make async hooks gracefully handle non async hooks environment
6
- //p1 - implement generic sqlite support better-sqlite3/ bun sqlite
6
+ //p1 - document new sqlite providers
7
7
  //p1 - article auth.js with express
8
8
  //p1 - document offline support
9
+ //p1 - fix getting started article
9
10
  //y2 - should we validate relations
11
+ //y1 - dependency of live query tables
10
12
  //y1 - consider replacing all errors with error classes that extend the base Error class
11
13
  //y2 - should enforce integer - currently we probably round / truncate it
12
14
  /*y1 - talk about modules in init express with entities/controllers,initRequest,initApi