Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions src/70insert.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,174 @@ yy.Insert.prototype.toJS = function (context, tableid, defcols) {

yy.Insert.prototype.compile = function (databaseid) {
var self = this;

// Check if inserting into a ParamValue (anonymous data table)
var isParamValue = this.into instanceof yy.ParamValue;
var paramIndex = isParamValue ? this.into.param : null;

// Handle ParamValue INSERT - simpler logic without table metadata
if (isParamValue) {
// INSERT INTO ? VALUES
if (this.values) {
if (this.exists) {
this.existsfn = this.exists.map(function (ex) {
var nq = ex.compile(databaseid);
nq.query.modifier = 'RECORDSET';
return nq;
});
}
if (this.queries) {
this.queriesfn = this.queries.map(function (q) {
var nq = q.compile(databaseid);
nq.query.modifier = 'RECORDSET';
return nq;
});
}

var statement = function (params, cb) {
var data = params[paramIndex];
if (!Array.isArray(data)) {
throw new Error('INSERT requires an array for parameter ' + paramIndex);
}

var insertedRows = [];
self.values.forEach(function (values) {
var row;
if (self.columns) {
// Build object from column names and values
row = {};
self.columns.forEach(function (col, idx) {
var val = values[idx].toJS('params', databaseid);
row[col.columnid] = new Function('params', 'return ' + val)(params);
});
} else {
// Direct array value or object
if (Array.isArray(values)) {
row = values.map(function (v) {
var val = v.toJS('params', databaseid);
return new Function('params', 'return ' + val)(params);
});
} else {
var val = JSONtoJS(values);
row = new Function('params', 'return ' + val)(params);
}
}
data.push(row);
insertedRows.push(row);
});

var res = insertedRows.length;

// Handle OUTPUT clause
if (self.output) {
var output = [];
for (var i = 0; i < insertedRows.length; i++) {
var r = insertedRows[i];
var outputRow = {};
self.output.columns.forEach(function (col) {
if (col.columnid === '*') {
for (var key in r) {
outputRow[key] = r[key];
}
} else {
var colname = col.as || col.columnid;
outputRow[colname] = r[col.columnid];
}
});
output.push(outputRow);
}
res = output;
}

if (cb) cb(res);
return res;
};
return statement;
}
// INSERT INTO ? SELECT
else if (this.select) {
this.select.modifier = 'RECORDSET';
if (this.queries) {
this.select.queries = this.queries;
}
var selectfn = this.select.compile(databaseid);

var statement = function (params, cb) {
var data = params[paramIndex];
if (!Array.isArray(data)) {
throw new Error('INSERT requires an array for parameter ' + paramIndex);
}

var res = selectfn(params).data;
var insertedRows = res;

// Push all rows to the target array
for (var i = 0; i < res.length; i++) {
data.push(res[i]);
}

// Handle OUTPUT clause
if (self.output) {
var output = [];
for (var i = 0; i < insertedRows.length; i++) {
var r = insertedRows[i];
var outputRow = {};
self.output.columns.forEach(function (col) {
if (col.columnid === '*') {
for (var key in r) {
outputRow[key] = r[key];
}
} else {
var colname = col.as || col.columnid;
outputRow[colname] = r[col.columnid];
}
});
output.push(outputRow);
}
if (cb) cb(output);
return output;
}

if (cb) cb(res.length);
return res.length;
};
return statement;
}
// INSERT INTO ? SET column = value
else if (this.setcolumns) {
var columns = [];
var valueExprs = [];
this.setcolumns.forEach(function (setcol) {
columns.push(setcol.column);
valueExprs.push(setcol.expression);
});

// Transform to VALUES and recurse once
// Save and clear the ParamValue temporarily
var originalInto = this.into;
var originalColumns = this.columns;
var originalValues = this.values;
var originalSetcolumns = this.setcolumns;

this.columns = columns;
this.values = [valueExprs];
this.setcolumns = null;

try {
var compiledFn = yy.Insert.prototype.compile.call(this, databaseid);
return compiledFn;
} finally {
this.into = originalInto;
this.columns = originalColumns;
this.values = originalValues;
this.setcolumns = originalSetcolumns;
}
} else {
throw new Error('Wrong INSERT parameters for ParamValue');
}
}

// Original table-based INSERT logic continues below
databaseid = self.into.databaseid || databaseid;
var db = alasql.databases[databaseid];
// console.log(self);
Expand Down
117 changes: 115 additions & 2 deletions src/72delete.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ yy.Delete.prototype.toString = function () {

yy.Delete.prototype.compile = function (databaseid) {
var self = this;
databaseid = this.table.databaseid || databaseid;

// Check if deleting from a ParamValue (anonymous data table)
var isParamValue = this.table instanceof yy.ParamValue;
var paramIndex = isParamValue ? this.table.param : null;

var databaseid = this.table.databaseid || databaseid;
var tableid = this.table.tableid;
var statement;
var db = alasql.databases[databaseid];
var db = isParamValue ? null : alasql.databases[databaseid];

if (this.where) {
if (this.exists) {
Expand All @@ -57,6 +62,64 @@ yy.Delete.prototype.compile = function (databaseid) {
).bind(this);

statement = function (params, cb) {
// Handle ParamValue (anonymous data table)
if (isParamValue) {
var data = params[paramIndex];
if (!Array.isArray(data)) {
throw new Error('DELETE requires an array for parameter ' + paramIndex);
}

var orignum = data.length;
var newtable = [];
var deletedRows = [];

for (var i = 0, ilen = data.length; i < ilen; i++) {
if (wherefn(data[i], params, alasql)) {
// Track deleted row for OUTPUT clause
if (self.output) {
deletedRows.push(cloneDeep(data[i]));
}
} else {
newtable.push(data[i]);
}
}

// Replace array contents (preserve reference)
data.length = 0;
for (var i = 0; i < newtable.length; i++) {
data.push(newtable[i]);
}

var res = orignum - data.length;

// Handle OUTPUT clause
if (self.output) {
var output = [];
for (var i = 0; i < deletedRows.length; i++) {
var r = deletedRows[i];
var outputRow = {};
self.output.columns.forEach(function (col) {
if (col.columnid === '*') {
// For *, expand all properties
for (var key in r) {
outputRow[key] = r[key];
}
} else {
var colname = col.as || col.columnid;
// Direct property access
outputRow[colname] = r[col.columnid];
}
});
output.push(outputRow);
}
res = output;
}

if (cb) res = cb(res);
return res;
}

// Handle normal table
if (db.engineid && alasql.engines[db.engineid].deleteFromTable) {
return alasql.engines[db.engineid].deleteFromTable(
databaseid,
Expand Down Expand Up @@ -149,6 +212,56 @@ yy.Delete.prototype.compile = function (databaseid) {
};
} else {
statement = function (params, cb) {
// Handle ParamValue (anonymous data table)
if (isParamValue) {
var data = params[paramIndex];
if (!Array.isArray(data)) {
throw new Error('DELETE requires an array for parameter ' + paramIndex);
}

var orignum = data.length;

// Track deleted rows for OUTPUT clause
var deletedRows = [];
if (self.output) {
deletedRows = data.map(function (row) {
return cloneDeep(row);
});
}

// Delete all records from the array
data.length = 0;

var res = orignum;

// Handle OUTPUT clause
if (self.output) {
var output = [];
for (var i = 0; i < deletedRows.length; i++) {
var r = deletedRows[i];
var outputRow = {};
self.output.columns.forEach(function (col) {
if (col.columnid === '*') {
// For *, expand all properties
for (var key in r) {
outputRow[key] = r[key];
}
} else {
var colname = col.as || col.columnid;
// Direct property access
outputRow[colname] = r[col.columnid];
}
});
output.push(outputRow);
}
res = output;
}

if (cb) cb(res);
return res;
}

// Handle normal table
if (alasql.options.autocommit && db.engineid) {
alasql.engines[db.engineid].loadTableData(databaseid, tableid);
}
Expand Down
Loading