alasql 4.2.5 → 4.2.7
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/alasql-worker.js +4 -4
- package/dist/alasql.d.ts +17 -0
- package/dist/alasql.fs.js +408 -444
- package/dist/alasql.js +408 -444
- package/dist/alasql.min.js +33 -22
- package/package.json +10 -8
- package/types/alasql.d.ts +17 -0
package/dist/alasql.fs.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
//! AlaSQL v4.2.
|
|
1
|
+
//! AlaSQL v4.2.6 build: develop-6db74fcc | © 2014-2024 Andrey Gershun & Mathias Wulff | License: MIT
|
|
2
2
|
/*
|
|
3
3
|
@module alasql
|
|
4
|
-
@version 4.2.
|
|
4
|
+
@version 4.2.6
|
|
5
5
|
|
|
6
6
|
AlaSQL - JavaScript SQL database
|
|
7
|
-
© 2014-
|
|
7
|
+
© 2014-2024 Andrey Gershun & Mathias Wulff
|
|
8
8
|
|
|
9
9
|
@license
|
|
10
10
|
The MIT License (MIT)
|
|
11
11
|
|
|
12
|
-
Copyright 2014-
|
|
12
|
+
Copyright 2014-2024 Andrey Gershun (agershun@gmail.com) & Mathias Wulff (m@rawu.dk)
|
|
13
13
|
|
|
14
14
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
15
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -49,109 +49,109 @@ SOFTWARE.
|
|
|
49
49
|
*/
|
|
50
50
|
|
|
51
51
|
(function (root, factory) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
if (typeof define === 'function' && define.amd) {
|
|
53
|
+
define([], factory);
|
|
54
|
+
} else if (typeof exports === 'object') {
|
|
55
|
+
/** alasql main function */
|
|
56
|
+
module.exports = factory();
|
|
57
|
+
} else {
|
|
58
|
+
root.alasql = factory();
|
|
59
|
+
}
|
|
60
60
|
}(this, function () {
|
|
61
61
|
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
62
|
+
/**
|
|
63
|
+
AlaSQL - Main Alasql class
|
|
64
|
+
@function
|
|
65
|
+
@param {string|function|object} sql - SQL-statement or data object for fluent interface
|
|
66
|
+
@param {object} params - SQL parameters
|
|
67
|
+
@param {function} cb - callback function
|
|
68
|
+
@param {object} scope - Scope for nested queries
|
|
69
|
+
@return {any} - Result data object
|
|
70
|
+
|
|
71
|
+
@example
|
|
72
|
+
Standard sync call:
|
|
73
|
+
alasql('CREATE TABLE one');
|
|
74
|
+
Query:
|
|
75
|
+
var res = alasql('SELECT * FROM one');
|
|
76
|
+
Call with parameters:
|
|
77
|
+
var res = alasql('SELECT * FROM ?',[data]);
|
|
78
|
+
Standard async call with callback function:
|
|
79
|
+
alasql('SELECT * FROM ?',[data],function(res){
|
|
80
|
+
console.log(data);
|
|
81
|
+
});
|
|
82
|
+
Call with scope for subquery (to pass common values):
|
|
83
|
+
var scope = {one:{a:2,b;20}}
|
|
84
|
+
alasql('SELECT * FROM ? two WHERE two.a = one.a',[data],null,scope);
|
|
85
|
+
Call for fluent interface with data object:
|
|
86
|
+
alasql(data).Where(function(x){return x.a == 10}).exec();
|
|
87
|
+
Call for fluent interface without data object:
|
|
88
|
+
alasql().From(data).Where(function(x){return x.a == 10}).exec();
|
|
89
|
+
*/
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
let alasql = function (sql, params, cb, scope) {
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
params = params || [];
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
if (typeof importScripts !== 'function' && alasql.webworker) {
|
|
96
|
+
var id = alasql.lastid++;
|
|
97
|
+
alasql.buffer[id] = cb;
|
|
98
|
+
alasql.webworker.postMessage({ id: id, sql: sql, params: params });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
if (arguments.length === 0) {
|
|
103
|
+
// Without arguments - Fluent interface
|
|
104
|
+
return new yy.Select({
|
|
105
|
+
columns: [new yy.Column({ columnid: '*' })],
|
|
106
|
+
from: [new yy.ParamValue({ param: 0 })]
|
|
107
|
+
});
|
|
108
|
+
} else if (arguments.length === 1) {
|
|
109
|
+
// Access promise notation without using `.promise(...)`
|
|
110
|
+
if (sql.constructor === Array) {
|
|
111
|
+
return alasql.promise(sql);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Avoid setting params if not needed even with callback
|
|
115
|
+
if (typeof params === 'function') {
|
|
116
|
+
scope = cb;
|
|
117
|
+
cb = params;
|
|
118
|
+
params = [];
|
|
112
119
|
}
|
|
113
|
-
}
|
|
114
|
-
// Avoid setting params if not needed even with callback
|
|
115
|
-
if(typeof params === 'function'){
|
|
116
|
-
scope = cb;
|
|
117
|
-
cb = params;
|
|
118
|
-
params = [];
|
|
119
|
-
}
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
if (typeof params !== 'object') {
|
|
122
122
|
params = [params];
|
|
123
|
-
|
|
123
|
+
}
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
};
|
|
125
|
+
// Standard interface
|
|
126
|
+
// alasql('#sql');
|
|
127
|
+
if (typeof sql === 'string' && sql[0] === '#' && typeof document === "object") {
|
|
128
|
+
sql = document.querySelector(sql).textContent;
|
|
129
|
+
} else if (typeof sql === 'object' && sql instanceof HTMLElement) {
|
|
130
|
+
sql = sql.textContent;
|
|
131
|
+
} else if (typeof sql === 'function') {
|
|
132
|
+
// to run multiline functions
|
|
133
|
+
sql = sql.toString();
|
|
134
|
+
sql = (/\/\*([\S\s]+)\*\//m.exec(sql) || ['', 'Function given as SQL. Plese Provide SQL string or have a /* ... */ syle comment with SQL in the function.'])[1];
|
|
135
|
+
}
|
|
136
|
+
// Run SQL
|
|
137
|
+
return alasql.exec(sql, params, cb, scope);
|
|
138
|
+
};
|
|
139
139
|
|
|
140
|
-
/**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
*/
|
|
144
|
-
alasql.version = '4.2.
|
|
145
|
-
alasql.build = 'develop-
|
|
140
|
+
/**
|
|
141
|
+
Current version of alasql
|
|
142
|
+
@constant {string}
|
|
143
|
+
*/
|
|
144
|
+
alasql.version = '4.2.6';
|
|
145
|
+
alasql.build = 'develop-6db74fcc';
|
|
146
146
|
|
|
147
|
-
/**
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
*/
|
|
151
|
-
alasql.debug = undefined; // Initial debug variable
|
|
147
|
+
/**
|
|
148
|
+
Debug flag
|
|
149
|
+
@type {boolean}
|
|
150
|
+
*/
|
|
151
|
+
alasql.debug = undefined; // Initial debug variable
|
|
152
152
|
|
|
153
153
|
/*only-for-browser/*
|
|
154
|
-
var require = function(){return null}; // as alasqlparser.js is generated, we can not "remove" references to
|
|
154
|
+
var require = function(){return null}; // as alasqlparser.js is generated, we can not "remove" references to
|
|
155
155
|
var __dirname = '';
|
|
156
156
|
//*/
|
|
157
157
|
/* parser generated by jison 0.4.18 */
|
|
@@ -3144,7 +3144,7 @@ if (typeof module !== 'undefined' && require.main === module) {
|
|
|
3144
3144
|
*/
|
|
3145
3145
|
|
|
3146
3146
|
/**
|
|
3147
|
-
|
|
3147
|
+
Pretty flag - nice HTML output or standard text without any tags
|
|
3148
3148
|
@type {boolean}
|
|
3149
3149
|
*/
|
|
3150
3150
|
|
|
@@ -3155,7 +3155,7 @@ alasql.prettyflag = false;
|
|
|
3155
3155
|
@function
|
|
3156
3156
|
@param {string} sql SQL statement
|
|
3157
3157
|
@param {boolean} flag value
|
|
3158
|
-
@return {string} HTML or text string with pretty output
|
|
3158
|
+
@return {string} HTML or text string with pretty output
|
|
3159
3159
|
*/
|
|
3160
3160
|
|
|
3161
3161
|
alasql.pretty = function (sql, flag) {
|
|
@@ -3165,7 +3165,6 @@ alasql.pretty = function (sql, flag) {
|
|
|
3165
3165
|
alasql.prettyflag = pf;
|
|
3166
3166
|
return s;
|
|
3167
3167
|
};
|
|
3168
|
-
|
|
3169
3168
|
/*jshint unused:false*/
|
|
3170
3169
|
/*
|
|
3171
3170
|
Utilities for Alasql.js
|
|
@@ -3455,6 +3454,7 @@ utils.hasIndexedDB = (function () {
|
|
|
3455
3454
|
utils.isArray = function (obj) {
|
|
3456
3455
|
return '[object Array]' === Object.prototype.toString.call(obj);
|
|
3457
3456
|
};
|
|
3457
|
+
|
|
3458
3458
|
/**
|
|
3459
3459
|
Load text file from anywhere
|
|
3460
3460
|
@param {string|object} path File path or HTML event
|
|
@@ -3466,7 +3466,9 @@ utils.isArray = function (obj) {
|
|
|
3466
3466
|
@todo Define Event type
|
|
3467
3467
|
@todo Smaller if-else structures.
|
|
3468
3468
|
*/
|
|
3469
|
-
|
|
3469
|
+
|
|
3470
|
+
const protocolRegex = /^[a-z]+:\/\//i;
|
|
3471
|
+
let loadFile = (utils.loadFile = function (path, asy, success, error) {
|
|
3470
3472
|
var data, fs;
|
|
3471
3473
|
if (utils.isNode || utils.isMeteorServer) {
|
|
3472
3474
|
//*not-for-browser/*
|
|
@@ -3485,30 +3487,38 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
|
|
|
3485
3487
|
process.stdin.on('end', function () {
|
|
3486
3488
|
success(cutbom(buff));
|
|
3487
3489
|
});
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
// Call sync version
|
|
3502
|
-
try {
|
|
3503
|
-
data = fs.readFileSync(path);
|
|
3504
|
-
} catch (e) {
|
|
3505
|
-
return error(err, null);
|
|
3506
|
-
}
|
|
3507
|
-
success(cutbom(data.toString()));
|
|
3490
|
+
return;
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
if (protocolRegex.test(path)) {
|
|
3494
|
+
fetchData(path, x => success(cutbom(x)), error, asy);
|
|
3495
|
+
return;
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3498
|
+
//If async callthen call async
|
|
3499
|
+
if (asy) {
|
|
3500
|
+
fs.readFile(path, function (err, data) {
|
|
3501
|
+
if (err) {
|
|
3502
|
+
return error(err, null);
|
|
3508
3503
|
}
|
|
3509
|
-
|
|
3504
|
+
success(cutbom(data.toString()));
|
|
3505
|
+
});
|
|
3506
|
+
return;
|
|
3510
3507
|
}
|
|
3511
|
-
|
|
3508
|
+
|
|
3509
|
+
// Call sync version
|
|
3510
|
+
try {
|
|
3511
|
+
data = fs.readFileSync(path);
|
|
3512
|
+
} catch (e) {
|
|
3513
|
+
error(err, null);
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
|
|
3517
|
+
success(cutbom(data.toString()));
|
|
3518
|
+
return;
|
|
3519
|
+
}
|
|
3520
|
+
|
|
3521
|
+
if (utils.isReactNative) {
|
|
3512
3522
|
// If ReactNative
|
|
3513
3523
|
var RNFS = require('react-native-fs');
|
|
3514
3524
|
RNFS.readFile(path, 'utf8')
|
|
@@ -3519,7 +3529,10 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
|
|
|
3519
3529
|
return error(err, null);
|
|
3520
3530
|
});
|
|
3521
3531
|
//*/
|
|
3522
|
-
|
|
3532
|
+
return;
|
|
3533
|
+
}
|
|
3534
|
+
|
|
3535
|
+
if (utils.isCordova) {
|
|
3523
3536
|
/* If Cordova */
|
|
3524
3537
|
utils.global.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {
|
|
3525
3538
|
fileSystem.root.getFile(path, {create: false}, function (fileEntry) {
|
|
@@ -3533,48 +3546,52 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
|
|
|
3533
3546
|
});
|
|
3534
3547
|
});
|
|
3535
3548
|
|
|
3536
|
-
|
|
3549
|
+
return;
|
|
3550
|
+
}
|
|
3537
3551
|
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
} else {
|
|
3549
|
-
/*
|
|
3550
|
-
Simply read file from HTTP request, like:
|
|
3551
|
-
SELECT * FROM TXT('http://alasql.org/README.md');
|
|
3552
|
-
*/
|
|
3553
|
-
fetchData(path, x => success(cutbom(x)), error, asy);
|
|
3554
|
-
}
|
|
3555
|
-
} else if (path instanceof Event) {
|
|
3556
|
-
/*
|
|
3557
|
-
For browser read from files input element
|
|
3558
|
-
<input type="files" onchange="readFile(event)">
|
|
3559
|
-
<script>
|
|
3560
|
-
function readFile(event) {
|
|
3561
|
-
alasql('SELECT * FROM TXT(?)',[event])
|
|
3562
|
-
}
|
|
3563
|
-
</script>
|
|
3564
|
-
*/
|
|
3565
|
-
/** @type {array} List of files from <input> element */
|
|
3566
|
-
var files = path.target.files;
|
|
3567
|
-
/** type {object} */
|
|
3568
|
-
var reader = new FileReader();
|
|
3569
|
-
/** type {string} */
|
|
3570
|
-
var name = files[0].name;
|
|
3571
|
-
reader.onload = function (e) {
|
|
3572
|
-
var data = e.target.result;
|
|
3573
|
-
success(cutbom(data));
|
|
3574
|
-
};
|
|
3575
|
-
reader.readAsText(files[0]);
|
|
3552
|
+
/* For string */
|
|
3553
|
+
if (typeof path === 'string') {
|
|
3554
|
+
// For browser read from tag
|
|
3555
|
+
/*
|
|
3556
|
+
SELECT * FROM TXT('#one') -- read data from HTML element with id="one"
|
|
3557
|
+
*/
|
|
3558
|
+
if (path.substr(0, 1) === '#' && typeof document !== 'undefined') {
|
|
3559
|
+
data = document.querySelector(path).textContent;
|
|
3560
|
+
success(data);
|
|
3561
|
+
return;
|
|
3576
3562
|
}
|
|
3563
|
+
|
|
3564
|
+
/*
|
|
3565
|
+
Simply read file from HTTP request, like:
|
|
3566
|
+
SELECT * FROM TXT('http://alasql.org/README.md');
|
|
3567
|
+
*/
|
|
3568
|
+
fetchData(path, x => success(cutbom(x)), error, asy);
|
|
3569
|
+
return;
|
|
3570
|
+
}
|
|
3571
|
+
|
|
3572
|
+
if (path instanceof Event) {
|
|
3573
|
+
/*
|
|
3574
|
+
For browser read from files input element
|
|
3575
|
+
<input type="files" onchange="readFile(event)">
|
|
3576
|
+
<script>
|
|
3577
|
+
function readFile(event) {
|
|
3578
|
+
alasql('SELECT * FROM TXT(?)',[event])
|
|
3579
|
+
}
|
|
3580
|
+
</script>
|
|
3581
|
+
*/
|
|
3582
|
+
/** @type {array} List of files from <input> element */
|
|
3583
|
+
var files = path.target.files;
|
|
3584
|
+
/** type {object} */
|
|
3585
|
+
var reader = new FileReader();
|
|
3586
|
+
/** type {string} */
|
|
3587
|
+
var name = files[0].name;
|
|
3588
|
+
reader.onload = function (e) {
|
|
3589
|
+
var data = e.target.result;
|
|
3590
|
+
success(cutbom(data));
|
|
3591
|
+
};
|
|
3592
|
+
reader.readAsText(files[0]);
|
|
3577
3593
|
}
|
|
3594
|
+
fetchData(path, x => success(cutbom(x)), error, asy);
|
|
3578
3595
|
});
|
|
3579
3596
|
|
|
3580
3597
|
let _fetch = typeof fetch !== 'undefined' ? fetch : null;
|
|
@@ -4340,15 +4357,15 @@ var getXLSX = function () {
|
|
|
4340
4357
|
// set AlaSQl path
|
|
4341
4358
|
alasql.path = alasql.utils.findAlaSQLPath();
|
|
4342
4359
|
/**
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4360
|
+
Strip all comments.
|
|
4361
|
+
@function
|
|
4362
|
+
@param {string} str
|
|
4363
|
+
@return {string}
|
|
4364
|
+
Based om the https://github.com/lehni/uncomment.js/blob/master/uncomment.js
|
|
4365
|
+
I just replaced JavaScript's '//' to SQL's '--' and remove other stuff
|
|
4366
|
+
|
|
4367
|
+
@todo Fixed [aaa/*bbb] for column names
|
|
4368
|
+
@todo Bug if -- comments in the last line
|
|
4352
4369
|
@todo Check if it possible to model it with Jison parser
|
|
4353
4370
|
@todo Remove unused code
|
|
4354
4371
|
*/
|
|
@@ -4367,7 +4384,6 @@ alasql.utils.uncomment = function (str) {
|
|
|
4367
4384
|
// preserveComment = false;
|
|
4368
4385
|
|
|
4369
4386
|
for (var i = 0, l = str.length; i < l; i++) {
|
|
4370
|
-
|
|
4371
4387
|
// When checking for quote escaping, we also need to check that the
|
|
4372
4388
|
// escape sign itself is not escaped, as otherwise '\\' would cause
|
|
4373
4389
|
// the wrong impression of an unclosed string:
|
|
@@ -4377,7 +4393,6 @@ alasql.utils.uncomment = function (str) {
|
|
|
4377
4393
|
if (str[i] === quoteSign && unescaped) {
|
|
4378
4394
|
quote = false;
|
|
4379
4395
|
}
|
|
4380
|
-
|
|
4381
4396
|
} else if (blockComment) {
|
|
4382
4397
|
// Is the block comment closing?
|
|
4383
4398
|
if (str[i] === '*' && str[i + 1] === '/') {
|
|
@@ -4414,7 +4429,6 @@ alasql.utils.uncomment = function (str) {
|
|
|
4414
4429
|
// if (!preserveComment)
|
|
4415
4430
|
str[i] = '';
|
|
4416
4431
|
blockComment = true;
|
|
4417
|
-
|
|
4418
4432
|
}
|
|
4419
4433
|
}
|
|
4420
4434
|
}
|
|
@@ -4600,17 +4614,18 @@ alasql.use = function (databaseid) {
|
|
|
4600
4614
|
if (!databaseid) {
|
|
4601
4615
|
databaseid = alasql.DEFAULTDATABASEID;
|
|
4602
4616
|
}
|
|
4617
|
+
|
|
4603
4618
|
if (alasql.useid === databaseid) {
|
|
4604
4619
|
return;
|
|
4605
4620
|
}
|
|
4621
|
+
|
|
4606
4622
|
if (alasql.databases[databaseid] !== undefined) {
|
|
4607
4623
|
alasql.useid = databaseid;
|
|
4608
|
-
|
|
4624
|
+
let db = alasql.databases[alasql.useid];
|
|
4609
4625
|
alasql.tables = db.tables;
|
|
4610
|
-
// alasql.fn = db.fn;
|
|
4611
4626
|
db.resetSqlCache();
|
|
4612
4627
|
if (alasql.options.usedbo) {
|
|
4613
|
-
alasql.databases.dbo = db;
|
|
4628
|
+
alasql.databases.dbo = db;
|
|
4614
4629
|
}
|
|
4615
4630
|
} else {
|
|
4616
4631
|
throw Error('Database does not exist: ' + databaseid);
|
|
@@ -4650,7 +4665,9 @@ alasql.exec = function (sql, params, cb, scope) {
|
|
|
4650
4665
|
}
|
|
4651
4666
|
|
|
4652
4667
|
delete alasql.error;
|
|
4668
|
+
|
|
4653
4669
|
params = params || {};
|
|
4670
|
+
|
|
4654
4671
|
if (alasql.options.errorlog) {
|
|
4655
4672
|
try {
|
|
4656
4673
|
return alasql.dexec(alasql.useid, sql, params, cb, scope);
|
|
@@ -4676,14 +4693,14 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) {
|
|
|
4676
4693
|
|
|
4677
4694
|
// Create hash
|
|
4678
4695
|
if (alasql.options.cache) {
|
|
4679
|
-
|
|
4696
|
+
let statement = db.sqlCache[hh];
|
|
4680
4697
|
// If database structure was not changed since last time return cache
|
|
4681
4698
|
if (statement && db.dbversion === statement.dbversion) {
|
|
4682
4699
|
return statement(params, cb);
|
|
4683
4700
|
}
|
|
4684
4701
|
}
|
|
4685
4702
|
|
|
4686
|
-
|
|
4703
|
+
let ast = db.astCache[hh];
|
|
4687
4704
|
if (alasql.options.cache && !ast) {
|
|
4688
4705
|
// Create AST cache
|
|
4689
4706
|
ast = alasql.parse(sql);
|
|
@@ -4694,12 +4711,16 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) {
|
|
|
4694
4711
|
} else {
|
|
4695
4712
|
ast = alasql.parse(sql);
|
|
4696
4713
|
}
|
|
4714
|
+
|
|
4697
4715
|
if (!ast.statements) {
|
|
4698
4716
|
return;
|
|
4699
4717
|
}
|
|
4718
|
+
|
|
4700
4719
|
if (0 === ast.statements.length) {
|
|
4701
4720
|
return 0;
|
|
4702
|
-
}
|
|
4721
|
+
}
|
|
4722
|
+
|
|
4723
|
+
if (1 === ast.statements.length) {
|
|
4703
4724
|
if (ast.statements[0].compile) {
|
|
4704
4725
|
// Compile and Execute
|
|
4705
4726
|
var statement = ast.statements[0].compile(databaseid, params);
|
|
@@ -4719,20 +4740,18 @@ alasql.dexec = function (databaseid, sql, params, cb, scope) {
|
|
|
4719
4740
|
}
|
|
4720
4741
|
var res = (alasql.res = statement(params, cb, scope));
|
|
4721
4742
|
return res;
|
|
4722
|
-
} else {
|
|
4723
|
-
|
|
4724
|
-
alasql.precompile(ast.statements[0], alasql.useid, params);
|
|
4725
|
-
var res = (alasql.res = ast.statements[0].execute(databaseid, params, cb, scope));
|
|
4726
|
-
return res;
|
|
4727
|
-
}
|
|
4728
|
-
} else {
|
|
4729
|
-
// Multiple statements
|
|
4730
|
-
if (cb) {
|
|
4731
|
-
alasql.adrun(databaseid, ast, params, cb, scope);
|
|
4732
|
-
} else {
|
|
4733
|
-
return alasql.drun(databaseid, ast, params, cb, scope);
|
|
4734
4743
|
}
|
|
4744
|
+
alasql.precompile(ast.statements[0], alasql.useid, params);
|
|
4745
|
+
var res = (alasql.res = ast.statements[0].execute(databaseid, params, cb, scope));
|
|
4746
|
+
return res;
|
|
4747
|
+
}
|
|
4748
|
+
|
|
4749
|
+
if (cb) {
|
|
4750
|
+
alasql.adrun(databaseid, ast, params, cb, scope);
|
|
4751
|
+
return;
|
|
4735
4752
|
}
|
|
4753
|
+
|
|
4754
|
+
return alasql.drun(databaseid, ast, params, cb, scope);
|
|
4736
4755
|
};
|
|
4737
4756
|
|
|
4738
4757
|
/**
|
|
@@ -4791,28 +4810,30 @@ alasql.adrun = function (databaseid, ast, params, cb, scope) {
|
|
|
4791
4810
|
if (data !== undefined) {
|
|
4792
4811
|
res.push(data);
|
|
4793
4812
|
}
|
|
4813
|
+
|
|
4794
4814
|
var astatement = ast.statements.shift();
|
|
4795
4815
|
if (!astatement) {
|
|
4796
4816
|
if (useid !== databaseid) {
|
|
4797
4817
|
alasql.use(useid);
|
|
4798
4818
|
}
|
|
4799
4819
|
cb(res);
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
}
|
|
4809
|
-
} else {
|
|
4810
|
-
alasql.precompile(ast.statements[0], alasql.useid, params);
|
|
4811
|
-
astatement.execute(alasql.useid, params, adrunone);
|
|
4812
|
-
if (alasql.options.progress !== false) {
|
|
4813
|
-
alasql.options.progress(noqueries, idx++);
|
|
4814
|
-
}
|
|
4820
|
+
return;
|
|
4821
|
+
}
|
|
4822
|
+
|
|
4823
|
+
if (astatement.compile) {
|
|
4824
|
+
var statement = astatement.compile(alasql.useid);
|
|
4825
|
+
statement(params, adrunone, scope);
|
|
4826
|
+
if (alasql.options.progress !== false) {
|
|
4827
|
+
alasql.options.progress(noqueries, idx++);
|
|
4815
4828
|
}
|
|
4829
|
+
return;
|
|
4830
|
+
}
|
|
4831
|
+
|
|
4832
|
+
alasql.precompile(ast.statements[0], alasql.useid, params);
|
|
4833
|
+
astatement.execute(alasql.useid, params, adrunone);
|
|
4834
|
+
|
|
4835
|
+
if (alasql.options.progress !== false) {
|
|
4836
|
+
alasql.options.progress(noqueries, idx++);
|
|
4816
4837
|
}
|
|
4817
4838
|
}
|
|
4818
4839
|
|
|
@@ -4828,29 +4849,27 @@ alasql.adrun = function (databaseid, ast, params, cb, scope) {
|
|
|
4828
4849
|
alasql.compile = function (sql, databaseid) {
|
|
4829
4850
|
databaseid = databaseid || alasql.useid;
|
|
4830
4851
|
|
|
4831
|
-
|
|
4852
|
+
let ast = alasql.parse(sql); // Create AST
|
|
4832
4853
|
|
|
4833
|
-
if (1
|
|
4834
|
-
|
|
4835
|
-
statement.promise = function (params) {
|
|
4836
|
-
return new Promise(function (resolve, reject) {
|
|
4837
|
-
statement(params, function (data, err) {
|
|
4838
|
-
if (err) {
|
|
4839
|
-
reject(err);
|
|
4840
|
-
} else {
|
|
4841
|
-
resolve(data);
|
|
4842
|
-
}
|
|
4843
|
-
});
|
|
4844
|
-
});
|
|
4845
|
-
};
|
|
4854
|
+
if (1 !== ast.statements.length)
|
|
4855
|
+
throw new Error('Cannot compile, because number of statements in SQL is not equal to 1');
|
|
4846
4856
|
|
|
4847
|
-
|
|
4857
|
+
var statement = ast.statements[0].compile(databaseid);
|
|
4848
4858
|
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4859
|
+
statement.promise = function (params) {
|
|
4860
|
+
return new Promise(function (resolve, reject) {
|
|
4861
|
+
statement(params, function (data, err) {
|
|
4862
|
+
if (err) {
|
|
4863
|
+
reject(err);
|
|
4864
|
+
} else {
|
|
4865
|
+
resolve(data);
|
|
4866
|
+
}
|
|
4867
|
+
});
|
|
4868
|
+
});
|
|
4869
|
+
};
|
|
4853
4870
|
|
|
4871
|
+
return statement;
|
|
4872
|
+
};
|
|
4854
4873
|
//
|
|
4855
4874
|
// Promises for AlaSQL
|
|
4856
4875
|
//
|
|
@@ -4876,6 +4895,7 @@ var promiseExec = function (sql, params, counterStep, counterTotal) {
|
|
|
4876
4895
|
|
|
4877
4896
|
const sequentialPromiseResolver = (promiseData, Promise) => {
|
|
4878
4897
|
var startingPoint = Promise.resolve([]);
|
|
4898
|
+
|
|
4879
4899
|
promiseData.forEach(p => {
|
|
4880
4900
|
startingPoint = startingPoint.then(previousResult =>
|
|
4881
4901
|
promiseExec(p.sql, p.params, p.i, p.length).then(result => [...previousResult, result])
|
|
@@ -5233,7 +5253,6 @@ class Recordset {
|
|
|
5233
5253
|
|
|
5234
5254
|
alasql.Recordset = Recordset;
|
|
5235
5255
|
alasql.Query = Query;
|
|
5236
|
-
|
|
5237
5256
|
/*
|
|
5238
5257
|
//
|
|
5239
5258
|
// Parser helper for Alasql.js
|
|
@@ -5626,7 +5645,6 @@ yy.Search = class Search {
|
|
|
5626
5645
|
alasql.vars[sel.args[0]] = oldv;
|
|
5627
5646
|
return r1;
|
|
5628
5647
|
}
|
|
5629
|
-
|
|
5630
5648
|
} else if (sel.selid === 'ARRAY') {
|
|
5631
5649
|
var nest = processSelector(sel.args, 0, value);
|
|
5632
5650
|
if (nest.length > 0) {
|
|
@@ -5919,10 +5937,6 @@ yy.Search = class Search {
|
|
|
5919
5937
|
) {
|
|
5920
5938
|
fromdata = fromdata.find().fetch();
|
|
5921
5939
|
}
|
|
5922
|
-
|
|
5923
|
-
// if(typeof fromdata == 'object' && Array.isArray(fromdata)) {
|
|
5924
|
-
// selectors.unshift({srchid:'CHILD'});
|
|
5925
|
-
// }
|
|
5926
5940
|
}
|
|
5927
5941
|
|
|
5928
5942
|
// If source data is array than first step is to run over array
|
|
@@ -6386,7 +6400,7 @@ var compileSearchOrder = function (order) {
|
|
|
6386
6400
|
s += `if (
|
|
6387
6401
|
(a[${JSON.stringify(columnid)}]||'')${dg}
|
|
6388
6402
|
${ord.direction === 'ASC' ? '>' : '<'}
|
|
6389
|
-
(b[${JSON.stringify(columnid)}]||'')${dg}
|
|
6403
|
+
(b[${JSON.stringify(columnid)}]||'')${dg}
|
|
6390
6404
|
) return 1;
|
|
6391
6405
|
|
|
6392
6406
|
if(
|
|
@@ -6402,26 +6416,17 @@ var compileSearchOrder = function (order) {
|
|
|
6402
6416
|
if (ord.nocase) {
|
|
6403
6417
|
dg += '.toUpperCase()';
|
|
6404
6418
|
}
|
|
6405
|
-
s +=
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
|
|
6416
|
-
'if((' +
|
|
6417
|
-
ord.toJS('a', '') +
|
|
6418
|
-
"||'')" +
|
|
6419
|
-
dg +
|
|
6420
|
-
'==(' +
|
|
6421
|
-
ord.toJS('b', '') +
|
|
6422
|
-
"||'')" +
|
|
6423
|
-
dg +
|
|
6424
|
-
'){';
|
|
6419
|
+
s += `
|
|
6420
|
+
if (
|
|
6421
|
+
(${ord.toJS('a', '')} || '')${dg}
|
|
6422
|
+
${ord.direction === 'ASC' ? '>' : '<'}
|
|
6423
|
+
(${ord.toJS('b', '')} || '')${dg}
|
|
6424
|
+
) return 1;
|
|
6425
|
+
|
|
6426
|
+
if (
|
|
6427
|
+
(${ord.toJS('a', '')} || '')${dg} ==
|
|
6428
|
+
(${ord.toJS('b', '')} || '')${dg}
|
|
6429
|
+
) {`;
|
|
6425
6430
|
}
|
|
6426
6431
|
|
|
6427
6432
|
// TODO Add date comparision
|
|
@@ -6438,11 +6443,8 @@ var compileSearchOrder = function (order) {
|
|
|
6438
6443
|
};
|
|
6439
6444
|
// Main query procedure
|
|
6440
6445
|
function queryfn(query, oldscope, cb, A, B) {
|
|
6441
|
-
var aaa = query.sources.length;
|
|
6442
|
-
|
|
6443
|
-
var ms;
|
|
6444
6446
|
query.sourceslen = query.sources.length;
|
|
6445
|
-
|
|
6447
|
+
let slen = query.sourceslen;
|
|
6446
6448
|
query.query = query; // TODO Remove to prevent memory leaks
|
|
6447
6449
|
query.A = A;
|
|
6448
6450
|
query.B = B;
|
|
@@ -6479,10 +6481,7 @@ function queryfn(query, oldscope, cb, A, B) {
|
|
|
6479
6481
|
|
|
6480
6482
|
}
|
|
6481
6483
|
|
|
6482
|
-
|
|
6483
|
-
if (!oldscope) scope = {};
|
|
6484
|
-
else scope = cloneDeep(oldscope);
|
|
6485
|
-
query.scope = scope;
|
|
6484
|
+
query.scope = oldscope ? cloneDeep(oldscope) : {};
|
|
6486
6485
|
|
|
6487
6486
|
// First - refresh data sources
|
|
6488
6487
|
|
|
@@ -6494,19 +6493,21 @@ function queryfn(query, oldscope, cb, A, B) {
|
|
|
6494
6493
|
var rs = source.datafn(query, query.params, queryfn2, idx, alasql);
|
|
6495
6494
|
|
|
6496
6495
|
if (typeof rs !== 'undefined') {
|
|
6497
|
-
// TODO - this is a hack: check if result is array - check all cases and
|
|
6498
|
-
|
|
6499
|
-
|
|
6496
|
+
// TODO - this is a hack: check if result is array - check all cases and make it more logical
|
|
6497
|
+
if ((query.intofn || query.intoallfn) && Array.isArray(rs)) {
|
|
6498
|
+
rs = rs.length;
|
|
6499
|
+
}
|
|
6500
6500
|
result = rs;
|
|
6501
6501
|
}
|
|
6502
6502
|
//
|
|
6503
6503
|
// Ugly hack to use in query.wherefn and source.srcwherefns functions
|
|
6504
6504
|
// constructions like this.queriesdata['test'].
|
|
6505
|
-
//
|
|
6505
|
+
// We can elimite it with source.srcwherefn.bind(this)()
|
|
6506
6506
|
// but it may be slow.
|
|
6507
6507
|
//
|
|
6508
6508
|
source.queriesdata = query.queriesdata;
|
|
6509
6509
|
});
|
|
6510
|
+
|
|
6510
6511
|
if (query.sources.length == 0 || 0 === slen) {
|
|
6511
6512
|
try {
|
|
6512
6513
|
result = queryfn3(query);
|
|
@@ -6554,13 +6555,7 @@ function queryfn3(query) {
|
|
|
6554
6555
|
jlen;
|
|
6555
6556
|
|
|
6556
6557
|
// Preindexation of data sources
|
|
6557
|
-
// if(!oldscope) {
|
|
6558
6558
|
preIndex(query);
|
|
6559
|
-
// }
|
|
6560
|
-
|
|
6561
|
-
// query.sources.forEach(function(source) {
|
|
6562
|
-
|
|
6563
|
-
// });
|
|
6564
6559
|
|
|
6565
6560
|
// Prepare variables
|
|
6566
6561
|
query.data = [];
|
|
@@ -6571,17 +6566,14 @@ function queryfn3(query) {
|
|
|
6571
6566
|
var h = 0;
|
|
6572
6567
|
|
|
6573
6568
|
// Start walking over data
|
|
6574
|
-
|
|
6575
6569
|
doJoin(query, scope, h);
|
|
6576
6570
|
|
|
6577
6571
|
// If grouping, then filter groups with HAVING function
|
|
6578
|
-
|
|
6579
6572
|
if (query.groupfn) {
|
|
6580
6573
|
query.data = [];
|
|
6581
6574
|
if (query.groups.length === 0 && query.allgroups.length === 0) {
|
|
6582
6575
|
var g = {};
|
|
6583
6576
|
if (query.selectGroup.length > 0) {
|
|
6584
|
-
|
|
6585
6577
|
query.selectGroup.forEach(function (sg) {
|
|
6586
6578
|
if (
|
|
6587
6579
|
sg.aggregatorid == 'COUNT' ||
|
|
@@ -6595,37 +6587,25 @@ function queryfn3(query) {
|
|
|
6595
6587
|
});
|
|
6596
6588
|
}
|
|
6597
6589
|
query.groups = [g];
|
|
6598
|
-
|
|
6599
6590
|
}
|
|
6600
6591
|
|
|
6601
|
-
// ******
|
|
6602
|
-
|
|
6603
6592
|
if (query.aggrKeys.length > 0) {
|
|
6604
6593
|
var gfns = '';
|
|
6605
6594
|
query.aggrKeys.forEach(function (col) {
|
|
6606
|
-
gfns += `
|
|
6595
|
+
gfns += `
|
|
6596
|
+
g[${JSON.stringify(col.nick)}] = alasql.aggr[${JSON.stringify(
|
|
6607
6597
|
col.funcid
|
|
6608
|
-
)}](undefined,g[${JSON.stringify(col.nick)}],3)
|
|
6609
|
-
|
|
6610
|
-
// gfns += 'return g[\''+col.nick+'\];';
|
|
6598
|
+
)}](undefined,g[${JSON.stringify(col.nick)}],3); `;
|
|
6611
6599
|
});
|
|
6612
|
-
|
|
6613
6600
|
var gfn = new Function('g,params,alasql', 'var y;' + gfns);
|
|
6614
6601
|
}
|
|
6615
6602
|
|
|
6616
|
-
// *******
|
|
6617
|
-
|
|
6618
|
-
// debugger;
|
|
6619
|
-
// if(false && (query.groups.length == 1) && (Object.keys(query.groups[0]).length == 0)) {
|
|
6620
|
-
|
|
6621
|
-
// } else {
|
|
6622
6603
|
for (var i = 0, ilen = query.groups.length; i < ilen; i++) {
|
|
6623
6604
|
var g = query.groups[i];
|
|
6624
6605
|
|
|
6625
6606
|
if (gfn) gfn(g, query.params, alasql);
|
|
6626
6607
|
|
|
6627
6608
|
if (!query.havingfn || query.havingfn(g, query.params, alasql)) {
|
|
6628
|
-
|
|
6629
6609
|
var d = query.selectgfn(g, query.params, alasql);
|
|
6630
6610
|
|
|
6631
6611
|
for (const key in query.groupColumns) {
|
|
@@ -6641,9 +6621,6 @@ function queryfn3(query) {
|
|
|
6641
6621
|
query.data.push(d);
|
|
6642
6622
|
}
|
|
6643
6623
|
}
|
|
6644
|
-
// }
|
|
6645
|
-
|
|
6646
|
-
// query.groups = query.groups.filter();
|
|
6647
6624
|
}
|
|
6648
6625
|
// Remove distinct values
|
|
6649
6626
|
doDistinct(query);
|
|
@@ -6752,9 +6729,6 @@ function queryfn3(query) {
|
|
|
6752
6729
|
// Reduce to limit and offset
|
|
6753
6730
|
doLimit(query);
|
|
6754
6731
|
|
|
6755
|
-
// Remove Angular.js artifacts and other unnecessary columns
|
|
6756
|
-
// Issue #25
|
|
6757
|
-
|
|
6758
6732
|
// TODO: Check what artefacts rest from Angular.js
|
|
6759
6733
|
if (typeof angular != 'undefined') {
|
|
6760
6734
|
query.removeKeys.push('$$hashKey');
|
|
@@ -6796,7 +6770,6 @@ function queryfn3(query) {
|
|
|
6796
6770
|
for (var k in r) {
|
|
6797
6771
|
for (j = 0; j < query.removeLikeKeys.length; j++) {
|
|
6798
6772
|
if (alasql.utils.like(query.removeLikeKeys[j], k)) {
|
|
6799
|
-
// if(k.match(query.removeLikeKeys[j])) {
|
|
6800
6773
|
delete r[k];
|
|
6801
6774
|
}
|
|
6802
6775
|
}
|
|
@@ -6807,7 +6780,6 @@ function queryfn3(query) {
|
|
|
6807
6780
|
query.columns = query.columns.filter(function (column) {
|
|
6808
6781
|
var found = false;
|
|
6809
6782
|
removeLikeKeys.forEach(function (key) {
|
|
6810
|
-
// if(column.columnid.match(key)) found = true;
|
|
6811
6783
|
if (alasql.utils.like(key, column.columnid)) {
|
|
6812
6784
|
found = true;
|
|
6813
6785
|
}
|
|
@@ -6818,31 +6790,25 @@ function queryfn3(query) {
|
|
|
6818
6790
|
}
|
|
6819
6791
|
|
|
6820
6792
|
if (query.pivotfn) query.pivotfn();
|
|
6793
|
+
|
|
6821
6794
|
if (query.unpivotfn) query.unpivotfn();
|
|
6822
6795
|
|
|
6823
6796
|
if (query.intoallfn) {
|
|
6824
|
-
|
|
6825
|
-
// var res = query.intoallfn(query.columns,query.cb,query.A, query.B, alasql);
|
|
6826
6797
|
var res = query.intoallfn(query.columns, query.cb, query.params, query.alasql);
|
|
6827
|
-
|
|
6828
|
-
// if(query.cb) res = query.cb(res,query.A, query.B);
|
|
6829
|
-
|
|
6830
|
-
// debugger;
|
|
6831
6798
|
return res;
|
|
6832
|
-
}
|
|
6799
|
+
}
|
|
6800
|
+
|
|
6801
|
+
if (query.intofn) {
|
|
6833
6802
|
ilen = query.data.length;
|
|
6834
6803
|
for (i = 0; i < ilen; i++) {
|
|
6835
6804
|
query.intofn(query.data[i], i, query.params, query.alasql);
|
|
6836
6805
|
}
|
|
6837
|
-
|
|
6838
6806
|
if (query.cb) query.cb(query.data.length, query.A, query.B);
|
|
6839
6807
|
return query.data.length;
|
|
6840
|
-
} else {
|
|
6841
|
-
|
|
6842
|
-
res = query.data;
|
|
6843
|
-
if (query.cb) res = query.cb(query.data, query.A, query.B);
|
|
6844
|
-
return res;
|
|
6845
6808
|
}
|
|
6809
|
+
res = query.data;
|
|
6810
|
+
if (query.cb) res = query.cb(query.data, query.A, query.B);
|
|
6811
|
+
return res;
|
|
6846
6812
|
}
|
|
6847
6813
|
|
|
6848
6814
|
// Limiting
|
|
@@ -6895,14 +6861,13 @@ var preIndex = function (query) {
|
|
|
6895
6861
|
var source = query.sources[k];
|
|
6896
6862
|
delete source.ix;
|
|
6897
6863
|
// If there is indexation rule
|
|
6898
|
-
|
|
6899
6864
|
if (k > 0 && source.optimization == 'ix' && source.onleftfn && source.onrightfn) {
|
|
6900
6865
|
// If there is no table.indices - create it
|
|
6901
6866
|
if (source.databaseid && alasql.databases[source.databaseid].tables[source.tableid]) {
|
|
6902
6867
|
if (!alasql.databases[source.databaseid].tables[source.tableid].indices)
|
|
6903
6868
|
query.database.tables[source.tableid].indices = {};
|
|
6904
6869
|
// Check if index already exists
|
|
6905
|
-
|
|
6870
|
+
let ixx =
|
|
6906
6871
|
alasql.databases[source.databaseid].tables[source.tableid].indices[
|
|
6907
6872
|
hash(source.onrightfns + '`' + source.srcwherefns)
|
|
6908
6873
|
];
|
|
@@ -6914,10 +6879,10 @@ var preIndex = function (query) {
|
|
|
6914
6879
|
if (!source.ix) {
|
|
6915
6880
|
source.ix = {};
|
|
6916
6881
|
// Walking over source data
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
6882
|
+
let scope = {};
|
|
6883
|
+
let i = 0;
|
|
6884
|
+
let ilen = source.data.length;
|
|
6885
|
+
let dataw;
|
|
6921
6886
|
// while(source.getfn i<ilen) {
|
|
6922
6887
|
|
|
6923
6888
|
while (
|
|
@@ -6926,9 +6891,7 @@ var preIndex = function (query) {
|
|
|
6926
6891
|
i < ilen
|
|
6927
6892
|
) {
|
|
6928
6893
|
if (source.getfn && !source.dontcache) source.data[i] = dataw;
|
|
6929
|
-
// scope[tableid] = dataw;
|
|
6930
6894
|
|
|
6931
|
-
// for(var i=0, ilen=source.data.length; i<ilen; i++) {
|
|
6932
6895
|
// Prepare scope for indexation
|
|
6933
6896
|
scope[source.alias || source.tableid] = dataw;
|
|
6934
6897
|
|
|
@@ -6995,7 +6958,6 @@ var preIndex = function (query) {
|
|
|
6995
6958
|
group.push(source.data[i]);
|
|
6996
6959
|
i++;
|
|
6997
6960
|
}
|
|
6998
|
-
// query.database.tables[source.tableid].indices[hash(source.wxleftfns+'`'+source.onwherefns)] = source.ix;
|
|
6999
6961
|
if (!alasql.databases[source.databaseid].engineid) {
|
|
7000
6962
|
alasql.databases[source.databaseid].tables[source.tableid].indices[
|
|
7001
6963
|
hash(source.wxleftfns + '`')
|
|
@@ -7014,7 +6976,6 @@ var preIndex = function (query) {
|
|
|
7014
6976
|
source.data = [];
|
|
7015
6977
|
}
|
|
7016
6978
|
}
|
|
7017
|
-
// }
|
|
7018
6979
|
// If there is no any optimization than apply srcwhere filter
|
|
7019
6980
|
} else if (source.srcwherefns && !source.dontcache) {
|
|
7020
6981
|
if (source.data) {
|
|
@@ -7023,16 +6984,13 @@ var preIndex = function (query) {
|
|
|
7023
6984
|
|
|
7024
6985
|
source.data = source.data.filter(function (r) {
|
|
7025
6986
|
scope[source.alias] = r;
|
|
7026
|
-
|
|
7027
6987
|
return source.srcwherefn(scope, query.params, alasql);
|
|
7028
6988
|
});
|
|
7029
6989
|
|
|
7030
6990
|
scope = {};
|
|
7031
6991
|
i = 0;
|
|
7032
6992
|
ilen = source.data.length;
|
|
7033
|
-
|
|
7034
|
-
var res = [];
|
|
7035
|
-
// while(source.getfn i<ilen) {
|
|
6993
|
+
let res = [];
|
|
7036
6994
|
|
|
7037
6995
|
while (
|
|
7038
6996
|
(dataw = source.data[i]) ||
|
|
@@ -7051,7 +7009,6 @@ var preIndex = function (query) {
|
|
|
7051
7009
|
}
|
|
7052
7010
|
// Change this to another place (this is a wrong)
|
|
7053
7011
|
if (source.databaseid && alasql.databases[source.databaseid].tables[source.tableid]) {
|
|
7054
|
-
//query.database.tables[source.tableid].dirty = false;
|
|
7055
7012
|
} else {
|
|
7056
7013
|
// this is a subquery?
|
|
7057
7014
|
}
|
|
@@ -7062,34 +7019,24 @@ var preIndex = function (query) {
|
|
|
7062
7019
|
//
|
|
7063
7020
|
|
|
7064
7021
|
function doJoin(query, scope, h) {
|
|
7065
|
-
|
|
7066
7022
|
// Check, if this is a last join?
|
|
7067
7023
|
if (h >= query.sources.length) {
|
|
7068
7024
|
// Todo: check if this runs once too many
|
|
7069
|
-
|
|
7070
7025
|
// Then apply where and select
|
|
7071
|
-
|
|
7072
7026
|
if (query.wherefn(scope, query.params, alasql)) {
|
|
7073
|
-
|
|
7074
|
-
// var res = query.selectfn(scope, query.params, alasql);
|
|
7075
|
-
|
|
7076
7027
|
// If there is a GROUP BY then pipe to grouping function
|
|
7077
7028
|
if (query.groupfn) {
|
|
7078
7029
|
query.groupfn(scope, query.params, alasql);
|
|
7079
7030
|
} else {
|
|
7080
|
-
// query.qwerty = 999;
|
|
7081
|
-
|
|
7082
7031
|
query.data.push(query.selectfn(scope, query.params, alasql));
|
|
7083
7032
|
}
|
|
7084
7033
|
}
|
|
7085
7034
|
} else if (query.sources[h].applyselect) {
|
|
7086
|
-
|
|
7087
7035
|
var source = query.sources[h];
|
|
7088
7036
|
source.applyselect(
|
|
7089
7037
|
query.params,
|
|
7090
7038
|
function (data) {
|
|
7091
7039
|
if (data.length > 0) {
|
|
7092
|
-
|
|
7093
7040
|
for (var i = 0; i < data.length; i++) {
|
|
7094
7041
|
scope[source.alias] = data[i];
|
|
7095
7042
|
doJoin(query, scope, h + 1);
|
|
@@ -7103,101 +7050,79 @@ function doJoin(query, scope, h) {
|
|
|
7103
7050
|
},
|
|
7104
7051
|
scope
|
|
7105
7052
|
);
|
|
7106
|
-
|
|
7107
7053
|
} else {
|
|
7108
7054
|
// STEP 1
|
|
7109
7055
|
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
// if(source.joinmode == "LEFT" || source.joinmode == "INNER" || source.joinmode == "RIGHT"
|
|
7114
|
-
// || source.joinmode == "OUTER" || source.joinmode == "SEMI") {
|
|
7115
|
-
// Todo: check if this is smart
|
|
7116
|
-
if (true) {
|
|
7117
|
-
//source.joinmode != "ANTI") {
|
|
7118
|
-
|
|
7119
|
-
var tableid = source.alias || source.tableid;
|
|
7120
|
-
var pass = false; // For LEFT JOIN
|
|
7121
|
-
var data = source.data;
|
|
7122
|
-
var opt = false;
|
|
7056
|
+
let source = query.sources[h];
|
|
7057
|
+
let nextsource = query.sources[h + 1];
|
|
7123
7058
|
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
source.joinmode != 'OUTER' &&
|
|
7129
|
-
source.joinmode != 'ANTI' &&
|
|
7130
|
-
source.optimization == 'ix'
|
|
7131
|
-
) {
|
|
7132
|
-
data = source.ix[source.onleftfn(scope, query.params, alasql)] || [];
|
|
7133
|
-
opt = true;
|
|
7134
|
-
|
|
7135
|
-
}
|
|
7136
|
-
}
|
|
7059
|
+
let tableid = source.alias || source.tableid;
|
|
7060
|
+
let pass = false; // For LEFT JOIN
|
|
7061
|
+
let data = source.data;
|
|
7062
|
+
let opt = false;
|
|
7137
7063
|
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
if (
|
|
7141
|
-
|
|
7064
|
+
// Reduce data for looping if there is optimization hint
|
|
7065
|
+
if (!source.getfn || (source.getfn && !source.dontcache)) {
|
|
7066
|
+
if (
|
|
7067
|
+
source.joinmode != 'RIGHT' &&
|
|
7068
|
+
source.joinmode != 'OUTER' &&
|
|
7069
|
+
source.joinmode != 'ANTI' &&
|
|
7070
|
+
source.optimization == 'ix'
|
|
7071
|
+
) {
|
|
7072
|
+
data = source.ix[source.onleftfn(scope, query.params, alasql)] || [];
|
|
7073
|
+
opt = true;
|
|
7142
7074
|
}
|
|
7143
|
-
|
|
7144
|
-
var dataw;
|
|
7145
|
-
|
|
7146
|
-
while ((dataw = data[i]) || (!opt && source.getfn && (dataw = source.getfn(i))) || i < ilen) {
|
|
7147
|
-
if (!opt && source.getfn && !source.dontcache) data[i] = dataw;
|
|
7148
|
-
|
|
7149
|
-
scope[tableid] = dataw;
|
|
7150
|
-
|
|
7151
|
-
// Reduce with ON and USING clause
|
|
7152
|
-
var usingPassed = !source.onleftfn;
|
|
7153
|
-
if (!usingPassed) {
|
|
7154
|
-
var left = source.onleftfn(scope, query.params, alasql);
|
|
7155
|
-
var right = source.onrightfn(scope, query.params, alasql);
|
|
7156
|
-
if (left instanceof String || left instanceof Number) left = left.valueOf();
|
|
7157
|
-
if (right instanceof String || right instanceof Number) right = left.valueOf();
|
|
7158
|
-
usingPassed = left == right;
|
|
7159
|
-
}
|
|
7160
|
-
|
|
7161
|
-
if (usingPassed) {
|
|
7162
|
-
// For all non-standard JOINs like a-b=0
|
|
7163
|
-
if (source.onmiddlefn(scope, query.params, alasql)) {
|
|
7164
|
-
// Recursively call new join
|
|
7165
|
-
// if(source.joinmode == "LEFT" || source.joinmode == "INNER" || source.joinmode == "OUTER" || source.joinmode == "RIGHT" ) {
|
|
7166
|
-
if (source.joinmode != 'SEMI' && source.joinmode != 'ANTI') {
|
|
7075
|
+
}
|
|
7167
7076
|
|
|
7168
|
-
|
|
7169
|
-
|
|
7077
|
+
// Main cycle
|
|
7078
|
+
let i = 0;
|
|
7079
|
+
if (typeof data == 'undefined') {
|
|
7080
|
+
throw new Error('Data source number ' + h + ' in undefined');
|
|
7081
|
+
}
|
|
7082
|
+
let ilen = data.length;
|
|
7083
|
+
let dataw;
|
|
7170
7084
|
|
|
7171
|
-
|
|
7085
|
+
while ((dataw = data[i]) || (!opt && source.getfn && (dataw = source.getfn(i))) || i < ilen) {
|
|
7086
|
+
if (!opt && source.getfn && !source.dontcache) data[i] = dataw;
|
|
7087
|
+
scope[tableid] = dataw;
|
|
7172
7088
|
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7089
|
+
// Reduce with ON and USING clause
|
|
7090
|
+
var usingPassed = !source.onleftfn;
|
|
7091
|
+
if (!usingPassed) {
|
|
7092
|
+
var left = source.onleftfn(scope, query.params, alasql);
|
|
7093
|
+
var right = source.onrightfn(scope, query.params, alasql);
|
|
7094
|
+
if (left instanceof String || left instanceof Number) left = left.valueOf();
|
|
7095
|
+
if (right instanceof String || right instanceof Number) right = left.valueOf();
|
|
7096
|
+
usingPassed = left == right;
|
|
7097
|
+
}
|
|
7177
7098
|
|
|
7178
|
-
|
|
7179
|
-
|
|
7099
|
+
if (usingPassed) {
|
|
7100
|
+
// For all non-standard JOINs like a-b=0
|
|
7101
|
+
if (source.onmiddlefn(scope, query.params, alasql)) {
|
|
7102
|
+
// Recursively call new join
|
|
7103
|
+
if (source.joinmode != 'SEMI' && source.joinmode != 'ANTI') {
|
|
7104
|
+
doJoin(query, scope, h + 1);
|
|
7105
|
+
}
|
|
7106
|
+
if (source.joinmode != 'LEFT' && source.joinmode != 'INNER') {
|
|
7107
|
+
dataw._rightjoin = true;
|
|
7180
7108
|
}
|
|
7181
|
-
}
|
|
7182
|
-
i++;
|
|
7183
|
-
}
|
|
7184
7109
|
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
!pass
|
|
7189
|
-
) {
|
|
7190
|
-
// Clear the scope after the loop
|
|
7191
|
-
scope[tableid] = {};
|
|
7192
|
-
doJoin(query, scope, h + 1);
|
|
7110
|
+
// for LEFT JOIN
|
|
7111
|
+
pass = true;
|
|
7112
|
+
}
|
|
7193
7113
|
}
|
|
7114
|
+
i++;
|
|
7194
7115
|
}
|
|
7195
7116
|
|
|
7196
|
-
//
|
|
7197
|
-
|
|
7198
|
-
|
|
7199
|
-
|
|
7200
|
-
|
|
7117
|
+
// Additional join for LEFT JOINS
|
|
7118
|
+
if (
|
|
7119
|
+
(source.joinmode == 'LEFT' || source.joinmode == 'OUTER' || source.joinmode == 'SEMI') &&
|
|
7120
|
+
!pass
|
|
7121
|
+
) {
|
|
7122
|
+
// Clear the scope after the loop
|
|
7123
|
+
scope[tableid] = {};
|
|
7124
|
+
doJoin(query, scope, h + 1);
|
|
7125
|
+
}
|
|
7201
7126
|
|
|
7202
7127
|
// STEP 2
|
|
7203
7128
|
|
|
@@ -7210,9 +7135,9 @@ function doJoin(query, scope, h) {
|
|
|
7210
7135
|
) {
|
|
7211
7136
|
scope[source.alias] = {};
|
|
7212
7137
|
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7138
|
+
let j = 0;
|
|
7139
|
+
let jlen = nextsource.data.length;
|
|
7140
|
+
let dataw;
|
|
7216
7141
|
|
|
7217
7142
|
while (
|
|
7218
7143
|
(dataw = nextsource.data[j]) ||
|
|
@@ -7243,7 +7168,6 @@ function doJoin(query, scope, h) {
|
|
|
7243
7168
|
}
|
|
7244
7169
|
|
|
7245
7170
|
scope[tableid] = undefined;
|
|
7246
|
-
|
|
7247
7171
|
}
|
|
7248
7172
|
}
|
|
7249
7173
|
|
|
@@ -7631,7 +7555,6 @@ yy.Select = class Select {
|
|
|
7631
7555
|
query.intoallfn = new Function('columns,cb,params,alasql', 'var y;' + query.intoallfns);
|
|
7632
7556
|
}
|
|
7633
7557
|
}
|
|
7634
|
-
|
|
7635
7558
|
// Now, compile all togeather into one function with query object in scope
|
|
7636
7559
|
var statement = function (params, cb, oldscope) {
|
|
7637
7560
|
query.params = params;
|
|
@@ -10420,9 +10343,29 @@ yy.Over = class Over {
|
|
|
10420
10343
|
const toTypeNumberOps = new Set(['-', '*', '/', '%', '^']);
|
|
10421
10344
|
const toTypeStringOps = new Set(['||']);
|
|
10422
10345
|
const toTypeBoolOps = new Set([
|
|
10423
|
-
'AND',
|
|
10424
|
-
'
|
|
10425
|
-
'
|
|
10346
|
+
'AND',
|
|
10347
|
+
'OR',
|
|
10348
|
+
'NOT',
|
|
10349
|
+
'=',
|
|
10350
|
+
'==',
|
|
10351
|
+
'===',
|
|
10352
|
+
'!=',
|
|
10353
|
+
'!==',
|
|
10354
|
+
'!===',
|
|
10355
|
+
'>',
|
|
10356
|
+
'>=',
|
|
10357
|
+
'<',
|
|
10358
|
+
'<=',
|
|
10359
|
+
'IN',
|
|
10360
|
+
'NOT IN',
|
|
10361
|
+
'LIKE',
|
|
10362
|
+
'NOT LIKE',
|
|
10363
|
+
'REGEXP',
|
|
10364
|
+
'GLOB',
|
|
10365
|
+
'BETWEEN',
|
|
10366
|
+
'NOT BETWEEN',
|
|
10367
|
+
'IS NULL',
|
|
10368
|
+
'IS NOT NULL',
|
|
10426
10369
|
]);
|
|
10427
10370
|
class Op {
|
|
10428
10371
|
constructor(params) {
|
|
@@ -10466,11 +10409,9 @@ yy.Over = class Over {
|
|
|
10466
10409
|
}
|
|
10467
10410
|
|
|
10468
10411
|
toType(tableid) {
|
|
10469
|
-
if (toTypeNumberOps.has(this.op))
|
|
10470
|
-
return 'number';
|
|
10412
|
+
if (toTypeNumberOps.has(this.op)) return 'number';
|
|
10471
10413
|
|
|
10472
|
-
if (toTypeStringOps.has(this.op))
|
|
10473
|
-
return 'string';
|
|
10414
|
+
if (toTypeStringOps.has(this.op)) return 'string';
|
|
10474
10415
|
|
|
10475
10416
|
if (this.op === '+') {
|
|
10476
10417
|
const leftType = this.left.toType(tableid);
|
|
@@ -10484,11 +10425,9 @@ yy.Over = class Over {
|
|
|
10484
10425
|
}
|
|
10485
10426
|
}
|
|
10486
10427
|
|
|
10487
|
-
if (toTypeBoolOps.has(this.op) || this.allsome)
|
|
10488
|
-
return 'boolean';
|
|
10428
|
+
if (toTypeBoolOps.has(this.op) || this.allsome) return 'boolean';
|
|
10489
10429
|
|
|
10490
|
-
if (!this.op)
|
|
10491
|
-
return this.left.toType(tableid);
|
|
10430
|
+
if (!this.op) return this.left.toType(tableid);
|
|
10492
10431
|
|
|
10493
10432
|
return 'unknown';
|
|
10494
10433
|
}
|
|
@@ -10945,7 +10884,7 @@ yy.Over = class Over {
|
|
|
10945
10884
|
'~': '~',
|
|
10946
10885
|
'-': '-',
|
|
10947
10886
|
'+': '+',
|
|
10948
|
-
|
|
10887
|
+
NOT: '!',
|
|
10949
10888
|
};
|
|
10950
10889
|
|
|
10951
10890
|
class UniOp {
|
|
@@ -10954,7 +10893,7 @@ yy.Over = class Over {
|
|
|
10954
10893
|
}
|
|
10955
10894
|
|
|
10956
10895
|
toString() {
|
|
10957
|
-
const {
|
|
10896
|
+
const {op, right} = this;
|
|
10958
10897
|
const res = right.toString();
|
|
10959
10898
|
|
|
10960
10899
|
switch (op) {
|
|
@@ -11005,7 +10944,6 @@ yy.Over = class Over {
|
|
|
11005
10944
|
|
|
11006
10945
|
throw new Error(`Unsupported operator: ${this.op}`);
|
|
11007
10946
|
}
|
|
11008
|
-
|
|
11009
10947
|
}
|
|
11010
10948
|
|
|
11011
10949
|
class Column {
|
|
@@ -11033,7 +10971,11 @@ yy.Over = class Over {
|
|
|
11033
10971
|
|
|
11034
10972
|
toJS(context, tableid, defcols) {
|
|
11035
10973
|
if (!this.tableid && tableid === '' && !defcols) {
|
|
11036
|
-
return this.columnid !== '_'
|
|
10974
|
+
return this.columnid !== '_'
|
|
10975
|
+
? `${context}['${this.columnid}']`
|
|
10976
|
+
: context === 'g'
|
|
10977
|
+
? "g['_']"
|
|
10978
|
+
: context;
|
|
11037
10979
|
}
|
|
11038
10980
|
|
|
11039
10981
|
if (context === 'g') {
|
|
@@ -11041,17 +10983,27 @@ yy.Over = class Over {
|
|
|
11041
10983
|
}
|
|
11042
10984
|
|
|
11043
10985
|
if (this.tableid) {
|
|
11044
|
-
return this.columnid !== '_'
|
|
10986
|
+
return this.columnid !== '_'
|
|
10987
|
+
? `${context}['${this.tableid}']['${this.columnid}']`
|
|
10988
|
+
: context === 'g'
|
|
10989
|
+
? "g['_']"
|
|
10990
|
+
: `${context}['${this.tableid}']`;
|
|
11045
10991
|
}
|
|
11046
10992
|
|
|
11047
10993
|
if (defcols) {
|
|
11048
10994
|
const tbid = defcols[this.columnid];
|
|
11049
10995
|
if (tbid === '-') {
|
|
11050
|
-
throw new Error(
|
|
10996
|
+
throw new Error(
|
|
10997
|
+
`Cannot resolve column "${this.columnid}" because it exists in two source tables`
|
|
10998
|
+
);
|
|
11051
10999
|
} else if (tbid) {
|
|
11052
|
-
return this.columnid !== '_'
|
|
11000
|
+
return this.columnid !== '_'
|
|
11001
|
+
? `${context}['${tbid}']['${this.columnid}']`
|
|
11002
|
+
: `${context}['${tbid}']`;
|
|
11053
11003
|
} else {
|
|
11054
|
-
return this.columnid !== '_'
|
|
11004
|
+
return this.columnid !== '_'
|
|
11005
|
+
? `${context}['${this.tableid || tableid}']['${this.columnid}']`
|
|
11006
|
+
: `${context}['${this.tableid || tableid}']`;
|
|
11055
11007
|
}
|
|
11056
11008
|
}
|
|
11057
11009
|
|
|
@@ -11059,9 +11011,10 @@ yy.Over = class Over {
|
|
|
11059
11011
|
return `${context}['${this.columnid}']`;
|
|
11060
11012
|
}
|
|
11061
11013
|
|
|
11062
|
-
return this.columnid !== '_'
|
|
11014
|
+
return this.columnid !== '_'
|
|
11015
|
+
? `${context}['${this.tableid || tableid}']['${this.columnid}']`
|
|
11016
|
+
: `${context}['${this.tableid || tableid}']`;
|
|
11063
11017
|
}
|
|
11064
|
-
|
|
11065
11018
|
}
|
|
11066
11019
|
|
|
11067
11020
|
class AggrValue {
|
|
@@ -11070,7 +11023,10 @@ yy.Over = class Over {
|
|
|
11070
11023
|
}
|
|
11071
11024
|
|
|
11072
11025
|
toString() {
|
|
11073
|
-
const funcName =
|
|
11026
|
+
const funcName =
|
|
11027
|
+
this.aggregatorid === 'REDUCE'
|
|
11028
|
+
? this.funcid.replace(re_invalidFnNameChars, '')
|
|
11029
|
+
: this.aggregatorid;
|
|
11074
11030
|
const distinctPart = this.distinct ? 'DISTINCT ' : '';
|
|
11075
11031
|
const expressionPart = this.expression ? this.expression.toString() : '';
|
|
11076
11032
|
const overPart = this.over ? ` ${this.over.toString()}` : '';
|
|
@@ -11093,7 +11049,11 @@ yy.Over = class Over {
|
|
|
11093
11049
|
}
|
|
11094
11050
|
|
|
11095
11051
|
toType() {
|
|
11096
|
-
if (
|
|
11052
|
+
if (
|
|
11053
|
+
['SUM', 'COUNT', 'AVG', 'MIN', 'MAX', 'AGGR', 'VAR', 'STDDEV', 'TOTAL'].includes(
|
|
11054
|
+
this.aggregatorid
|
|
11055
|
+
)
|
|
11056
|
+
) {
|
|
11097
11057
|
return 'number';
|
|
11098
11058
|
}
|
|
11099
11059
|
|
|
@@ -16739,10 +16699,14 @@ alasql.into.XLSX = function (filename, opts, data, columns, cb) {
|
|
|
16739
16699
|
var dataLength = Object.keys(data).length;
|
|
16740
16700
|
|
|
16741
16701
|
// Generate columns if they are not defined
|
|
16742
|
-
if (
|
|
16743
|
-
|
|
16744
|
-
|
|
16745
|
-
|
|
16702
|
+
if (!columns || columns.length == 0) {
|
|
16703
|
+
if (dataLength > 0) {
|
|
16704
|
+
columns = Object.keys(data[0]).map(function (columnid) {
|
|
16705
|
+
return {columnid: columnid};
|
|
16706
|
+
});
|
|
16707
|
+
} else {
|
|
16708
|
+
columns = [];
|
|
16709
|
+
}
|
|
16746
16710
|
}
|
|
16747
16711
|
|
|
16748
16712
|
var cells = {};
|