Skip to content

Commit 4af78a0

Browse files
Copilotmathiasrw
andauthored
Fix DEFAULT values FILESTORAGE and LOCALSTORAGE to close #1848 (#2340)
Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mathiasrw <[email protected]> Co-authored-by: M. Wulff <[email protected]>
1 parent ef3769d commit 4af78a0

File tree

5 files changed

+243
-3
lines changed

5 files changed

+243
-3
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ yarn-error.log
1212
package-lock.json
1313
/dist/
1414
pnpm-lock.yaml
15+
# Test storage files generated by dom-storage
16+
test*.json

src/70insert.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ yy.Insert.prototype.compile = function (databaseid) {
397397

398398
if (db.engineid && alasql.engines[db.engineid].intoTable && alasql.options.autocommit) {
399399
var statement = function (params, cb) {
400-
var aa = new Function('db,params', 'var y;' + s33 + 'return aa;')(db, params);
400+
var aa = new Function('db,params,alasql', 'var y;' + s33 + 'return aa;')(db, params, alasql);
401401
// console.log(s33);
402402
var res = alasql.engines[db.engineid].intoTable(db.databaseid, tableid, aa, null, cb);
403403
// if(cb) cb(res);

src/92localstorage.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ LS.storeTable = function (databaseid, tableid) {
5050
tbl.columns = table.columns;
5151
tbl.data = table.data;
5252
tbl.identities = table.identities;
53+
tbl.defaultfns = table.defaultfns;
54+
tbl.onupdatefns = table.onupdatefns;
5355
// TODO: May be add indexes, objects and other fields?
5456
LS.set(db.lsdbid + '.' + tableid, tbl);
5557
};

src/94filestorage.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ FS.createTable = function (databaseid, tableid, ifnotexists, cb) {
107107
throw new Error('Table "' + tableid + '" alsready exists in the database "' + fsdbid + '"');
108108
}
109109
var table = alasql.databases[databaseid].tables[tableid];
110-
db.data.tables[tableid] = {columns: table.columns};
110+
db.data.tables[tableid] = {
111+
columns: table.columns,
112+
defaultfns: table.defaultfns,
113+
onupdatefns: table.onupdatefns,
114+
};
111115
db.data[tableid] = [];
112116

113117
FS.updateFile(databaseid);
@@ -186,7 +190,11 @@ FS.commit = function (databaseid, cb) {
186190
var fsdb = {tables: {}};
187191
if (db.tables) {
188192
for (var tbid in db.tables) {
189-
db.data.tables[tbid] = {columns: db.tables[tbid].columns};
193+
db.data.tables[tbid] = {
194+
columns: db.tables[tbid].columns,
195+
defaultfns: db.tables[tbid].defaultfns,
196+
onupdatefns: db.tables[tbid].onupdatefns,
197+
};
190198
db.data[tbid] = db.tables[tbid].data;
191199
}
192200
}

test/test1848.js

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
if (typeof exports === 'object') {
2+
var assert = require('assert');
3+
var alasql = require('..');
4+
}
5+
6+
if (typeof exports == 'object') {
7+
var DOMStorage = require('dom-storage');
8+
global.localStorage = new DOMStorage('./test1848.json', {
9+
strict: false,
10+
ws: '',
11+
});
12+
}
13+
14+
describe('Test 1848 - Default values in FILESTORAGE and LOCALSTORAGE', function () {
15+
const test = '1848';
16+
17+
// Test for LOCALSTORAGE
18+
describe('LOCALSTORAGE', function () {
19+
var lsdbid = 'test' + test + 'ls';
20+
21+
before(function () {
22+
// Ensure clean state
23+
localStorage.clear();
24+
});
25+
26+
after(function () {
27+
// Cleanup
28+
try {
29+
alasql('DETACH DATABASE ' + lsdbid);
30+
alasql('DROP LOCALSTORAGE DATABASE ' + lsdbid);
31+
} catch (e) {
32+
// Database might not exist
33+
}
34+
localStorage.clear();
35+
});
36+
37+
it('A) Should apply DEFAULT values on INSERT in LOCALSTORAGE', function (done) {
38+
alasql('CREATE LOCALSTORAGE DATABASE IF NOT EXISTS ' + lsdbid);
39+
alasql('ATTACH LOCALSTORAGE DATABASE ' + lsdbid);
40+
alasql('USE ' + lsdbid);
41+
42+
alasql(`CREATE TABLE banks (
43+
name STRING PRIMARY KEY,
44+
is_open BOOLEAN DEFAULT true,
45+
[key] STRING
46+
)`);
47+
48+
alasql(`CREATE TABLE pigs (
49+
id STRING PRIMARY KEY,
50+
bank STRING DEFAULT null,
51+
ready BOOLEAN DEFAULT false,
52+
dream STRING,
53+
notes STRING,
54+
kind STRING
55+
)`);
56+
57+
// Insert without specifying all columns
58+
alasql("INSERT INTO banks (name, [key]) VALUES ('Bank1', 'abc123')");
59+
alasql("INSERT INTO pigs (id, dream) VALUES ('pig1', 'fly')");
60+
61+
var banksResult = alasql('SELECT * FROM banks');
62+
var pigsResult = alasql('SELECT * FROM pigs');
63+
64+
// Check that defaults were applied
65+
assert.deepEqual(banksResult, [{name: 'Bank1', is_open: true, key: 'abc123'}]);
66+
assert.deepEqual(pigsResult, [
67+
{id: 'pig1', bank: null, ready: false, dream: 'fly', notes: undefined, kind: undefined},
68+
]);
69+
70+
alasql('DETACH DATABASE ' + lsdbid);
71+
alasql('DROP LOCALSTORAGE DATABASE ' + lsdbid);
72+
done();
73+
});
74+
75+
it('B) Should apply CURRENT_TIMESTAMP DEFAULT in LOCALSTORAGE', function (done) {
76+
alasql('CREATE LOCALSTORAGE DATABASE IF NOT EXISTS ' + lsdbid);
77+
alasql('ATTACH LOCALSTORAGE DATABASE ' + lsdbid);
78+
alasql('USE ' + lsdbid);
79+
80+
alasql(`CREATE TABLE events (
81+
id STRING PRIMARY KEY,
82+
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
83+
)`);
84+
85+
// Insert without specifying timestamp
86+
var beforeInsert = new Date();
87+
alasql("INSERT INTO events (id) VALUES ('event1')");
88+
var afterInsert = new Date();
89+
90+
var result = alasql('SELECT * FROM events');
91+
92+
assert.equal(result.length, 1);
93+
assert.equal(result[0].id, 'event1');
94+
assert.ok(
95+
result[0].timestamp !== undefined,
96+
'timestamp should be set with DEFAULT CURRENT_TIMESTAMP'
97+
);
98+
// Check that timestamp is a Date or string that can be converted to Date
99+
var timestamp = new Date(result[0].timestamp);
100+
assert.ok(
101+
timestamp >= beforeInsert && timestamp <= afterInsert,
102+
'timestamp should be within the expected range'
103+
);
104+
105+
alasql('DETACH DATABASE ' + lsdbid);
106+
alasql('DROP LOCALSTORAGE DATABASE ' + lsdbid);
107+
done();
108+
});
109+
});
110+
111+
// Test for FILESTORAGE
112+
describe('FILESTORAGE', function () {
113+
var fsdbid = 'test' + test + 'fs';
114+
var filename = 'test' + test + '.db';
115+
116+
beforeEach(function () {
117+
// Clean up file before each test
118+
try {
119+
var fs = require('fs');
120+
if (fs.existsSync(filename)) {
121+
fs.unlinkSync(filename);
122+
}
123+
} catch (e) {
124+
// File might not exist
125+
}
126+
});
127+
128+
afterEach(function () {
129+
// Cleanup after each test
130+
try {
131+
alasql('DROP DATABASE ' + fsdbid);
132+
} catch (e) {
133+
// Database might not exist
134+
}
135+
try {
136+
var fs = require('fs');
137+
if (fs.existsSync(filename)) {
138+
fs.unlinkSync(filename);
139+
}
140+
} catch (e) {
141+
// File might not exist
142+
}
143+
});
144+
145+
it('C) Should apply DEFAULT values on INSERT in FILESTORAGE', function (done) {
146+
// Use synchronous mode for simplicity in testing
147+
alasql.options.autocommit = true;
148+
149+
alasql('CREATE FILESTORAGE DATABASE ' + fsdbid + '("' + filename + '")', function () {
150+
alasql('ATTACH FILESTORAGE DATABASE ' + fsdbid + '("' + filename + '")', function () {
151+
alasql('USE ' + fsdbid);
152+
153+
alasql(`CREATE TABLE banks (
154+
name STRING PRIMARY KEY,
155+
is_open BOOLEAN DEFAULT true,
156+
[key] STRING
157+
)`);
158+
159+
alasql(`CREATE TABLE pigs (
160+
id STRING PRIMARY KEY,
161+
bank STRING DEFAULT null,
162+
ready BOOLEAN DEFAULT false,
163+
dream STRING,
164+
notes STRING,
165+
kind STRING
166+
)`);
167+
168+
// Insert without specifying all columns
169+
alasql("INSERT INTO banks (name, [key]) VALUES ('Bank1', 'abc123')");
170+
alasql("INSERT INTO pigs (id, dream) VALUES ('pig1', 'fly')");
171+
172+
var banksResult = alasql('SELECT * FROM banks');
173+
var pigsResult = alasql('SELECT * FROM pigs');
174+
175+
// Check that defaults were applied
176+
assert.deepEqual(banksResult, [{name: 'Bank1', is_open: true, key: 'abc123'}]);
177+
assert.deepEqual(pigsResult, [
178+
{id: 'pig1', bank: null, ready: false, dream: 'fly', notes: undefined, kind: undefined},
179+
]);
180+
181+
alasql('DETACH DATABASE ' + fsdbid);
182+
alasql('DROP DATABASE ' + fsdbid);
183+
done();
184+
});
185+
});
186+
});
187+
188+
it('D) Should apply CURRENT_TIMESTAMP DEFAULT in FILESTORAGE', function (done) {
189+
// Use synchronous mode for simplicity in testing
190+
alasql.options.autocommit = true;
191+
192+
alasql('CREATE FILESTORAGE DATABASE ' + fsdbid + '("' + filename + '")', function () {
193+
alasql('ATTACH FILESTORAGE DATABASE ' + fsdbid + '("' + filename + '")', function () {
194+
alasql('USE ' + fsdbid);
195+
196+
alasql(`CREATE TABLE events (
197+
id STRING PRIMARY KEY,
198+
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
199+
)`);
200+
201+
// Insert without specifying timestamp
202+
var beforeInsert = new Date();
203+
alasql("INSERT INTO events (id) VALUES ('event1')");
204+
var afterInsert = new Date();
205+
206+
var result = alasql('SELECT * FROM events');
207+
208+
assert.equal(result.length, 1);
209+
assert.equal(result[0].id, 'event1');
210+
assert.ok(
211+
result[0].timestamp !== undefined,
212+
'timestamp should be set with DEFAULT CURRENT_TIMESTAMP'
213+
);
214+
// Check that timestamp is a Date or string that can be converted to Date
215+
var timestamp = new Date(result[0].timestamp);
216+
assert.ok(
217+
timestamp >= beforeInsert && timestamp <= afterInsert,
218+
'timestamp should be within the expected range'
219+
);
220+
221+
alasql('DETACH DATABASE ' + fsdbid);
222+
alasql('DROP DATABASE ' + fsdbid);
223+
done();
224+
});
225+
});
226+
});
227+
});
228+
});

0 commit comments

Comments
 (0)