sorla-db 1.0.0 → 1.1.0
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/Brainstorming.md +21 -21
- package/LICENSE +21 -21
- package/README.md +216 -31
- package/debug-not.js +23 -23
- package/dist/sorla.min.js +1 -1
- package/example/simple_data_example.html +195 -195
- package/index.js +61 -61
- package/package.json +42 -42
- package/src/collections/collection.js +46 -46
- package/src/dbs/database.js +71 -71
- package/src/documents/cursor.js +143 -143
- package/src/documents/document.js +87 -87
- package/src/helper.js +40 -40
- package/src/query_language/manipulation.js +160 -160
- package/src/query_language/operators.js +242 -288
- package/src/query_language/query.js +73 -103
- package/src/sorla.js +122 -122
- package/src/utils.js +40 -40
- package/test/feature_collection.test.js +74 -72
- package/test/feature_collection_queries.test.js +223 -268
- package/test/feature_cursor.test.js +84 -0
- package/test/feature_database.test.js +62 -0
- package/test/feature_insert.test.js +116 -0
- package/test/feature_nested_queries.test.js +94 -0
- package/test/feature_query_equivalence.test.js +165 -0
- package/test/unit_database.test.js +35 -35
- package/test/{unit_document_test.js → unit_document.test.js} +38 -38
- package/test/unit_operators.test.js +78 -0
- package/test/unit_sorla.test.js +41 -41
- package/test/unit_test.test.js +24 -24
- package/webpack.config.js +10 -10
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
const query = require('../query_language/query.js');
|
|
2
|
-
|
|
3
|
-
class collection extends query
|
|
4
|
-
{
|
|
5
|
-
/**
|
|
6
|
-
* Constructs class Collection to manage documents
|
|
7
|
-
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
* @param object validationSchema - in construction
|
|
10
|
-
* @return void
|
|
11
|
-
**/
|
|
12
|
-
constructor(validationSchema)
|
|
13
|
-
{
|
|
14
|
-
super(validationSchema);
|
|
15
|
-
this._documents = [];
|
|
16
|
-
this._indexes = [];
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Returns the first document of the collection
|
|
21
|
-
* @return object
|
|
22
|
-
*/
|
|
23
|
-
get first()
|
|
24
|
-
{
|
|
25
|
-
return structuredClone(this._documents[0]._data);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Returns the last document of the collection
|
|
30
|
-
* @return object
|
|
31
|
-
*/
|
|
32
|
-
get last()
|
|
33
|
-
{
|
|
34
|
-
return structuredClone(this._documents[this._documents.length - 1]._data);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Return all the documents of the collection
|
|
39
|
-
* @return array
|
|
40
|
-
*/
|
|
41
|
-
get all()
|
|
42
|
-
{
|
|
43
|
-
return this._documents;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
1
|
+
const query = require('../query_language/query.js');
|
|
2
|
+
|
|
3
|
+
class collection extends query
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* Constructs class Collection to manage documents
|
|
7
|
+
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
* @param object validationSchema - in construction
|
|
10
|
+
* @return void
|
|
11
|
+
**/
|
|
12
|
+
constructor(validationSchema)
|
|
13
|
+
{
|
|
14
|
+
super(validationSchema);
|
|
15
|
+
this._documents = [];
|
|
16
|
+
this._indexes = [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns the first document of the collection
|
|
21
|
+
* @return object
|
|
22
|
+
*/
|
|
23
|
+
get first()
|
|
24
|
+
{
|
|
25
|
+
return structuredClone(this._documents[0]._data);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns the last document of the collection
|
|
30
|
+
* @return object
|
|
31
|
+
*/
|
|
32
|
+
get last()
|
|
33
|
+
{
|
|
34
|
+
return structuredClone(this._documents[this._documents.length - 1]._data);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Return all the documents of the collection
|
|
39
|
+
* @return array
|
|
40
|
+
*/
|
|
41
|
+
get all()
|
|
42
|
+
{
|
|
43
|
+
return this._documents;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
47
|
module.exports = collection;
|
package/src/dbs/database.js
CHANGED
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
const collection = require('../collections/collection.js');
|
|
2
|
-
|
|
3
|
-
class database
|
|
4
|
-
{
|
|
5
|
-
/**
|
|
6
|
-
* Constructs class Database to manage collections
|
|
7
|
-
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
* @param string name
|
|
10
|
-
* @return void
|
|
11
|
-
**/
|
|
12
|
-
constructor(name)
|
|
13
|
-
{
|
|
14
|
-
this._collections = {};
|
|
15
|
-
this._name = name;
|
|
16
|
-
this._collectionCount = 0;
|
|
17
|
-
|
|
18
|
-
return new Proxy(this, {
|
|
19
|
-
get: (target, prop, receiver) => {
|
|
20
|
-
if(prop in target._collections)
|
|
21
|
-
{
|
|
22
|
-
return target._collections[prop];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return target[prop];
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns the database name
|
|
32
|
-
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
33
|
-
* @version 1.0.0
|
|
34
|
-
* @param
|
|
35
|
-
* @return string
|
|
36
|
-
**/
|
|
37
|
-
get name()
|
|
38
|
-
{
|
|
39
|
-
return this._name;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Sets a new collection in the database
|
|
44
|
-
* @param string name
|
|
45
|
-
* @param object validationSchema - in construction
|
|
46
|
-
* @return void
|
|
47
|
-
*/
|
|
48
|
-
createCollection(name, validationSchema)
|
|
49
|
-
{
|
|
50
|
-
if(this._collections.hasOwnProperty(name) || typeof this[name] !== 'undefined')
|
|
51
|
-
{
|
|
52
|
-
throw new Error('Collection already exists');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
this._collections[name] = new collection(validationSchema);
|
|
56
|
-
this._collectionCount++;
|
|
57
|
-
|
|
58
|
-
//creates _id as a index unique
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Returns the number of collections in the database
|
|
63
|
-
* @param
|
|
64
|
-
* @return int
|
|
65
|
-
*/
|
|
66
|
-
countCollections()
|
|
67
|
-
{
|
|
68
|
-
return this._collectionCount;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
1
|
+
const collection = require('../collections/collection.js');
|
|
2
|
+
|
|
3
|
+
class database
|
|
4
|
+
{
|
|
5
|
+
/**
|
|
6
|
+
* Constructs class Database to manage collections
|
|
7
|
+
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
* @param string name
|
|
10
|
+
* @return void
|
|
11
|
+
**/
|
|
12
|
+
constructor(name)
|
|
13
|
+
{
|
|
14
|
+
this._collections = {};
|
|
15
|
+
this._name = name;
|
|
16
|
+
this._collectionCount = 0;
|
|
17
|
+
|
|
18
|
+
return new Proxy(this, {
|
|
19
|
+
get: (target, prop, receiver) => {
|
|
20
|
+
if(prop in target._collections)
|
|
21
|
+
{
|
|
22
|
+
return target._collections[prop];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return target[prop];
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Returns the database name
|
|
32
|
+
* @author Anderson Arruda < anderson@sysborg.com.br >
|
|
33
|
+
* @version 1.0.0
|
|
34
|
+
* @param
|
|
35
|
+
* @return string
|
|
36
|
+
**/
|
|
37
|
+
get name()
|
|
38
|
+
{
|
|
39
|
+
return this._name;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sets a new collection in the database
|
|
44
|
+
* @param string name
|
|
45
|
+
* @param object validationSchema - in construction
|
|
46
|
+
* @return void
|
|
47
|
+
*/
|
|
48
|
+
createCollection(name, validationSchema)
|
|
49
|
+
{
|
|
50
|
+
if(this._collections.hasOwnProperty(name) || typeof this[name] !== 'undefined')
|
|
51
|
+
{
|
|
52
|
+
throw new Error('Collection already exists');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this._collections[name] = new collection(validationSchema);
|
|
56
|
+
this._collectionCount++;
|
|
57
|
+
|
|
58
|
+
//creates _id as a index unique
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Returns the number of collections in the database
|
|
63
|
+
* @param
|
|
64
|
+
* @return int
|
|
65
|
+
*/
|
|
66
|
+
countCollections()
|
|
67
|
+
{
|
|
68
|
+
return this._collectionCount;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
72
|
module.exports = database;
|
package/src/documents/cursor.js
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @class Cursor
|
|
3
|
-
* @description Cursor class is used to represent the cursor in the document, adding some extra capabilities to object.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const documents = require('../documents/document.js');
|
|
7
|
-
|
|
8
|
-
class cursor {
|
|
9
|
-
/**
|
|
10
|
-
* @constructor
|
|
11
|
-
* @param array data
|
|
12
|
-
* @description Create a new cursor instance
|
|
13
|
-
*/
|
|
14
|
-
constructor(data, projection) {
|
|
15
|
-
this._data = typeof data === 'undefined' ? [] : data;
|
|
16
|
-
this.currIndex = 0;
|
|
17
|
-
if(typeof projection === 'object')
|
|
18
|
-
this.projection(projection);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @method hasNext
|
|
23
|
-
* @description Check if the cursor has more elements
|
|
24
|
-
* @return boolean
|
|
25
|
-
*/
|
|
26
|
-
hasNext() {
|
|
27
|
-
return this.currIndex < this._data.length;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @method next
|
|
32
|
-
* @description Get the next element in the cursor
|
|
33
|
-
* @return mixed
|
|
34
|
-
*/
|
|
35
|
-
next() {
|
|
36
|
-
if(!this.hasNext())
|
|
37
|
-
throw new Error('No more item to the cursor');
|
|
38
|
-
|
|
39
|
-
return this._data[this.currIndex++];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @method toArray
|
|
44
|
-
* @description Convert the cursor to an array
|
|
45
|
-
* @return array
|
|
46
|
-
*/
|
|
47
|
-
toArray() {
|
|
48
|
-
return structuredClone(this._data);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @methor reset
|
|
53
|
-
* @description Reset the cursor to the first element
|
|
54
|
-
* @return void
|
|
55
|
-
*/
|
|
56
|
-
reset() {
|
|
57
|
-
this.currIndex = 0;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @method first
|
|
62
|
-
* @description Get the first element in the cursor
|
|
63
|
-
* @return mixed
|
|
64
|
-
*/
|
|
65
|
-
first() {
|
|
66
|
-
return this._data[0]._data;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @method last
|
|
71
|
-
* @description Get the last element in the cursor
|
|
72
|
-
* @return mixed
|
|
73
|
-
*/
|
|
74
|
-
last() {
|
|
75
|
-
return this._data[this._data.length - 1];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @method sort
|
|
80
|
-
* @description Sort the cursor using collection
|
|
81
|
-
* @param json sortQuery
|
|
82
|
-
* @return void
|
|
83
|
-
*/
|
|
84
|
-
sort(sortQuery) {
|
|
85
|
-
const queryDoc = new documents(sortQuery);
|
|
86
|
-
this._data.sort((a, b) => {
|
|
87
|
-
for(const key of Object.keys(sortQuery))
|
|
88
|
-
{
|
|
89
|
-
const ascending = queryDoc[key] === 1;
|
|
90
|
-
if(a[key] > b[key])
|
|
91
|
-
return ascending ? 1 : -1;
|
|
92
|
-
|
|
93
|
-
if(a[key] < b[key])
|
|
94
|
-
return ascending ? -1 : 1;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return 0;
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @get length
|
|
103
|
-
* @description Get the number of elements in the cursor
|
|
104
|
-
* @return number
|
|
105
|
-
*/
|
|
106
|
-
get length() {
|
|
107
|
-
return this._data.length;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Projection of the cursor
|
|
112
|
-
* @param json projection
|
|
113
|
-
* @return cursor
|
|
114
|
-
*/
|
|
115
|
-
projection(projection) {
|
|
116
|
-
if(projection === null || typeof projection !== 'object')
|
|
117
|
-
return;
|
|
118
|
-
|
|
119
|
-
const self = this;
|
|
120
|
-
this._data.forEach(doc => {
|
|
121
|
-
for(const attribute of Object.keys(projection))
|
|
122
|
-
{
|
|
123
|
-
if(projection[attribute] === 0) {
|
|
124
|
-
doc.deleteProp(attribute, self);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* @method push
|
|
132
|
-
* @description Push an element to the cursor
|
|
133
|
-
* @param object element
|
|
134
|
-
* @return void
|
|
135
|
-
*/
|
|
136
|
-
push(element) {
|
|
137
|
-
if(typeof element !== 'object')
|
|
138
|
-
throw new Error('The element must be an object');
|
|
139
|
-
|
|
140
|
-
this._data.push(element);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @class Cursor
|
|
3
|
+
* @description Cursor class is used to represent the cursor in the document, adding some extra capabilities to object.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const documents = require('../documents/document.js');
|
|
7
|
+
|
|
8
|
+
class cursor {
|
|
9
|
+
/**
|
|
10
|
+
* @constructor
|
|
11
|
+
* @param array data
|
|
12
|
+
* @description Create a new cursor instance
|
|
13
|
+
*/
|
|
14
|
+
constructor(data, projection) {
|
|
15
|
+
this._data = typeof data === 'undefined' ? [] : data;
|
|
16
|
+
this.currIndex = 0;
|
|
17
|
+
if(typeof projection === 'object')
|
|
18
|
+
this.projection(projection);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @method hasNext
|
|
23
|
+
* @description Check if the cursor has more elements
|
|
24
|
+
* @return boolean
|
|
25
|
+
*/
|
|
26
|
+
hasNext() {
|
|
27
|
+
return this.currIndex < this._data.length;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @method next
|
|
32
|
+
* @description Get the next element in the cursor
|
|
33
|
+
* @return mixed
|
|
34
|
+
*/
|
|
35
|
+
next() {
|
|
36
|
+
if(!this.hasNext())
|
|
37
|
+
throw new Error('No more item to the cursor');
|
|
38
|
+
|
|
39
|
+
return this._data[this.currIndex++];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @method toArray
|
|
44
|
+
* @description Convert the cursor to an array
|
|
45
|
+
* @return array
|
|
46
|
+
*/
|
|
47
|
+
toArray() {
|
|
48
|
+
return structuredClone(this._data);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @methor reset
|
|
53
|
+
* @description Reset the cursor to the first element
|
|
54
|
+
* @return void
|
|
55
|
+
*/
|
|
56
|
+
reset() {
|
|
57
|
+
this.currIndex = 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @method first
|
|
62
|
+
* @description Get the first element in the cursor
|
|
63
|
+
* @return mixed
|
|
64
|
+
*/
|
|
65
|
+
first() {
|
|
66
|
+
return this._data[0]._data;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @method last
|
|
71
|
+
* @description Get the last element in the cursor
|
|
72
|
+
* @return mixed
|
|
73
|
+
*/
|
|
74
|
+
last() {
|
|
75
|
+
return this._data[this._data.length - 1];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @method sort
|
|
80
|
+
* @description Sort the cursor using collection
|
|
81
|
+
* @param json sortQuery
|
|
82
|
+
* @return void
|
|
83
|
+
*/
|
|
84
|
+
sort(sortQuery) {
|
|
85
|
+
const queryDoc = new documents(sortQuery);
|
|
86
|
+
this._data.sort((a, b) => {
|
|
87
|
+
for(const key of Object.keys(sortQuery))
|
|
88
|
+
{
|
|
89
|
+
const ascending = queryDoc[key] === 1;
|
|
90
|
+
if(a[key] > b[key])
|
|
91
|
+
return ascending ? 1 : -1;
|
|
92
|
+
|
|
93
|
+
if(a[key] < b[key])
|
|
94
|
+
return ascending ? -1 : 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return 0;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @get length
|
|
103
|
+
* @description Get the number of elements in the cursor
|
|
104
|
+
* @return number
|
|
105
|
+
*/
|
|
106
|
+
get length() {
|
|
107
|
+
return this._data.length;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Projection of the cursor
|
|
112
|
+
* @param json projection
|
|
113
|
+
* @return cursor
|
|
114
|
+
*/
|
|
115
|
+
projection(projection) {
|
|
116
|
+
if(projection === null || typeof projection !== 'object')
|
|
117
|
+
return;
|
|
118
|
+
|
|
119
|
+
const self = this;
|
|
120
|
+
this._data.forEach(doc => {
|
|
121
|
+
for(const attribute of Object.keys(projection))
|
|
122
|
+
{
|
|
123
|
+
if(projection[attribute] === 0) {
|
|
124
|
+
doc.deleteProp(attribute, self);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @method push
|
|
132
|
+
* @description Push an element to the cursor
|
|
133
|
+
* @param object element
|
|
134
|
+
* @return void
|
|
135
|
+
*/
|
|
136
|
+
push(element) {
|
|
137
|
+
if(typeof element !== 'object')
|
|
138
|
+
throw new Error('The element must be an object');
|
|
139
|
+
|
|
140
|
+
this._data.push(element);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
144
|
module.exports = cursor;
|