remult 0.26.16 → 0.26.18
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/esm/remult-duckdb.js +116 -0
- package/esm/remult-knex/index.js +4 -1
- package/esm/remult-sqlite-core.js +6 -4
- package/esm/src/data-providers/sql-database.js +13 -2
- package/esm/src/remult3/remult3.js +3 -0
- package/package.json +6 -1
- package/remult-duckdb.d.ts +9 -0
- package/remult-duckdb.js +155 -0
- package/remult-knex/index.js +5 -2
- package/remult-sqlite-core.d.ts +5 -3
- package/remult-sqlite-core.js +6 -4
- package/remult-turso.d.ts +1 -1
- package/src/data-providers/sql-database.js +14 -3
- package/src/remult3/remult3.js +3 -0
- package/src/sql-command.d.ts +1 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
|
|
2
|
+
import { ValueConverters, dbNamesOf, } from './index.js';
|
|
3
|
+
import { shouldNotCreateField } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
|
+
import { isAutoIncrement } from './src/remult3/RepositoryImplementation.js';
|
|
5
|
+
export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
6
|
+
constructor(db) {
|
|
7
|
+
super(() => new DuckDBCommand(db), async () => (await db).close(), false, true);
|
|
8
|
+
}
|
|
9
|
+
wrapIdentifier(name) {
|
|
10
|
+
return `"${name}"`;
|
|
11
|
+
}
|
|
12
|
+
async getCreateTableSql(entity) {
|
|
13
|
+
let result = '';
|
|
14
|
+
let e = await dbNamesOf(entity, this.wrapIdentifier);
|
|
15
|
+
let sql = '';
|
|
16
|
+
for (const x of entity.fields) {
|
|
17
|
+
if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
|
|
18
|
+
if (result.length != 0)
|
|
19
|
+
result += ',';
|
|
20
|
+
result += '\r\n ';
|
|
21
|
+
if (isAutoIncrement(x)) {
|
|
22
|
+
const sequenceName = `${entity.dbName}_${x.dbName}_seq`;
|
|
23
|
+
sql += `create sequence if not exists "${sequenceName}";\r\n`;
|
|
24
|
+
result += `${e.$dbNameOf(x)} integer default nextval('${sequenceName}')`;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x), false);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
result += `,\r\n primary key (${entity.idMetadata.fields
|
|
32
|
+
.map((f) => e.$dbNameOf(f))
|
|
33
|
+
.join(',')})`;
|
|
34
|
+
sql +=
|
|
35
|
+
'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
|
|
36
|
+
return sql;
|
|
37
|
+
}
|
|
38
|
+
addColumnSqlSyntax(x, dbName, isAlterColumn) {
|
|
39
|
+
let result = dbName;
|
|
40
|
+
var allowNull = x.allowNull;
|
|
41
|
+
if (allowNull && isAlterColumn) {
|
|
42
|
+
allowNull = false;
|
|
43
|
+
console.log('DuckDB does not support altering columns to allow null on existing tables');
|
|
44
|
+
}
|
|
45
|
+
if (x.valueType == Number) {
|
|
46
|
+
if (!x.valueConverter.fieldTypeInDb)
|
|
47
|
+
result += ' numeric' + (allowNull ? '' : ' default 0 not null');
|
|
48
|
+
else
|
|
49
|
+
result +=
|
|
50
|
+
' ' +
|
|
51
|
+
x.valueConverter.fieldTypeInDb +
|
|
52
|
+
(x.allowNull || isAlterColumn ? '' : ' default 0 not null');
|
|
53
|
+
}
|
|
54
|
+
else if (x.valueType == Date) {
|
|
55
|
+
if (!x.valueConverter.fieldTypeInDb)
|
|
56
|
+
if (x.valueConverter == ValueConverters.DateOnly)
|
|
57
|
+
result += ' date';
|
|
58
|
+
else
|
|
59
|
+
result += ' timestamp';
|
|
60
|
+
else
|
|
61
|
+
result += ' ' + x.valueConverter.fieldTypeInDb;
|
|
62
|
+
}
|
|
63
|
+
else if (x.valueType == Boolean)
|
|
64
|
+
result +=
|
|
65
|
+
' boolean' +
|
|
66
|
+
(x.allowNull || isAlterColumn ? '' : ' default false not null');
|
|
67
|
+
else if (x.valueConverter.fieldTypeInDb) {
|
|
68
|
+
result += ' ' + x.valueConverter.fieldTypeInDb;
|
|
69
|
+
if (!(x.allowNull || isAlterColumn) &&
|
|
70
|
+
x.valueConverter.fieldTypeInDb == 'integer') {
|
|
71
|
+
result += ' default 0 not null';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
result +=
|
|
76
|
+
' varchar' +
|
|
77
|
+
(x.allowNull || isAlterColumn ? '' : " default '' not null");
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
class DuckDBCommand {
|
|
82
|
+
db;
|
|
83
|
+
values = [];
|
|
84
|
+
constructor(db) {
|
|
85
|
+
this.db = db;
|
|
86
|
+
}
|
|
87
|
+
async execute(sql) {
|
|
88
|
+
return new Promise((resolve, error) => {
|
|
89
|
+
this.db.all(sql, ...this.values, (err, rows) => {
|
|
90
|
+
if (err)
|
|
91
|
+
error(err);
|
|
92
|
+
else
|
|
93
|
+
resolve(new DuckDBSqlResult(rows));
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
addParameterAndReturnSqlToken(val) {
|
|
98
|
+
return this.param(val);
|
|
99
|
+
}
|
|
100
|
+
param(val) {
|
|
101
|
+
const key = '?';
|
|
102
|
+
this.values.push(val);
|
|
103
|
+
return key;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
class DuckDBSqlResult {
|
|
107
|
+
result;
|
|
108
|
+
constructor(result) {
|
|
109
|
+
this.result = result;
|
|
110
|
+
this.rows = result;
|
|
111
|
+
}
|
|
112
|
+
rows;
|
|
113
|
+
getColumnKeyInResultForIndexInSelect(index) {
|
|
114
|
+
return Object.keys(this.result[0])[index];
|
|
115
|
+
}
|
|
116
|
+
}
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -138,7 +138,10 @@ class KnexEntityDataProvider {
|
|
|
138
138
|
if (x.isServerExpression) {
|
|
139
139
|
}
|
|
140
140
|
else {
|
|
141
|
-
|
|
141
|
+
let name = e.$dbNameOf(x);
|
|
142
|
+
if (x.options.sqlExpression)
|
|
143
|
+
name = this.knex.raw('?? as ' + x.key, [name]);
|
|
144
|
+
cols.push(name);
|
|
142
145
|
colKeys.push(x);
|
|
143
146
|
}
|
|
144
147
|
}
|
|
@@ -5,10 +5,12 @@ export class SqliteCoreDataProvider {
|
|
|
5
5
|
createCommand;
|
|
6
6
|
end;
|
|
7
7
|
doesNotSupportReturningSyntax;
|
|
8
|
-
|
|
8
|
+
doesNotSupportReturningSyntaxOnlyForUpdate;
|
|
9
|
+
constructor(createCommand, end, doesNotSupportReturningSyntax = false, doesNotSupportReturningSyntaxOnlyForUpdate = false) {
|
|
9
10
|
this.createCommand = createCommand;
|
|
10
11
|
this.end = end;
|
|
11
12
|
this.doesNotSupportReturningSyntax = doesNotSupportReturningSyntax;
|
|
13
|
+
this.doesNotSupportReturningSyntaxOnlyForUpdate = doesNotSupportReturningSyntaxOnlyForUpdate;
|
|
12
14
|
}
|
|
13
15
|
orderByNullsFirst;
|
|
14
16
|
getLimitSqlSyntax(limit, offset) {
|
|
@@ -23,7 +25,7 @@ export class SqliteCoreDataProvider {
|
|
|
23
25
|
},
|
|
24
26
|
addColumn: async (entity, field) => {
|
|
25
27
|
let e = await dbNamesOf(entity, this.wrapIdentifier);
|
|
26
|
-
let sql = `alter table ${e.$entityName} add column ${self.addColumnSqlSyntax(field, e.$dbNameOf(field))}`;
|
|
28
|
+
let sql = `alter table ${e.$entityName} add column ${self.addColumnSqlSyntax(field, e.$dbNameOf(field), true)}`;
|
|
27
29
|
builder.addSql(sql);
|
|
28
30
|
},
|
|
29
31
|
};
|
|
@@ -52,7 +54,7 @@ export class SqliteCoreDataProvider {
|
|
|
52
54
|
console.info(sql);
|
|
53
55
|
await this.createCommand().execute(sql);
|
|
54
56
|
}
|
|
55
|
-
addColumnSqlSyntax(x, dbName) {
|
|
57
|
+
addColumnSqlSyntax(x, dbName, isAlterTable) {
|
|
56
58
|
let result = dbName;
|
|
57
59
|
const nullNumber = x.allowNull ? '' : ' default 0 not null';
|
|
58
60
|
if (x.valueType == Date)
|
|
@@ -90,7 +92,7 @@ export class SqliteCoreDataProvider {
|
|
|
90
92
|
result += e.$dbNameOf(x) + ' integer primary key autoincrement';
|
|
91
93
|
}
|
|
92
94
|
else {
|
|
93
|
-
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
|
|
95
|
+
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x), false);
|
|
94
96
|
if (x.key == entity.idMetadata.field.key) {
|
|
95
97
|
result += ' primary key';
|
|
96
98
|
}
|
|
@@ -76,6 +76,9 @@ export class SqlDatabase {
|
|
|
76
76
|
supportsJsonColumnType: this.sql.supportsJsonColumnType,
|
|
77
77
|
wrapIdentifier: this.wrapIdentifier,
|
|
78
78
|
end: this.end,
|
|
79
|
+
doesNotSupportReturningSyntax: this.sql.doesNotSupportReturningSyntax,
|
|
80
|
+
doesNotSupportReturningSyntaxOnlyForUpdate: this.sql.doesNotSupportReturningSyntaxOnlyForUpdate,
|
|
81
|
+
orderByNullsFirst: this.sql.orderByNullsFirst,
|
|
79
82
|
}));
|
|
80
83
|
}
|
|
81
84
|
finally {
|
|
@@ -315,6 +318,8 @@ class ActualSQLServerDataProvider {
|
|
|
315
318
|
if (colKeys.length > 0)
|
|
316
319
|
select += ', ';
|
|
317
320
|
select += e.$dbNameOf(x);
|
|
321
|
+
if (x.options.sqlExpression)
|
|
322
|
+
select += ' as ' + x.key;
|
|
318
323
|
colKeys.push(x);
|
|
319
324
|
}
|
|
320
325
|
}
|
|
@@ -344,11 +349,17 @@ class ActualSQLServerDataProvider {
|
|
|
344
349
|
Filter.fromEntityFilter(this.entity, idFilter).__applyToConsumer(f);
|
|
345
350
|
statement += await f.resolveWhere();
|
|
346
351
|
let { colKeys, select } = this.buildSelect(e);
|
|
347
|
-
|
|
352
|
+
let returning = true;
|
|
353
|
+
if (this.sql._getSourceSql().doesNotSupportReturningSyntax)
|
|
354
|
+
returning = false;
|
|
355
|
+
if (returning &&
|
|
356
|
+
this.sql._getSourceSql().doesNotSupportReturningSyntaxOnlyForUpdate)
|
|
357
|
+
returning = false;
|
|
358
|
+
if (returning)
|
|
348
359
|
statement += ' returning ' + select;
|
|
349
360
|
return r.execute(statement).then((sqlResult) => {
|
|
350
361
|
this.sql._getSourceSql().afterMutation?.();
|
|
351
|
-
if (
|
|
362
|
+
if (!returning) {
|
|
352
363
|
return getRowAfterUpdate(this.entity, this, data, id, 'update');
|
|
353
364
|
}
|
|
354
365
|
if (sqlResult.rows.length != 1)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const flags = {
|
|
2
2
|
error500RetryCount: 4,
|
|
3
3
|
};
|
|
4
|
+
//y1 - 'test expression columns without aliases'
|
|
5
|
+
//p1 - see if I can fix the no alias problem in selects
|
|
4
6
|
//p1 - add luid - it's cool for order by.
|
|
5
7
|
//p1 - replace uuid with crypto.randomUUID and allow custom fallback
|
|
6
8
|
//p1 - add nanoid
|
|
@@ -11,6 +13,7 @@ export const flags = {
|
|
|
11
13
|
//p1 - add LifecycleEvent to documentation
|
|
12
14
|
//y1 - Talk about the case where we had one to many, without a field - just a filter - for example, event,event participants, users - and a field that shows all users that are not participants
|
|
13
15
|
//p1 - Fix hagai and starter project to latest ts
|
|
16
|
+
//y1 - talk about the $ sign in my filter rules - no other orm uses that (part of sql work, with $ etc)
|
|
14
17
|
//y1 TODO - discuss next auth withRemult paradox - the gift that keeps on giving - it's doing something crazy there!!
|
|
15
18
|
//p1 - fix chaining of saving and saved in multiple entity options args
|
|
16
19
|
//p1 - review starter and examples and separate remult * auth from the routes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.18",
|
|
4
4
|
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"homepage": "https://remult.dev",
|
|
6
6
|
"repository": {
|
|
@@ -121,6 +121,11 @@
|
|
|
121
121
|
"import": "./esm/remult-turso.js",
|
|
122
122
|
"types": "./remult-turso.d.ts"
|
|
123
123
|
},
|
|
124
|
+
"./remult-duckdb": {
|
|
125
|
+
"require": "./remult-duckdb.js",
|
|
126
|
+
"import": "./esm/remult-duckdb.js",
|
|
127
|
+
"types": "./remult-duckdb.d.ts"
|
|
128
|
+
},
|
|
124
129
|
"./remult-bun-sqlite": {
|
|
125
130
|
"require": "./remult-bun-sqlite.js",
|
|
126
131
|
"import": "./esm/remult-bun-sqlite.js",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Database } from 'duckdb';
|
|
2
|
+
import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
|
|
3
|
+
import { type FieldMetadata, type EntityMetadata } from './index.js';
|
|
4
|
+
export declare class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
5
|
+
constructor(db: Database);
|
|
6
|
+
wrapIdentifier(name: string): string;
|
|
7
|
+
getCreateTableSql(entity: EntityMetadata<any>): Promise<string>;
|
|
8
|
+
addColumnSqlSyntax(x: FieldMetadata, dbName: string, isAlterColumn: boolean): string;
|
|
9
|
+
}
|
package/remult-duckdb.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DuckDBDataProvider = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
|
|
6
|
+
var index_js_1 = require("./index.js");
|
|
7
|
+
var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
8
|
+
var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
|
|
9
|
+
var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
10
|
+
tslib_1.__extends(DuckDBDataProvider, _super);
|
|
11
|
+
function DuckDBDataProvider(db) {
|
|
12
|
+
var _this = _super.call(this, function () { return new DuckDBCommand(db); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
|
|
13
|
+
switch (_a.label) {
|
|
14
|
+
case 0: return [4 /*yield*/, db];
|
|
15
|
+
case 1: return [2 /*return*/, (_a.sent()).close()];
|
|
16
|
+
}
|
|
17
|
+
}); }); }, false, true) || this;
|
|
18
|
+
return _this;
|
|
19
|
+
}
|
|
20
|
+
DuckDBDataProvider.prototype.wrapIdentifier = function (name) {
|
|
21
|
+
return "\"".concat(name, "\"");
|
|
22
|
+
};
|
|
23
|
+
DuckDBDataProvider.prototype.getCreateTableSql = function (entity) {
|
|
24
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
25
|
+
var result, e, sql, _a, _b, x, sequenceName;
|
|
26
|
+
var e_1, _c;
|
|
27
|
+
return tslib_1.__generator(this, function (_d) {
|
|
28
|
+
switch (_d.label) {
|
|
29
|
+
case 0:
|
|
30
|
+
result = '';
|
|
31
|
+
return [4 /*yield*/, (0, index_js_1.dbNamesOf)(entity, this.wrapIdentifier)];
|
|
32
|
+
case 1:
|
|
33
|
+
e = _d.sent();
|
|
34
|
+
sql = '';
|
|
35
|
+
try {
|
|
36
|
+
for (_a = tslib_1.__values(entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
37
|
+
x = _b.value;
|
|
38
|
+
if (!(0, filter_consumer_bridge_to_sql_request_js_1.shouldNotCreateField)(x, e) || (0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
|
|
39
|
+
if (result.length != 0)
|
|
40
|
+
result += ',';
|
|
41
|
+
result += '\r\n ';
|
|
42
|
+
if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
|
|
43
|
+
sequenceName = "".concat(entity.dbName, "_").concat(x.dbName, "_seq");
|
|
44
|
+
sql += "create sequence if not exists \"".concat(sequenceName, "\";\r\n");
|
|
45
|
+
result += "".concat(e.$dbNameOf(x), " integer default nextval('").concat(sequenceName, "')");
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x), false);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
54
|
+
finally {
|
|
55
|
+
try {
|
|
56
|
+
if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
|
|
57
|
+
}
|
|
58
|
+
finally { if (e_1) throw e_1.error; }
|
|
59
|
+
}
|
|
60
|
+
result += ",\r\n primary key (".concat(entity.idMetadata.fields
|
|
61
|
+
.map(function (f) { return e.$dbNameOf(f); })
|
|
62
|
+
.join(','), ")");
|
|
63
|
+
sql +=
|
|
64
|
+
'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
|
|
65
|
+
return [2 /*return*/, sql];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
DuckDBDataProvider.prototype.addColumnSqlSyntax = function (x, dbName, isAlterColumn) {
|
|
71
|
+
var result = dbName;
|
|
72
|
+
var allowNull = x.allowNull;
|
|
73
|
+
if (allowNull && isAlterColumn) {
|
|
74
|
+
allowNull = false;
|
|
75
|
+
console.log('DuckDB does not support altering columns to allow null on existing tables');
|
|
76
|
+
}
|
|
77
|
+
if (x.valueType == Number) {
|
|
78
|
+
if (!x.valueConverter.fieldTypeInDb)
|
|
79
|
+
result += ' numeric' + (allowNull ? '' : ' default 0 not null');
|
|
80
|
+
else
|
|
81
|
+
result +=
|
|
82
|
+
' ' +
|
|
83
|
+
x.valueConverter.fieldTypeInDb +
|
|
84
|
+
(x.allowNull || isAlterColumn ? '' : ' default 0 not null');
|
|
85
|
+
}
|
|
86
|
+
else if (x.valueType == Date) {
|
|
87
|
+
if (!x.valueConverter.fieldTypeInDb)
|
|
88
|
+
if (x.valueConverter == index_js_1.ValueConverters.DateOnly)
|
|
89
|
+
result += ' date';
|
|
90
|
+
else
|
|
91
|
+
result += ' timestamp';
|
|
92
|
+
else
|
|
93
|
+
result += ' ' + x.valueConverter.fieldTypeInDb;
|
|
94
|
+
}
|
|
95
|
+
else if (x.valueType == Boolean)
|
|
96
|
+
result +=
|
|
97
|
+
' boolean' +
|
|
98
|
+
(x.allowNull || isAlterColumn ? '' : ' default false not null');
|
|
99
|
+
else if (x.valueConverter.fieldTypeInDb) {
|
|
100
|
+
result += ' ' + x.valueConverter.fieldTypeInDb;
|
|
101
|
+
if (!(x.allowNull || isAlterColumn) &&
|
|
102
|
+
x.valueConverter.fieldTypeInDb == 'integer') {
|
|
103
|
+
result += ' default 0 not null';
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else
|
|
107
|
+
result +=
|
|
108
|
+
' varchar' +
|
|
109
|
+
(x.allowNull || isAlterColumn ? '' : " default '' not null");
|
|
110
|
+
return result;
|
|
111
|
+
};
|
|
112
|
+
return DuckDBDataProvider;
|
|
113
|
+
}(remult_sqlite_core_js_1.SqliteCoreDataProvider));
|
|
114
|
+
exports.DuckDBDataProvider = DuckDBDataProvider;
|
|
115
|
+
var DuckDBCommand = /** @class */ (function () {
|
|
116
|
+
function DuckDBCommand(db) {
|
|
117
|
+
this.db = db;
|
|
118
|
+
this.values = [];
|
|
119
|
+
}
|
|
120
|
+
DuckDBCommand.prototype.execute = function (sql) {
|
|
121
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
122
|
+
var _this = this;
|
|
123
|
+
return tslib_1.__generator(this, function (_a) {
|
|
124
|
+
return [2 /*return*/, new Promise(function (resolve, error) {
|
|
125
|
+
var _a;
|
|
126
|
+
(_a = _this.db).all.apply(_a, tslib_1.__spreadArray(tslib_1.__spreadArray([sql], tslib_1.__read(_this.values), false), [function (err, rows) {
|
|
127
|
+
if (err)
|
|
128
|
+
error(err);
|
|
129
|
+
else
|
|
130
|
+
resolve(new DuckDBSqlResult(rows));
|
|
131
|
+
}], false));
|
|
132
|
+
})];
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
DuckDBCommand.prototype.addParameterAndReturnSqlToken = function (val) {
|
|
137
|
+
return this.param(val);
|
|
138
|
+
};
|
|
139
|
+
DuckDBCommand.prototype.param = function (val) {
|
|
140
|
+
var key = '?';
|
|
141
|
+
this.values.push(val);
|
|
142
|
+
return key;
|
|
143
|
+
};
|
|
144
|
+
return DuckDBCommand;
|
|
145
|
+
}());
|
|
146
|
+
var DuckDBSqlResult = /** @class */ (function () {
|
|
147
|
+
function DuckDBSqlResult(result) {
|
|
148
|
+
this.result = result;
|
|
149
|
+
this.rows = result;
|
|
150
|
+
}
|
|
151
|
+
DuckDBSqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
|
|
152
|
+
return Object.keys(this.result[0])[index];
|
|
153
|
+
};
|
|
154
|
+
return DuckDBSqlResult;
|
|
155
|
+
}());
|
package/remult-knex/index.js
CHANGED
|
@@ -229,7 +229,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
229
229
|
};
|
|
230
230
|
KnexEntityDataProvider.prototype.find = function (options) {
|
|
231
231
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
232
|
-
var e, cols, colKeys, _a, _b, x, query, br, r_1, r;
|
|
232
|
+
var e, cols, colKeys, _a, _b, x, name_1, query, br, r_1, r;
|
|
233
233
|
var e_3, _c;
|
|
234
234
|
return tslib_1.__generator(this, function (_d) {
|
|
235
235
|
switch (_d.label) {
|
|
@@ -244,7 +244,10 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
244
244
|
if (x.isServerExpression) {
|
|
245
245
|
}
|
|
246
246
|
else {
|
|
247
|
-
|
|
247
|
+
name_1 = e.$dbNameOf(x);
|
|
248
|
+
if (x.options.sqlExpression)
|
|
249
|
+
name_1 = this.knex.raw('?? as ' + x.key, [name_1]);
|
|
250
|
+
cols.push(name_1);
|
|
248
251
|
colKeys.push(x);
|
|
249
252
|
}
|
|
250
253
|
}
|
package/remult-sqlite-core.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { EntityMetadata } from './src/remult3/remult3.js';
|
|
2
2
|
import type { SqlCommand, SqlImplementation } from './src/sql-command.js';
|
|
3
|
+
import type { FieldMetadata } from './src/column-interfaces.js';
|
|
3
4
|
import type { CanBuildMigrations, MigrationBuilder, MigrationCode } from './migrations/migration-types.js';
|
|
4
5
|
export declare class SqliteCoreDataProvider implements SqlImplementation, CanBuildMigrations {
|
|
5
6
|
createCommand: () => SqlCommand;
|
|
6
7
|
end: () => Promise<void>;
|
|
7
8
|
doesNotSupportReturningSyntax: boolean;
|
|
8
|
-
|
|
9
|
+
doesNotSupportReturningSyntaxOnlyForUpdate: boolean;
|
|
10
|
+
constructor(createCommand: () => SqlCommand, end: () => Promise<void>, doesNotSupportReturningSyntax?: boolean, doesNotSupportReturningSyntaxOnlyForUpdate?: boolean);
|
|
9
11
|
orderByNullsFirst?: boolean;
|
|
10
12
|
getLimitSqlSyntax(limit: number, offset: number): string;
|
|
11
13
|
afterMutation?: VoidFunction;
|
|
@@ -14,9 +16,9 @@ export declare class SqliteCoreDataProvider implements SqlImplementation, CanBui
|
|
|
14
16
|
entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
|
|
15
17
|
ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
|
|
16
18
|
dropTable(entity: EntityMetadata): Promise<void>;
|
|
17
|
-
|
|
19
|
+
addColumnSqlSyntax(x: FieldMetadata, dbName: string, isAlterTable: boolean): string;
|
|
18
20
|
createTableIfNotExist(entity: EntityMetadata<any>): Promise<void>;
|
|
19
21
|
supportsJsonColumnType?: boolean;
|
|
20
|
-
|
|
22
|
+
getCreateTableSql(entity: EntityMetadata<any>): Promise<string>;
|
|
21
23
|
wrapIdentifier(name: string): string;
|
|
22
24
|
}
|
package/remult-sqlite-core.js
CHANGED
|
@@ -6,11 +6,13 @@ var sql_database_js_1 = require("./src/data-providers/sql-database.js");
|
|
|
6
6
|
var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
7
7
|
var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
|
|
8
8
|
var SqliteCoreDataProvider = /** @class */ (function () {
|
|
9
|
-
function SqliteCoreDataProvider(createCommand, end, doesNotSupportReturningSyntax) {
|
|
9
|
+
function SqliteCoreDataProvider(createCommand, end, doesNotSupportReturningSyntax, doesNotSupportReturningSyntaxOnlyForUpdate) {
|
|
10
10
|
if (doesNotSupportReturningSyntax === void 0) { doesNotSupportReturningSyntax = false; }
|
|
11
|
+
if (doesNotSupportReturningSyntaxOnlyForUpdate === void 0) { doesNotSupportReturningSyntaxOnlyForUpdate = false; }
|
|
11
12
|
this.createCommand = createCommand;
|
|
12
13
|
this.end = end;
|
|
13
14
|
this.doesNotSupportReturningSyntax = doesNotSupportReturningSyntax;
|
|
15
|
+
this.doesNotSupportReturningSyntaxOnlyForUpdate = doesNotSupportReturningSyntaxOnlyForUpdate;
|
|
14
16
|
}
|
|
15
17
|
SqliteCoreDataProvider.prototype.getLimitSqlSyntax = function (limit, offset) {
|
|
16
18
|
return ' limit ' + limit + ' offset ' + offset;
|
|
@@ -39,7 +41,7 @@ var SqliteCoreDataProvider = /** @class */ (function () {
|
|
|
39
41
|
case 0: return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(entity, this.wrapIdentifier)];
|
|
40
42
|
case 1:
|
|
41
43
|
e = _a.sent();
|
|
42
|
-
sql = "alter table ".concat(e.$entityName, " add column ").concat(self.addColumnSqlSyntax(field, e.$dbNameOf(field)));
|
|
44
|
+
sql = "alter table ".concat(e.$entityName, " add column ").concat(self.addColumnSqlSyntax(field, e.$dbNameOf(field), true));
|
|
43
45
|
builder.addSql(sql);
|
|
44
46
|
return [2 /*return*/];
|
|
45
47
|
}
|
|
@@ -136,7 +138,7 @@ var SqliteCoreDataProvider = /** @class */ (function () {
|
|
|
136
138
|
});
|
|
137
139
|
});
|
|
138
140
|
};
|
|
139
|
-
SqliteCoreDataProvider.prototype.addColumnSqlSyntax = function (x, dbName) {
|
|
141
|
+
SqliteCoreDataProvider.prototype.addColumnSqlSyntax = function (x, dbName, isAlterTable) {
|
|
140
142
|
var result = dbName;
|
|
141
143
|
var nullNumber = x.allowNull ? '' : ' default 0 not null';
|
|
142
144
|
if (x.valueType == Date)
|
|
@@ -195,7 +197,7 @@ var SqliteCoreDataProvider = /** @class */ (function () {
|
|
|
195
197
|
result += e.$dbNameOf(x) + ' integer primary key autoincrement';
|
|
196
198
|
}
|
|
197
199
|
else {
|
|
198
|
-
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x));
|
|
200
|
+
result += this.addColumnSqlSyntax(x, e.$dbNameOf(x), false);
|
|
199
201
|
if (x.key == entity.idMetadata.field.key) {
|
|
200
202
|
result += ' primary key';
|
|
201
203
|
}
|
package/remult-turso.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SqlImplementation } from './index.js';
|
|
1
|
+
import type { SqlImplementation } from './index.js';
|
|
2
2
|
import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
|
|
3
3
|
import type { Client } from '@libsql/client';
|
|
4
4
|
export declare class TursoDataProvider extends SqliteCoreDataProvider {
|
|
@@ -136,6 +136,9 @@ var SqlDatabase = /** @class */ (function () {
|
|
|
136
136
|
supportsJsonColumnType: this.sql.supportsJsonColumnType,
|
|
137
137
|
wrapIdentifier: this.wrapIdentifier,
|
|
138
138
|
end: this.end,
|
|
139
|
+
doesNotSupportReturningSyntax: this.sql.doesNotSupportReturningSyntax,
|
|
140
|
+
doesNotSupportReturningSyntaxOnlyForUpdate: this.sql.doesNotSupportReturningSyntaxOnlyForUpdate,
|
|
141
|
+
orderByNullsFirst: this.sql.orderByNullsFirst,
|
|
139
142
|
}))];
|
|
140
143
|
case 2:
|
|
141
144
|
_a.sent();
|
|
@@ -459,6 +462,8 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
459
462
|
if (colKeys.length > 0)
|
|
460
463
|
select += ', ';
|
|
461
464
|
select += e.$dbNameOf(x);
|
|
465
|
+
if (x.options.sqlExpression)
|
|
466
|
+
select += ' as ' + x.key;
|
|
462
467
|
colKeys.push(x);
|
|
463
468
|
}
|
|
464
469
|
}
|
|
@@ -474,7 +479,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
474
479
|
};
|
|
475
480
|
ActualSQLServerDataProvider.prototype.update = function (id, data) {
|
|
476
481
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
477
|
-
var e, r, statement, added, _a, _b, x, v, idFilter, f, _c, _d, colKeys, select;
|
|
482
|
+
var e, r, statement, added, _a, _b, x, v, idFilter, f, _c, _d, colKeys, select, returning;
|
|
478
483
|
var e_5, _e;
|
|
479
484
|
var _this = this;
|
|
480
485
|
return tslib_1.__generator(this, function (_f) {
|
|
@@ -517,12 +522,18 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
517
522
|
case 2:
|
|
518
523
|
statement = _c + _f.sent();
|
|
519
524
|
_d = this.buildSelect(e), colKeys = _d.colKeys, select = _d.select;
|
|
520
|
-
|
|
525
|
+
returning = true;
|
|
526
|
+
if (this.sql._getSourceSql().doesNotSupportReturningSyntax)
|
|
527
|
+
returning = false;
|
|
528
|
+
if (returning &&
|
|
529
|
+
this.sql._getSourceSql().doesNotSupportReturningSyntaxOnlyForUpdate)
|
|
530
|
+
returning = false;
|
|
531
|
+
if (returning)
|
|
521
532
|
statement += ' returning ' + select;
|
|
522
533
|
return [2 /*return*/, r.execute(statement).then(function (sqlResult) {
|
|
523
534
|
var _a, _b;
|
|
524
535
|
(_b = (_a = _this.sql._getSourceSql()).afterMutation) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
525
|
-
if (
|
|
536
|
+
if (!returning) {
|
|
526
537
|
return getRowAfterUpdate(_this.entity, _this, data, id, 'update');
|
|
527
538
|
}
|
|
528
539
|
if (sqlResult.rows.length != 1)
|
package/src/remult3/remult3.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.flags = void 0;
|
|
|
4
4
|
exports.flags = {
|
|
5
5
|
error500RetryCount: 4,
|
|
6
6
|
};
|
|
7
|
+
//y1 - 'test expression columns without aliases'
|
|
8
|
+
//p1 - see if I can fix the no alias problem in selects
|
|
7
9
|
//p1 - add luid - it's cool for order by.
|
|
8
10
|
//p1 - replace uuid with crypto.randomUUID and allow custom fallback
|
|
9
11
|
//p1 - add nanoid
|
|
@@ -14,6 +16,7 @@ exports.flags = {
|
|
|
14
16
|
//p1 - add LifecycleEvent to documentation
|
|
15
17
|
//y1 - Talk about the case where we had one to many, without a field - just a filter - for example, event,event participants, users - and a field that shows all users that are not participants
|
|
16
18
|
//p1 - Fix hagai and starter project to latest ts
|
|
19
|
+
//y1 - talk about the $ sign in my filter rules - no other orm uses that (part of sql work, with $ etc)
|
|
17
20
|
//y1 TODO - discuss next auth withRemult paradox - the gift that keeps on giving - it's doing something crazy there!!
|
|
18
21
|
//p1 - fix chaining of saving and saved in multiple entity options args
|
|
19
22
|
//p1 - review starter and examples and separate remult * auth from the routes
|
package/src/sql-command.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export interface SqlImplementation extends HasWrapIdentifier {
|
|
|
8
8
|
supportsJsonColumnType?: boolean;
|
|
9
9
|
/** true by default */
|
|
10
10
|
doesNotSupportReturningSyntax?: boolean;
|
|
11
|
+
doesNotSupportReturningSyntaxOnlyForUpdate?: boolean;
|
|
11
12
|
orderByNullsFirst?: boolean;
|
|
12
13
|
end(): Promise<void>;
|
|
13
14
|
afterMutation?: VoidFunction;
|