backend-plus 2.7.6 → 2.7.8
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/for-client/img/hide.png +0 -0
- package/for-client/img/show.png +0 -0
- package/for-client/login.jade +1 -0
- package/for-client/my-tables.js +19 -4
- package/lib/backend-plus.d.ts +2 -0
- package/lib/backend-plus.js +5 -0
- package/package.json +20 -31
- package/src/test/karma-test-dummy.ts +6 -0
- package/unlogged/my-ajax.js +6 -1
- package/src/test/karma-test-localdb.ts +0 -381
|
Binary file
|
|
Binary file
|
package/for-client/login.jade
CHANGED
package/for-client/my-tables.js
CHANGED
|
@@ -2347,12 +2347,16 @@ myOwn.TableGrid.prototype.prepareGrid = function prepareGrid(){
|
|
|
2347
2347
|
grid.actualName = (grid.def.gridAlias || grid.def.name) + (grid.connector.fixedFields.length ? '-' + JSON4all.toUrl(grid.connector.fixedFields.map(function(pair){ return pair.value; })) : '')
|
|
2348
2348
|
var captionTitle = grid.def.title;
|
|
2349
2349
|
grid.connector.fixedFields.forEach(function(pair){
|
|
2350
|
-
var
|
|
2350
|
+
var fixedFieldDef = grid.def.field[pair.fieldName] ?? (grid.def.functionDef?.parameters ?? []).find(function(parameter){ return parameter.name == pair.fieldName; });
|
|
2351
|
+
if(fixedFieldDef == null){
|
|
2352
|
+
throw new Error('the grid '+grid.def.name+' is filtered by '+pair.fieldName+' that is not a field nor a parameter of the table');
|
|
2353
|
+
}
|
|
2354
|
+
var toCaption = fixedFieldDef.toCaption ?? my.config.config['grid-smart-caption']
|
|
2351
2355
|
if(toCaption && pair.value != null){
|
|
2352
|
-
var typeName =
|
|
2356
|
+
var typeName = fixedFieldDef.typeName;
|
|
2353
2357
|
captionTitle += ' '
|
|
2354
2358
|
if(toCaption == 'labeled' || toCaption != 'alone' && (typeName == 'boolean' || typeName == 'integer' || typeName == 'bigint' || typeName == 'decimal')){
|
|
2355
|
-
captionTitle +=
|
|
2359
|
+
captionTitle += (fixedFieldDef.title ?? fixedFieldDef.name) + ':'
|
|
2356
2360
|
}
|
|
2357
2361
|
if(typeName == 'date'){
|
|
2358
2362
|
var date = bestGlobals.date(new Date(pair.value))
|
|
@@ -2613,8 +2617,8 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
|
|
|
2613
2617
|
if(!Object.keys(depot.rowPendingForUpdate).length){
|
|
2614
2618
|
return Promise.resolve();
|
|
2615
2619
|
}
|
|
2620
|
+
var specialMandatories=grid.def.specialValidator?myOwn.validators[grid.def.specialValidator].getMandatoryMap(depot.row):{};
|
|
2616
2621
|
if(depot.status==='new'){
|
|
2617
|
-
var specialMandatories=grid.def.specialValidator?myOwn.validators[grid.def.specialValidator].getMandatoryMap(depot.row):{};
|
|
2618
2622
|
var mandatoryOmitted=function(fieldDef){
|
|
2619
2623
|
return (specialMandatories[fieldDef.name] || fieldDef.nullable!==true && fieldDef.isPk || fieldDef.nullable===false)
|
|
2620
2624
|
&& depot.row[fieldDef.name]==null
|
|
@@ -2630,6 +2634,17 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
|
|
|
2630
2634
|
}
|
|
2631
2635
|
return Promise.resolve(); // no grabo todavía
|
|
2632
2636
|
};
|
|
2637
|
+
}else{
|
|
2638
|
+
// en una modificación solo se controlan los obligatorios especiales (campos que son obligatorios según lo cargado en otros)
|
|
2639
|
+
var specialOmitted=grid.def.fields.filter(function(fieldDef){
|
|
2640
|
+
return specialMandatories[fieldDef.name] && depot.row[fieldDef.name]==null;
|
|
2641
|
+
});
|
|
2642
|
+
if(specialOmitted.length){
|
|
2643
|
+
if(depot.tr){
|
|
2644
|
+
depot.tr.title = myOwn.messages.mandatoryFieldOmited + specialOmitted.map(f=>f.name).join(', ');
|
|
2645
|
+
}
|
|
2646
|
+
return Promise.resolve(); // no grabo todavía
|
|
2647
|
+
}
|
|
2633
2648
|
}
|
|
2634
2649
|
var timeStamp = my.setTimeStamp(depot.row);
|
|
2635
2650
|
return grid.connector.saveRecord(depot, opts).then(function(result){
|
package/lib/backend-plus.d.ts
CHANGED
|
@@ -424,6 +424,7 @@ export interface AppConfigServer
|
|
|
424
424
|
useCors: boolean //habilita Cross-Origin Resource Sharing
|
|
425
425
|
allowedHosts:string[] //determina API allowed hosts (necesita habilitar useCors)
|
|
426
426
|
policy?:string
|
|
427
|
+
environment?:string // 'production' or other (to choose defaults, for example the background)
|
|
427
428
|
}
|
|
428
429
|
export interface AppConfigDb
|
|
429
430
|
{
|
|
@@ -503,6 +504,7 @@ export interface AppConfigClientSetup // front-end config
|
|
|
503
504
|
version?:string
|
|
504
505
|
menu?:boolean
|
|
505
506
|
"background-img"?:string
|
|
507
|
+
environment?:string // copied from server.environment
|
|
506
508
|
devel?:boolean
|
|
507
509
|
deviceWidthForMobile?:string
|
|
508
510
|
"initial-scale"?:string
|
package/lib/backend-plus.js
CHANGED
|
@@ -823,6 +823,11 @@ AppBackend.prototype.start = function start(opts){
|
|
|
823
823
|
be.config = config;
|
|
824
824
|
be.clientSetup = {config: be.config["client-setup"]};
|
|
825
825
|
be.clientSetup.config.prefix = be.clientSetup.config.prefix || be.config.server["base-url"].substr(1)+':';
|
|
826
|
+
if(be.config.server.environment == 'production' && be.config.devel){
|
|
827
|
+
console.warn('WARNING: devel config in a production environment (server.environment: production). For the background, production prevails');
|
|
828
|
+
}
|
|
829
|
+
// the client uses the environment to choose the default background (see my-ajax.js)
|
|
830
|
+
be.clientSetup.config.environment = be.config.server.environment;
|
|
826
831
|
var downloadsConfig = be.config["client-setup"].downloads;
|
|
827
832
|
if(downloadsConfig != null){
|
|
828
833
|
if(downloadsConfig.method != null && !['legacy','SaveFilePicker'].includes(downloadsConfig.method)){
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-plus",
|
|
3
3
|
"description": "Backend for the anti Pareto rule",
|
|
4
|
-
"version": "2.7.
|
|
4
|
+
"version": "2.7.8",
|
|
5
5
|
"author": "Codenautas <codenautas@googlegroups.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "codenautas/backend-plus",
|
|
@@ -47,36 +47,36 @@
|
|
|
47
47
|
"cors": "^2.8.6",
|
|
48
48
|
"dialog-promise": "^0.10.7",
|
|
49
49
|
"ensure-login": "^0.1.6",
|
|
50
|
-
"express": "^5.
|
|
51
|
-
"express-useragent": "^2.2.
|
|
50
|
+
"express": "^5.3.0",
|
|
51
|
+
"express-useragent": "^2.2.3",
|
|
52
52
|
"fflate": "^0.8.3",
|
|
53
|
-
"fs-extra": "^11.4.
|
|
53
|
+
"fs-extra": "^11.4.1",
|
|
54
54
|
"js-to-html": "^1.4.0",
|
|
55
|
-
"js-yaml": "^5.
|
|
56
|
-
"json4all": "^1.4.
|
|
55
|
+
"js-yaml": "^5.4.3",
|
|
56
|
+
"json4all": "^1.4.5",
|
|
57
57
|
"lazy-some": "^0.1.0",
|
|
58
|
-
"like-ar": "^0.5.
|
|
58
|
+
"like-ar": "^0.5.4",
|
|
59
59
|
"login-plus": "^1.9.0",
|
|
60
60
|
"memorystore": "^1.6.8",
|
|
61
61
|
"mini-tools": "^1.13.10",
|
|
62
|
-
"moment": "^2.
|
|
63
|
-
"multiparty": "^4.3.
|
|
64
|
-
"nodemailer": "^
|
|
62
|
+
"moment": "^2.31.0",
|
|
63
|
+
"multiparty": "^4.3.1",
|
|
64
|
+
"nodemailer": "^10.0.16",
|
|
65
65
|
"numeral": "^2.0.6",
|
|
66
66
|
"pg-promise-strict": "^1.5.0",
|
|
67
67
|
"pg-triggers": "0.4.6",
|
|
68
68
|
"pikaday": "^1.8.2",
|
|
69
|
-
"require-bro": "^0.4.
|
|
69
|
+
"require-bro": "^0.4.1",
|
|
70
70
|
"serve-content": "^1.0.6",
|
|
71
71
|
"session-file-store": "^1.5.0",
|
|
72
|
-
"simple-git": "^
|
|
72
|
+
"simple-git": "^4.0.2",
|
|
73
73
|
"sql-tools": "^0.1.7",
|
|
74
74
|
"stack-trace": "^1.0.0",
|
|
75
75
|
"tab-plus": "^0.2.0",
|
|
76
76
|
"type-store": "^0.6.1",
|
|
77
77
|
"typed-controls": "^0.12.7",
|
|
78
78
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
|
|
79
|
-
"xlsx-now": "^0.
|
|
79
|
+
"xlsx-now": "^0.5.0"
|
|
80
80
|
},
|
|
81
81
|
"devDependencies": {
|
|
82
82
|
"@types/big.js": "^7.0.0",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"@types/js-yaml": "^4.0.9",
|
|
88
88
|
"@types/mocha": "^10.0.10",
|
|
89
89
|
"@types/multiparty": "^4.2.1",
|
|
90
|
-
"@types/node": "^26.
|
|
91
|
-
"@types/nodemailer": "^8.0.
|
|
90
|
+
"@types/node": "^26.6.5",
|
|
91
|
+
"@types/nodemailer": "^8.0.2",
|
|
92
92
|
"@types/numeral": "~2.0.5",
|
|
93
93
|
"@types/session-file-store": "^1.2.6",
|
|
94
94
|
"@types/stack-trace": "^0.0.33",
|
|
@@ -97,24 +97,16 @@
|
|
|
97
97
|
"discrepances": "^0.2.14",
|
|
98
98
|
"esprima": "^4.0.1",
|
|
99
99
|
"expect.js": "^0.3.1",
|
|
100
|
-
"karma": "6.4.4",
|
|
101
|
-
"karma-chrome-launcher": "^3.2.0",
|
|
102
|
-
"karma-expect": "^1.1.3",
|
|
103
|
-
"karma-firefox-launcher": "^2.1.3",
|
|
104
|
-
"karma-ie-launcher": "^1.0.0",
|
|
105
|
-
"karma-mocha": "^2.0.1",
|
|
106
100
|
"kill-9": "^0.4.3",
|
|
107
|
-
"mocha": "^12.0.
|
|
108
|
-
"
|
|
109
|
-
"puppeteer": "^25.4.0",
|
|
110
|
-
"qa-control": "0.9.2",
|
|
101
|
+
"mocha": "^12.0.3",
|
|
102
|
+
"qa-control": "0.12.1",
|
|
111
103
|
"regexplicit": "^0.1.3",
|
|
112
104
|
"self-explain": "^0.11.0",
|
|
113
105
|
"sinon": "^22.1.0",
|
|
114
|
-
"supertest": "^7.
|
|
115
|
-
"types.d.ts": "^0.
|
|
106
|
+
"supertest": "^7.3.1",
|
|
107
|
+
"types.d.ts": "^0.7.1",
|
|
116
108
|
"typescript": "^5.9.3",
|
|
117
|
-
"why-is-node-running": "^3.2.
|
|
109
|
+
"why-is-node-running": "^3.2.3"
|
|
118
110
|
},
|
|
119
111
|
"engines": {
|
|
120
112
|
"node": ">= 22"
|
|
@@ -122,13 +114,10 @@
|
|
|
122
114
|
"scripts": {
|
|
123
115
|
"test": "echo testear SiPer que usa la mayoría de la funcionalidad de Backend-Plus",
|
|
124
116
|
"test-ui": "(npm run prepublish || echo \"continue w/error\") && mocha --reporter spec --single-run --bail test/test-*.js",
|
|
125
|
-
"test-karma": "(npm run prepublish || echo \"continue w/error\") && mocha --reporter spec --bail test/test-k*.js",
|
|
126
117
|
"test-why": "node --expose-internals ./node_modules/mocha/bin/_mocha --reporter spec --bail test/test*.js",
|
|
127
118
|
"test-ci": "npm test",
|
|
128
119
|
"test-cov": "(npm run prepublish || echo \"continue w/error\") && mocha --reporter spec --bail test/test*.js",
|
|
129
120
|
"test-good": "mocha --reporter spec --bail --check-leaks test/test*.js",
|
|
130
|
-
"example-pu": "node test/puppeteer/first-step.js",
|
|
131
|
-
"test-pu": "node ./test/download_puppeteer && mocha --reporter spec --bail --check-leaks --globals cptable --globals QUOTE --globals __core-js_shared__ test/test-pu.js",
|
|
132
121
|
"test-server": "mocha --reporter spec --single-run --bail test/test.js",
|
|
133
122
|
"server-test": "node test/run-simple-backend.js",
|
|
134
123
|
"example-tables": "node examples/tables/server/server-tables.js --dir-x examples/tables",
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// No es un test. Existe para que tsconfig-client.json compile archivos de dos
|
|
2
|
+
// carpetas (src/for-client y src/test): tsc toma como raíz la carpeta común a
|
|
3
|
+
// todo lo que compila, y si solo quedara src/for-client la salida iría a la
|
|
4
|
+
// raíz del proyecto en vez de a ./for-client.
|
|
5
|
+
// TODO: Cambiar la configuración para uqe este archivo no sea necesario.
|
|
6
|
+
export {};
|
package/unlogged/my-ajax.js
CHANGED
|
@@ -111,6 +111,8 @@ myAjax.readProcedureDefinitions=function readProcedureDefinitions(){
|
|
|
111
111
|
var backgroundUrl
|
|
112
112
|
if(my.config.config && my.config.config['background-img']){
|
|
113
113
|
backgroundUrl = 'url("'+my.path.img+my.config.config['background-img']+'")'
|
|
114
|
+
}else if(my.config.config && my.config.config.environment == 'production'){
|
|
115
|
+
backgroundUrl = '';
|
|
114
116
|
}else{
|
|
115
117
|
if(/(^|[-_0-9/])(test|pru|prueba)($|[-_0-9/])/.test(location.pathname)){
|
|
116
118
|
backgroundUrl = 'url("img/background-test.png")';
|
|
@@ -119,10 +121,13 @@ myAjax.readProcedureDefinitions=function readProcedureDefinitions(){
|
|
|
119
121
|
}else if(/(^|[-_0-9/])(desa|devel)($|[-_0-9/])/.test(location.pathname) || my.config.config && my.config.config['devel']){
|
|
120
122
|
backgroundUrl = 'url("img/background-devel.png")';
|
|
121
123
|
}else{
|
|
122
|
-
|
|
124
|
+
// unknown environment: better to see a missing image than no background (declare server.environment)
|
|
125
|
+
backgroundUrl = 'url("img/background-unknown.png")';
|
|
123
126
|
}
|
|
124
127
|
}
|
|
125
128
|
document.body.style.backgroundImage=backgroundUrl;
|
|
129
|
+
// for the apps that need the background in other elements
|
|
130
|
+
my.backgroundUrl=backgroundUrl;
|
|
126
131
|
}
|
|
127
132
|
}).then(function(){
|
|
128
133
|
my.config.procedure=my.config.procedure||{};
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/// <reference path="../node_modules/types.d.ts/modules/myOwn/in-myOwn.d.ts" />
|
|
4
|
-
/// <reference path="../../lib/in-backend-plus.d.ts" />
|
|
5
|
-
/// <reference path="../../src/for-client/my-localdb.ts" />
|
|
6
|
-
/// <reference path="../../src/for-client/my-websqldb.ts" />
|
|
7
|
-
|
|
8
|
-
import {LocalDb, LocalDbTransaction, TableDefinition} from "../for-client/my-localdb";
|
|
9
|
-
import {changing} from "best-globals";
|
|
10
|
-
import "mocha";
|
|
11
|
-
import { WebsqlDb } from "../for-client/my-websqldb";
|
|
12
|
-
|
|
13
|
-
function compare<T>(obtained:T, expected:T):boolean{
|
|
14
|
-
expect(obtained).to.eql(expected);
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
before(function(){
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
window.myOwn=window.myOwn||{};
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
window.myOwn.config=window.myOwn.config||{};
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
window.myOwn.config.useragent=new UserAgent().parse(window.navigator.userAgent);
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
describe("websql-db", function(){
|
|
28
|
-
var ldb:WebsqlDb;
|
|
29
|
-
before(function(){
|
|
30
|
-
this.timeout(10000);
|
|
31
|
-
ldb = new WebsqlDb("the-test-name"+Math.random());
|
|
32
|
-
});
|
|
33
|
-
after(function(){
|
|
34
|
-
//ldb.close();
|
|
35
|
-
});
|
|
36
|
-
describe("structures", function(){
|
|
37
|
-
it("put and get structure", async function(){
|
|
38
|
-
this.timeout(10000);
|
|
39
|
-
var tableDef:TableDefinition={
|
|
40
|
-
name:'this_name',
|
|
41
|
-
fields:[
|
|
42
|
-
{name: 'pk1', typeName:'text'}
|
|
43
|
-
],
|
|
44
|
-
primaryKey:['pk1']
|
|
45
|
-
};
|
|
46
|
-
await ldb.registerStructure(tableDef);
|
|
47
|
-
var newTableDef = await ldb.getStructure(tableDef.name);
|
|
48
|
-
compare(tableDef, newTableDef);
|
|
49
|
-
});
|
|
50
|
-
it("check if exists and exists", async function(){
|
|
51
|
-
this.timeout(10000);
|
|
52
|
-
var tableDef={
|
|
53
|
-
name:'this_name',
|
|
54
|
-
fields:[
|
|
55
|
-
{name: 'pk1', typeName:'text'}
|
|
56
|
-
],
|
|
57
|
-
primaryKey:['pk1']
|
|
58
|
-
};
|
|
59
|
-
var exists:boolean = await ldb.existsStructure(tableDef.name);
|
|
60
|
-
compare(true, exists);
|
|
61
|
-
});
|
|
62
|
-
it("check if exists and not exists", async function(){
|
|
63
|
-
this.timeout(10000);
|
|
64
|
-
var tableDef={
|
|
65
|
-
name:'inexistent_this_name',
|
|
66
|
-
fields:[
|
|
67
|
-
{name: 'pk1', typeName:'text'}
|
|
68
|
-
],
|
|
69
|
-
primaryKey:['pk1']
|
|
70
|
-
};
|
|
71
|
-
var exists:boolean = await ldb.existsStructure(tableDef.name);
|
|
72
|
-
compare(false, exists);
|
|
73
|
-
});
|
|
74
|
-
it("check empty structure", async function(){
|
|
75
|
-
this.timeout(10000);
|
|
76
|
-
var tableDef={
|
|
77
|
-
name:'this_name',
|
|
78
|
-
fields:[
|
|
79
|
-
{name: 'pk1', typeName:'text'}
|
|
80
|
-
],
|
|
81
|
-
primaryKey:['pk1']
|
|
82
|
-
};
|
|
83
|
-
var isEmpty:boolean = await ldb.isEmpty(tableDef.name);
|
|
84
|
-
compare(true, isEmpty);
|
|
85
|
-
});
|
|
86
|
-
it("reput and get structure", async function(){
|
|
87
|
-
this.timeout(10000);
|
|
88
|
-
var tableDef={
|
|
89
|
-
name:'this_name',
|
|
90
|
-
fields:[
|
|
91
|
-
{name: 'pk1', typeName:'text'},
|
|
92
|
-
{name: 'field1', typeName:'text'}
|
|
93
|
-
],
|
|
94
|
-
primaryKey:['pk1']
|
|
95
|
-
};
|
|
96
|
-
await ldb.registerStructure(tableDef);
|
|
97
|
-
var newTableDef = await ldb.getStructure(tableDef.name);
|
|
98
|
-
compare(tableDef, newTableDef);
|
|
99
|
-
});
|
|
100
|
-
it("put another structure", async function(){
|
|
101
|
-
this.timeout(10000);
|
|
102
|
-
var tableDef={
|
|
103
|
-
name:'other_name',
|
|
104
|
-
fields:[
|
|
105
|
-
{name: 'pk2', typeName:'text'}
|
|
106
|
-
],
|
|
107
|
-
primaryKey:['pk2']
|
|
108
|
-
};
|
|
109
|
-
await ldb.registerStructure(tableDef);
|
|
110
|
-
var newTableDef = await ldb.getStructure(tableDef.name);
|
|
111
|
-
compare(tableDef, newTableDef);
|
|
112
|
-
});
|
|
113
|
-
it("get all structures", async function(){
|
|
114
|
-
this.timeout(10000);
|
|
115
|
-
var tableDef1 = await ldb.getStructure('this_name');
|
|
116
|
-
var tableDef2 = await ldb.getStructure('other_name');
|
|
117
|
-
var tableDefs = await ldb.getAllStructures();
|
|
118
|
-
compare([tableDef1, tableDef2], tableDefs);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
describe("data", function(){
|
|
122
|
-
type Quantity = {
|
|
123
|
-
quantity:string,
|
|
124
|
-
preferedUnit:string
|
|
125
|
-
}
|
|
126
|
-
var tableDef:TableDefinition={
|
|
127
|
-
name:'phisical_quantities',
|
|
128
|
-
fields:[
|
|
129
|
-
{name: 'quantity', typeName:'text'},
|
|
130
|
-
{name: 'preferedUnit', typeName:'text'}
|
|
131
|
-
],
|
|
132
|
-
primaryKey:['quantity']
|
|
133
|
-
}
|
|
134
|
-
var mass:Quantity = {quantity: 'mass', preferedUnit:'g'};
|
|
135
|
-
var quantities:Quantity[]=[
|
|
136
|
-
mass,
|
|
137
|
-
{quantity:'time', preferedUnit:'s'},
|
|
138
|
-
{quantity:'volume', preferedUnit:'l'},
|
|
139
|
-
];
|
|
140
|
-
before(async function(){
|
|
141
|
-
await ldb.registerStructure(tableDef);
|
|
142
|
-
});
|
|
143
|
-
it("put a value", async function(){
|
|
144
|
-
var obtainedMass = await ldb.putOne("phisical_quantities", mass);
|
|
145
|
-
compare(mass, obtainedMass);
|
|
146
|
-
})
|
|
147
|
-
it("put many", async function(){
|
|
148
|
-
await ldb.putMany("phisical_quantities", quantities.slice(1));
|
|
149
|
-
})
|
|
150
|
-
it("check empty structure", async function(){
|
|
151
|
-
var count:boolean = await ldb.isEmpty("phisical_quantities");
|
|
152
|
-
compare(false, count);
|
|
153
|
-
});
|
|
154
|
-
it("get one", async function(){
|
|
155
|
-
var volume = await ldb.getOne<Quantity>("phisical_quantities", ["volume"]);
|
|
156
|
-
compare(volume, quantities[2]);
|
|
157
|
-
})
|
|
158
|
-
it("get one if exists and exists", async function(){
|
|
159
|
-
var time = await ldb.getOneIfExists<Quantity>("phisical_quantities", ["time"]);
|
|
160
|
-
compare(time, quantities[1]);
|
|
161
|
-
})
|
|
162
|
-
it("get one if exists and do not exists", async function(){
|
|
163
|
-
var undef = await ldb.getOneIfExists<Quantity>("phisical_quantities", ["fourth dimension"]);
|
|
164
|
-
compare(undef, undefined);
|
|
165
|
-
})
|
|
166
|
-
it("get all",async function(){
|
|
167
|
-
var all = await ldb.getAll<Quantity>("phisical_quantities");
|
|
168
|
-
compare(all, quantities);
|
|
169
|
-
})
|
|
170
|
-
it("clear all",async function(){
|
|
171
|
-
await ldb.clear("phisical_quantities");
|
|
172
|
-
var all = await ldb.getAll<Quantity>("phisical_quantities");
|
|
173
|
-
compare(all, []);
|
|
174
|
-
})
|
|
175
|
-
});
|
|
176
|
-
describe("childs",function(){
|
|
177
|
-
type Units = {
|
|
178
|
-
quantity:string,
|
|
179
|
-
unit:string
|
|
180
|
-
}
|
|
181
|
-
var tableDef:TableDefinition={
|
|
182
|
-
fields:[
|
|
183
|
-
{name: 'quantity', typeName:'text'},
|
|
184
|
-
{name: 'unit' , typeName:'text'}
|
|
185
|
-
],
|
|
186
|
-
name:'units',
|
|
187
|
-
primaryKey:['quantity', 'unit']
|
|
188
|
-
}
|
|
189
|
-
var volumeUnits=[
|
|
190
|
-
{quantity:'volume', unit:'ml'},
|
|
191
|
-
{quantity:'volume', unit:'l'},
|
|
192
|
-
{quantity:'volume', unit:'cm3'},
|
|
193
|
-
{quantity:'volume', unit:'m3'},
|
|
194
|
-
]
|
|
195
|
-
var volumeUnitsSorted=[
|
|
196
|
-
{quantity:'volume', unit:'cm3'},
|
|
197
|
-
{quantity:'volume', unit:'l'},
|
|
198
|
-
{quantity:'volume', unit:'m3'},
|
|
199
|
-
{quantity:'volume', unit:'ml'},
|
|
200
|
-
]
|
|
201
|
-
var massUnits=[
|
|
202
|
-
{quantity:'mass', unit:'g'},
|
|
203
|
-
{quantity:'mass', unit:'kg'},
|
|
204
|
-
{quantity:'mass', unit:'mg'},
|
|
205
|
-
]
|
|
206
|
-
var timeUnits=[
|
|
207
|
-
{quantity:'time', unit:'s'},
|
|
208
|
-
{quantity:'time', unit:'h'},
|
|
209
|
-
]
|
|
210
|
-
var units=volumeUnits.concat(massUnits).concat(timeUnits);
|
|
211
|
-
before("",async function(){
|
|
212
|
-
await ldb.registerStructure(tableDef);
|
|
213
|
-
await ldb.putMany("units", units);
|
|
214
|
-
})
|
|
215
|
-
it("get cm3", async function(){
|
|
216
|
-
var obtainedVolumes=await ldb.getOne<Units>("units", ["volume","cm3"]);
|
|
217
|
-
compare(obtainedVolumes, volumeUnits[2]);
|
|
218
|
-
})
|
|
219
|
-
it("get volume childs", async function(){
|
|
220
|
-
var obtainedVolumes=await ldb.getChild<Units>("units", ["volume"]);
|
|
221
|
-
compare(obtainedVolumes, volumeUnitsSorted);
|
|
222
|
-
})
|
|
223
|
-
it("get mass childs", async function(){
|
|
224
|
-
var obtainedMass=await ldb.getChild("units", ["mass"]);
|
|
225
|
-
compare(obtainedMass, massUnits);
|
|
226
|
-
})
|
|
227
|
-
})
|
|
228
|
-
describe("foreignKeys",function(){
|
|
229
|
-
this.timeout(10000);
|
|
230
|
-
type Product = {
|
|
231
|
-
product:string,
|
|
232
|
-
name:string,
|
|
233
|
-
price:number,
|
|
234
|
-
quantity_number: number,
|
|
235
|
-
quantity: string,
|
|
236
|
-
unit: string,
|
|
237
|
-
units__description: string
|
|
238
|
-
}
|
|
239
|
-
type Units = {
|
|
240
|
-
quantity:string,
|
|
241
|
-
unit:string,
|
|
242
|
-
description: string,
|
|
243
|
-
}
|
|
244
|
-
var unitsTableDef:TableDefinition={
|
|
245
|
-
name:'units',
|
|
246
|
-
fields:[
|
|
247
|
-
{name: 'quantity' , typeName:'text'},
|
|
248
|
-
{name: 'unit' , typeName:'text'},
|
|
249
|
-
{name: 'description' , typeName:'text'}
|
|
250
|
-
],
|
|
251
|
-
primaryKey:['quantity', 'unit']
|
|
252
|
-
}
|
|
253
|
-
var productsTableDef:TableDefinition={
|
|
254
|
-
name:'products',
|
|
255
|
-
fields:[
|
|
256
|
-
{name: 'product' , typeName:'text'},
|
|
257
|
-
{name: 'name' , typeName:'text'},
|
|
258
|
-
{name: 'price' , typeName:'decimal'},
|
|
259
|
-
{name: 'quantity_number' , typeName:'integer'},
|
|
260
|
-
{name: 'quantity' , typeName:'text'},
|
|
261
|
-
{name: 'unit' , typeName:'text'},
|
|
262
|
-
{name: 'units__description' , typeName:'text'}
|
|
263
|
-
],
|
|
264
|
-
primaryKey:['product'],
|
|
265
|
-
foreignKeys: [{references:'units', fields:[{source:'quantity', target:'quantity'}, {source:'unit', target:'unit'}], displayFields:['description'], alias:'units'}]
|
|
266
|
-
}
|
|
267
|
-
var volumeUnits:Units[]=[
|
|
268
|
-
{quantity:'volume', unit:'ml', description:'millilitre'},
|
|
269
|
-
{quantity:'volume', unit:'l', description:'litre'},
|
|
270
|
-
{quantity:'volume', unit:'cm3', description:'cubic centimetre'},
|
|
271
|
-
{quantity:'volume', unit:'m3', description:'cubic metre'},
|
|
272
|
-
]
|
|
273
|
-
var massUnits:Units[]=[
|
|
274
|
-
{quantity:'mass', unit:'g', description:'gram'},
|
|
275
|
-
{quantity:'mass', unit:'kg', description:'kilogram'},
|
|
276
|
-
{quantity:'mass', unit:'mg', description:'milligram'},
|
|
277
|
-
]
|
|
278
|
-
var timeUnits:Units[]=[
|
|
279
|
-
{quantity:'time', unit:'s', description:'second'},
|
|
280
|
-
{quantity:'time', unit:'m', description:'minute'},
|
|
281
|
-
{quantity:'time', unit:'h', description:'hour'},
|
|
282
|
-
]
|
|
283
|
-
|
|
284
|
-
var products:Product[]=[
|
|
285
|
-
{product:'P11111', name: 'Gaseosa', price:35.50, quantity_number: 750, quantity: 'volume', unit: 'cm3', units__description: 'cubic centimetre'},
|
|
286
|
-
{product:'P22222', name: 'Naranjas', price:25, quantity_number: 1, quantity: 'mass', unit: 'kg', units__description: 'kilogram'},
|
|
287
|
-
{product:'P33333', name: 'Pelicula', price:150, quantity_number: 1.5, quantity: 'time', unit: 'h', units__description: 'hour'},
|
|
288
|
-
]
|
|
289
|
-
var units=volumeUnits.concat(massUnits).concat(timeUnits);
|
|
290
|
-
before("",async function(){
|
|
291
|
-
await ldb.registerStructure(unitsTableDef);
|
|
292
|
-
await ldb.registerStructure(productsTableDef);
|
|
293
|
-
await ldb.putMany("units", units);
|
|
294
|
-
await ldb.putMany("products", products);
|
|
295
|
-
})
|
|
296
|
-
it("get product and change unit", async function(){
|
|
297
|
-
var myProduct=await ldb.getOne<Product>("products", ["P11111"]);
|
|
298
|
-
myProduct.unit = 'ml';
|
|
299
|
-
var myChangedProduct = await ldb.putOne("products", myProduct);
|
|
300
|
-
compare(myChangedProduct, changing(products[0],{unit:'ml', units__description:'millilitre'}));
|
|
301
|
-
})
|
|
302
|
-
})
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
//
|
|
307
|
-
//describe("local-db-transaction", function(){
|
|
308
|
-
// /** @type {(callback:(ldb:any)=>Promise<T>)=>Promise<T>} */
|
|
309
|
-
// var inLdb;
|
|
310
|
-
// var tableDef;
|
|
311
|
-
// var tableDef2;
|
|
312
|
-
// var tableDef3;
|
|
313
|
-
// var databaseName: string;
|
|
314
|
-
// before(function(){
|
|
315
|
-
// databaseName = "the-test-name"+Math.random();
|
|
316
|
-
// inLdb = new LocalDbTransaction(databaseName).getBindedInTransaction();
|
|
317
|
-
// tableDef={
|
|
318
|
-
// name:'this_name',
|
|
319
|
-
// fields:[
|
|
320
|
-
// {name: 'pk1', typeName:'text'}
|
|
321
|
-
// ],
|
|
322
|
-
// primaryKey:['pk1']
|
|
323
|
-
// };
|
|
324
|
-
// tableDef2={
|
|
325
|
-
// name:'other_name',
|
|
326
|
-
// fields:[
|
|
327
|
-
// {name: 'pk2', typeName:'text'}
|
|
328
|
-
// ],
|
|
329
|
-
// primaryKey:['pk2']
|
|
330
|
-
// };
|
|
331
|
-
// tableDef3={
|
|
332
|
-
// name:'another_name',
|
|
333
|
-
// fields:[
|
|
334
|
-
// {name: 'pk3', typeName:'text'}
|
|
335
|
-
// ],
|
|
336
|
-
// primaryKey:['pk3']
|
|
337
|
-
// };
|
|
338
|
-
// });
|
|
339
|
-
// describe("structures", function(){
|
|
340
|
-
// it("put and get structure", async function(){
|
|
341
|
-
// this.timeout(10000);
|
|
342
|
-
// var structure = await inLdb(async function(ldb){
|
|
343
|
-
// await ldb.registerStructure(tableDef);
|
|
344
|
-
// return ldb.getStructure(tableDef.name)
|
|
345
|
-
// });
|
|
346
|
-
// compare(tableDef,structure);
|
|
347
|
-
// });
|
|
348
|
-
// it("drop database and put structure", async function(){
|
|
349
|
-
// this.timeout(10000);
|
|
350
|
-
// await LocalDb.deleteDatabase(databaseName);
|
|
351
|
-
// var structure = await inLdb(async function(ldb){
|
|
352
|
-
// await ldb.registerStructure(tableDef);
|
|
353
|
-
// return ldb.getStructure(tableDef.name)
|
|
354
|
-
// });
|
|
355
|
-
// compare(tableDef,structure);
|
|
356
|
-
// });
|
|
357
|
-
// it("drop database and put a collection of structures", async function(){
|
|
358
|
-
// this.timeout(10000);
|
|
359
|
-
// var structures = [tableDef, tableDef2, tableDef3]
|
|
360
|
-
// await LocalDb.deleteDatabase(databaseName);
|
|
361
|
-
// var registeredStructs = await inLdb(async function(ldb){
|
|
362
|
-
// var promiseChain=Promise.resolve();
|
|
363
|
-
// structures.forEach(async function(structureToRegister){
|
|
364
|
-
// promiseChain = promiseChain.then(function(){
|
|
365
|
-
// return ldb.registerStructure(structureToRegister);
|
|
366
|
-
// });
|
|
367
|
-
// });
|
|
368
|
-
// promiseChain = promiseChain.then(async function(){
|
|
369
|
-
// var struct = await ldb.getStructure(tableDef.name);
|
|
370
|
-
// var struct2 = await ldb.getStructure(tableDef2.name);
|
|
371
|
-
// var struct3 = await ldb.getStructure(tableDef3.name);
|
|
372
|
-
// return [struct,struct2,struct3]
|
|
373
|
-
// });
|
|
374
|
-
// return promiseChain;
|
|
375
|
-
// });
|
|
376
|
-
// compare(tableDef,registeredStructs[0]);
|
|
377
|
-
// compare(tableDef2,registeredStructs[1]);
|
|
378
|
-
// compare(tableDef3,registeredStructs[2]);
|
|
379
|
-
// });
|
|
380
|
-
// });
|
|
381
|
-
//});
|