backend-plus 1.19.7 → 2.0.0-beta.10
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/README.md +7 -6
- package/for-client/my-menu.js +1 -1
- package/for-client/my-tables.js +64 -32
- package/for-client/my-things.js +3 -2
- package/lib/backend-plus.d.ts +3 -2
- package/lib/backend-plus.js +79 -42
- package/lib/procedures-table.js +3 -0
- package/lib/table-def-adapt.js +1 -1
- package/lib/tables/table-bitacora.js +5 -3
- package/lib/tables/table-locks.js +1 -0
- package/lib/tables/table-summary.js +2 -0
- package/lib/tables/table-tokens.js +3 -1
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
# backend-plus
|
|
4
4
|
|
|
5
|
-
Backend for
|
|
5
|
+
Backend for the anti Pareto rule.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|

|
|
9
|
-
[](https://npmjs.org/package/backend-star)
|
|
10
|
+
[](https://npmjs.org/package/backend-star)
|
|
11
|
+
[](https://travis-ci.org/codenautas/backend-star)
|
|
12
|
+
[](https://coveralls.io/r/codenautas/backend-star)
|
|
13
|
+
[](https://david-dm.org/codenautas/backend-star)
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
language: 
|
|
@@ -60,6 +60,7 @@ menuContent | A | | menu | menu content
|
|
|
60
60
|
table | T | `name` | table | table name
|
|
61
61
|
label | T | `name` | | if you don't want to use default value to display in menu
|
|
62
62
|
selectedByDefault | B | | | is the selected by default option
|
|
63
|
+
autoproced | B | `false` | proc | if yo want to execute the procedure without clicking the proced button
|
|
63
64
|
|
|
64
65
|
Integrating example:
|
|
65
66
|
|
package/for-client/my-menu.js
CHANGED
|
@@ -67,7 +67,7 @@ myOwn.wScreens.table = function(addrParams){
|
|
|
67
67
|
myOwn.wScreens.procAux = {
|
|
68
68
|
showParams:function(formDef, main_layout, addrParams, mainAction){
|
|
69
69
|
var autoproced = addrParams.autoproced || false
|
|
70
|
-
addrParams.up=addrParams.up||{};
|
|
70
|
+
addrParams.up=addrParams.up||addrParams.ff||{};
|
|
71
71
|
var params=addrParams.up;
|
|
72
72
|
// var button = html.button(formDef.proceedLabel||my.messages.proceed).create();
|
|
73
73
|
var label = formDef.proceedLabel||my.messages.proceed;
|
package/for-client/my-tables.js
CHANGED
|
@@ -284,6 +284,8 @@ myOwn.getStructuresToRegisterInLdb = function getStructuresToRegisterInLdb(paren
|
|
|
284
284
|
return promiseChain;
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
+
myOwn.skipInFixedFields = Symbol("skipInFixedFields");
|
|
288
|
+
|
|
287
289
|
myOwn.TableConnector = function(context, opts){
|
|
288
290
|
var connector = this;
|
|
289
291
|
for(var attr in context){
|
|
@@ -293,7 +295,7 @@ myOwn.TableConnector = function(context, opts){
|
|
|
293
295
|
connector.fixedFields = connector.opts.fixedFields || [];
|
|
294
296
|
connector.fixedField = {};
|
|
295
297
|
connector.fixedFields.forEach(function(pair){
|
|
296
|
-
if(!pair.range){
|
|
298
|
+
if(!pair.range && pair.value != myOwn.skipInFixedFields){
|
|
297
299
|
connector.fixedField[pair.fieldName] = pair.value;
|
|
298
300
|
}
|
|
299
301
|
});
|
|
@@ -442,7 +444,7 @@ myOwn.TableConnectorLocal = function(context, opts){
|
|
|
442
444
|
connector.fixedFields = connector.opts.fixedFields || [];
|
|
443
445
|
connector.fixedField = {};
|
|
444
446
|
connector.fixedFields.forEach(function(pair){
|
|
445
|
-
if(!pair.range){
|
|
447
|
+
if(!pair.range && pair.value != myOwn.skipInFixedFields){
|
|
446
448
|
connector.fixedField[pair.fieldName] = pair.value;
|
|
447
449
|
}
|
|
448
450
|
});
|
|
@@ -573,7 +575,6 @@ myOwn.setTimeStamp = function setTimeStamp(row){
|
|
|
573
575
|
|
|
574
576
|
myOwn.skipTimeStamp = function skipTimeStamp(row, timeStamp){
|
|
575
577
|
var skip = (row[TIME_STAMP_PROP] || 0) > timeStamp;
|
|
576
|
-
console.log(skip ? 'SKIP' : 'PASS', timeStamp, row[TIME_STAMP_PROP], JSON4all.toUrl(row))
|
|
577
578
|
if (!skip) row[TIME_STAMP_PROP] = timeStamp;
|
|
578
579
|
return skip;
|
|
579
580
|
}
|
|
@@ -601,9 +602,9 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
|
|
|
601
602
|
}
|
|
602
603
|
})
|
|
603
604
|
}
|
|
604
|
-
grid.refreshAllRows = function(){
|
|
605
|
+
grid.refreshAllRows = async function(force){
|
|
605
606
|
var timeStamp = new Date().getTime();
|
|
606
|
-
grid.connector.my.ajax.table_data({
|
|
607
|
+
await grid.connector.my.ajax.table_data({
|
|
607
608
|
table:grid.connector.tableName,
|
|
608
609
|
fixedFields:grid.connector.fixedFields,
|
|
609
610
|
paramfun:grid.connector.parameterFunctions||{}
|
|
@@ -624,7 +625,34 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
|
|
|
624
625
|
return sameValue(JSON.stringify(primaryKeyValuesForRow),JSON.stringify(primaryKeyValuesForDepotRow))
|
|
625
626
|
});
|
|
626
627
|
//chequeo que exista depot por las dudas
|
|
627
|
-
if (depot) {
|
|
628
|
+
if ((!depot || !depot.tr || !depot.tr.parentNode) && !thereIsANewRecord && !grid.vertical) {
|
|
629
|
+
if (!depot) {
|
|
630
|
+
var depot = grid.createDepotFromRow(row);
|
|
631
|
+
grid.depots.push(depot);
|
|
632
|
+
grid.sortDepotsToDisplay(grid.depots);
|
|
633
|
+
} else if (depot.tr && !depot.tr.parentNode) {
|
|
634
|
+
depot.tr = null
|
|
635
|
+
}
|
|
636
|
+
var iRow = -1;
|
|
637
|
+
var i = 0;
|
|
638
|
+
while (i < grid.depots.length){
|
|
639
|
+
var aDepot = grid.depots[i];
|
|
640
|
+
if (depot == aDepot) break;
|
|
641
|
+
if (aDepot && aDepot.tr && aDepot.tr.parentNode && aDepot.tr.rowIndex != null) {
|
|
642
|
+
iRow = aDepot.tr.sectionRowIndex
|
|
643
|
+
}
|
|
644
|
+
i++;
|
|
645
|
+
}
|
|
646
|
+
grid.createRowElements(iRow + 1, depot);
|
|
647
|
+
grid.updateRowData(depot);
|
|
648
|
+
depot.tick = tick
|
|
649
|
+
if (!force) {
|
|
650
|
+
changeIoStatus(depot,'background-change', depot.row);
|
|
651
|
+
setTimeout(function(){
|
|
652
|
+
changeIoStatus(depot,'ok', depot.row);
|
|
653
|
+
},3000);
|
|
654
|
+
}
|
|
655
|
+
} else if (depot) {
|
|
628
656
|
if (!sameValue(JSON.stringify(row),JSON.stringify(depot.row))) {
|
|
629
657
|
//grid.retrieveRowAndRefresh(depot);
|
|
630
658
|
if(depot.tr){
|
|
@@ -632,31 +660,20 @@ myOwn.tableGrid = function tableGrid(tableName, mainElement, opts){
|
|
|
632
660
|
}
|
|
633
661
|
}
|
|
634
662
|
depot.tick = tick
|
|
635
|
-
} else if (!depot && !thereIsANewRecord && !grid.vertical) {
|
|
636
|
-
var depot = grid.createDepotFromRow(row);
|
|
637
|
-
grid.depots.push(depot);
|
|
638
|
-
grid.sortDepotsToDisplay(grid.depots);
|
|
639
|
-
grid.createRowElements(grid.depots.findIndex((myDepot)=>myDepot===depot), depot);
|
|
640
|
-
grid.updateRowData(depot);
|
|
641
|
-
depot.tick = tick
|
|
642
|
-
changeIoStatus(depot,'background-change', depot.row);
|
|
643
|
-
setTimeout(function(){
|
|
644
|
-
changeIoStatus(depot,'ok', depot.row);
|
|
645
|
-
},3000);
|
|
646
663
|
}
|
|
647
664
|
})
|
|
648
665
|
if(!thereIsANewRecord){
|
|
649
666
|
var i = 0;
|
|
650
667
|
var depotsToDelete = grid.depots.filter(depot => depot.tick != tick);
|
|
651
668
|
var depot;
|
|
652
|
-
if (myOwn.config.config['grid-row-retain-moved-or-deleted']) {
|
|
669
|
+
if (myOwn.config.config['grid-row-retain-moved-or-deleted'] && !force) {
|
|
653
670
|
var depotsToRetain = grid.depots.filter(depot => depot.tick == tick);
|
|
654
671
|
for (depot of depotsToRetain) {
|
|
655
672
|
if (depot.tr && depot.tr.getAttribute('not-here')) depot.tr.removeAttribute('not-here')
|
|
656
673
|
}
|
|
657
674
|
}
|
|
658
675
|
while (depot = depotsToDelete.pop()) {
|
|
659
|
-
depot.manager.displayAsDeleted(depot, 'unknown');
|
|
676
|
+
depot.manager.displayAsDeleted(depot, force ? 'change-ff' : 'unknown');
|
|
660
677
|
}
|
|
661
678
|
}
|
|
662
679
|
})
|
|
@@ -1140,9 +1157,13 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
|
|
|
1140
1157
|
alt:'DETAIL',
|
|
1141
1158
|
title:detailTableDef.label||my.messages.details
|
|
1142
1159
|
}).create();
|
|
1143
|
-
var menuRef=
|
|
1160
|
+
var menuRef = detailTableDef.table ? {table:detailTableDef.table} : {w:detailTableDef.wScreen, autoproced:true};
|
|
1144
1161
|
var calculateFixedFields = function(){
|
|
1145
|
-
return detailTableDef.fields
|
|
1162
|
+
return detailTableDef.fields
|
|
1163
|
+
.filter(function(pair){
|
|
1164
|
+
return !pair.nullMeansAll || depot.row[pair.source] != null;
|
|
1165
|
+
})
|
|
1166
|
+
.map(function(pair){
|
|
1146
1167
|
var fieldCondition={fieldName: pair.target, value:'value' in pair ? pair.value : depot.row[pair.source]}
|
|
1147
1168
|
if(pair.range){
|
|
1148
1169
|
fieldCondition.range=pair.range;
|
|
@@ -1225,9 +1246,17 @@ myOwn.DetailColumnGrid.prototype.td = function td(depot, iColumn, tr){
|
|
|
1225
1246
|
g.dom.main.addEventListener('deletedRowOk', refresh);
|
|
1226
1247
|
g.dom.main.addEventListener('savedRowOk', refresh);
|
|
1227
1248
|
}
|
|
1228
|
-
detailControl.refreshAllRowsInGrid=function(){
|
|
1229
|
-
if(detailTableDef.refreshFromParent){
|
|
1230
|
-
|
|
1249
|
+
detailControl.refreshAllRowsInGrid=function(force){
|
|
1250
|
+
if(detailTableDef.refreshFromParent || force){
|
|
1251
|
+
if (force) {
|
|
1252
|
+
g.dom.main.style.opacity=0.5;
|
|
1253
|
+
fixedFields = calculateFixedFields()
|
|
1254
|
+
g.connector.fixedFields = fixedFields
|
|
1255
|
+
}
|
|
1256
|
+
setTimeout(async ()=>{
|
|
1257
|
+
await g.refreshAllRows(force);
|
|
1258
|
+
g.dom.main.style.opacity=1;
|
|
1259
|
+
},1)
|
|
1231
1260
|
}
|
|
1232
1261
|
}
|
|
1233
1262
|
return g;
|
|
@@ -2195,7 +2224,7 @@ myOwn.TableGrid.prototype.createRowInsertElements = function createRowInsertElem
|
|
|
2195
2224
|
}
|
|
2196
2225
|
var depotForInsert = grid.createDepotFromRow({$allow:{delete:true, update:true}}, 'new');
|
|
2197
2226
|
grid.connector.fixedFields.forEach(function(pair){
|
|
2198
|
-
if(!pair.range){
|
|
2227
|
+
if(!pair.range && grid.def.field[pair.fieldName].inTable !== false){
|
|
2199
2228
|
depotForInsert.row[pair.fieldName] = pair.value;
|
|
2200
2229
|
depotForInsert.rowPendingForUpdate[pair.fieldName] = pair.value;
|
|
2201
2230
|
}
|
|
@@ -2701,10 +2730,11 @@ myOwn.TableGrid.prototype.displayGrid = function displayGrid(){
|
|
|
2701
2730
|
|
|
2702
2731
|
myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mode){
|
|
2703
2732
|
var grid = this;
|
|
2733
|
+
var fast = mode == 'change-ff'
|
|
2704
2734
|
if (mode == 'unknown' && myOwn.config.config['grid-row-retain-moved-or-deleted']) {
|
|
2705
2735
|
depot.tr.setAttribute('not-here', 'yes');
|
|
2706
2736
|
} else {
|
|
2707
|
-
var position = Math.min(grid.depots.length,Math.max(0,depot.tr.sectionRowIndex));
|
|
2737
|
+
var position = depot.tr ? Math.min(grid.depots.length,Math.max(0,depot.tr.sectionRowIndex)) : 0;
|
|
2708
2738
|
if(grid.depots[position] !== depot){
|
|
2709
2739
|
position = grid.depots.indexOf(depot);
|
|
2710
2740
|
}
|
|
@@ -2729,12 +2759,14 @@ myOwn.TableGrid.prototype.displayAsDeleted = function displayAsDeleted(depot, mo
|
|
|
2729
2759
|
depots[j-1].colNumber = j;
|
|
2730
2760
|
}
|
|
2731
2761
|
}else{
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2762
|
+
if(depot.tr){
|
|
2763
|
+
depot.my.fade(depot.tr, {fast});
|
|
2764
|
+
for(var detailControl in depot.detailControls){
|
|
2765
|
+
if(depot.detailControls[detailControl].tr){
|
|
2766
|
+
depot.my.fade(depot.detailControls[detailControl].tr, {fast});
|
|
2767
|
+
}
|
|
2768
|
+
};
|
|
2769
|
+
}
|
|
2738
2770
|
}
|
|
2739
2771
|
}
|
|
2740
2772
|
grid.updateTotals(grid.depots.length?1:0, grid.depots.length);
|
package/for-client/my-things.js
CHANGED
|
@@ -252,11 +252,12 @@ myOwn.log = function log(severity, message){
|
|
|
252
252
|
};
|
|
253
253
|
|
|
254
254
|
myOwn.fade = function fade(element, options){
|
|
255
|
-
|
|
255
|
+
options=options||{};
|
|
256
|
+
if (!element.parentNode) return
|
|
257
|
+
if(element.tagName.toUpperCase()==='TR' && element.parentNode.replaceChild && !options.fast){
|
|
256
258
|
var parent=element.parentNode;
|
|
257
259
|
var dummyTr=document.createElement(element.tagName);
|
|
258
260
|
dummyTr.className=element.className;
|
|
259
|
-
options=options||{};
|
|
260
261
|
options.smooth=options.smooth||{};
|
|
261
262
|
var spans=options.smooth.spans;
|
|
262
263
|
var sourceRow;
|
package/lib/backend-plus.d.ts
CHANGED
|
@@ -230,7 +230,7 @@ export type EditableDbDefinition = {
|
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
export type FieldsForConnect = (string | {source:string, target:string})[]
|
|
233
|
-
export type FieldsForConnectDetailTable = (string | {source:string, target:string} | {value:any, target:string})[]
|
|
233
|
+
export type FieldsForConnectDetailTable = (string | {source:string, target:string, nullMeansAll?:boolean} | {value:any, target:string})[]
|
|
234
234
|
|
|
235
235
|
export type FkActions = 'no action'|'restrict'|'cascade'|'set null'|'set default';
|
|
236
236
|
export type ForeignKey = {
|
|
@@ -318,7 +318,7 @@ export type TableDefinition = EditableDbDefinition & {
|
|
|
318
318
|
specialValidator?:string
|
|
319
319
|
saveAfter?:boolean
|
|
320
320
|
selfRefresh?:boolean
|
|
321
|
-
filterColumns?:{column:string,
|
|
321
|
+
filterColumns?:{column:string, operator:string, value:any}[]
|
|
322
322
|
}
|
|
323
323
|
export type OtherTableDefs = TableDefinition['sql']['otherTableDefs']
|
|
324
324
|
export interface DetailTable { table?: string, fields: FieldsForConnectDetailTable, abr: string, label?: string, refreshParent?:boolean, refreshFromParent?:boolean, wScreen?:string, condition?:string }
|
|
@@ -418,6 +418,7 @@ export class AppBackend{
|
|
|
418
418
|
i18n:{
|
|
419
419
|
messages:Record<LangId,Record<string, string>>
|
|
420
420
|
}
|
|
421
|
+
shootDownBackend():Promise<void>
|
|
421
422
|
}
|
|
422
423
|
|
|
423
424
|
}
|
package/lib/backend-plus.js
CHANGED
|
@@ -158,6 +158,8 @@ AppBackend.prototype.configStaticConfig = function configStaticConfig(){
|
|
|
158
158
|
on-demand: false
|
|
159
159
|
server:
|
|
160
160
|
base-url: ''
|
|
161
|
+
bitacoraSchema: his
|
|
162
|
+
bitacoraTableName: bitacora
|
|
161
163
|
skins:
|
|
162
164
|
"":
|
|
163
165
|
local-path: for-client
|
|
@@ -614,6 +616,7 @@ AppBackend.prototype.start = function start(opts){
|
|
|
614
616
|
console.log('*','express server');
|
|
615
617
|
be.server.close(/** @param {Error} err */function(err){
|
|
616
618
|
if(err){
|
|
619
|
+
console.log('*', err)
|
|
617
620
|
reject(err);
|
|
618
621
|
}else{
|
|
619
622
|
resolve();
|
|
@@ -953,7 +956,7 @@ AppBackend.prototype.start = function start(opts){
|
|
|
953
956
|
function(req, username, password, done) {
|
|
954
957
|
var client;
|
|
955
958
|
if(!be.config.login["preserve-case"]){
|
|
956
|
-
username = username.toLowerCase();
|
|
959
|
+
username = username.toLowerCase().trim();
|
|
957
960
|
}
|
|
958
961
|
be.getDbClient(req).then(function(cli){
|
|
959
962
|
client = cli;
|
|
@@ -981,11 +984,26 @@ AppBackend.prototype.start = function start(opts){
|
|
|
981
984
|
if(be.config.login["double-dragon"]){
|
|
982
985
|
be.DoubleDragon.dbParams[username] = changing(be.config.db, {user:username, password});
|
|
983
986
|
}
|
|
984
|
-
|
|
987
|
+
return data.row;
|
|
985
988
|
}
|
|
986
989
|
}else{
|
|
987
990
|
done(null,false,{message:be.messages.unlogged.login.userOrPassFail});
|
|
988
991
|
}
|
|
992
|
+
}).then(async function(userInfo){
|
|
993
|
+
if (!userInfo) return;
|
|
994
|
+
if (!be.config.login.skipBitacora) {
|
|
995
|
+
var context = be.getContext(req);
|
|
996
|
+
var sessionInfo = await client.query(be.generateInsertSQL(be.config.server.bitacoraSchema, be.config.server.bitacoraTableName,{
|
|
997
|
+
procedure_name: '@login',
|
|
998
|
+
username,
|
|
999
|
+
machine_id: context.machineId,
|
|
1000
|
+
navigator: context.navigator,
|
|
1001
|
+
init_date: bestGlobals.datetime.now(),
|
|
1002
|
+
parameters: {}
|
|
1003
|
+
})).fetchUniqueValue();
|
|
1004
|
+
userInfo.bitacoraId = sessionInfo.value;
|
|
1005
|
+
}
|
|
1006
|
+
done(null, userInfo);
|
|
989
1007
|
}).then(function(){
|
|
990
1008
|
client.done();
|
|
991
1009
|
}).catch(function(err){
|
|
@@ -1095,7 +1113,7 @@ AppBackend.prototype.start = function start(opts){
|
|
|
1095
1113
|
console.log("Resolved modules from: " + process.cwd())
|
|
1096
1114
|
likeAr(resolved_modules_log).forEach((c,l)=>console.log(` ${c} ${l}`));
|
|
1097
1115
|
}
|
|
1098
|
-
|
|
1116
|
+
return be.sendMail({
|
|
1099
1117
|
to: be.config.mailer?.supervise?.to,
|
|
1100
1118
|
subject: `npm start ${be.config["client-setup"].title || packagejson.name} ok ✔️`,
|
|
1101
1119
|
text:`Inicio del servicio: ${new Date().toJSON()}
|
|
@@ -1193,7 +1211,7 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
|
|
|
1193
1211
|
from ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.config.login.table} limit 1`).fetchOneRowIfExists();
|
|
1194
1212
|
}catch(err){
|
|
1195
1213
|
var mensaje = `
|
|
1196
|
-
--------quizas falten los campos en la tabla usuarios:
|
|
1214
|
+
-------- quizas falten los campos en la tabla usuarios:
|
|
1197
1215
|
${be.config.login.forget.mailFields.map(name=>`
|
|
1198
1216
|
alter table ${be.config.login.schema?be.db.quoteIdent(be.config.login.schema)+'.':''}${be.config.login.table} add column ${name} text;`).join('')}
|
|
1199
1217
|
`;
|
|
@@ -1203,6 +1221,22 @@ AppBackend.prototype.checkDatabaseStructure = async function checkDatabaseStruct
|
|
|
1203
1221
|
}
|
|
1204
1222
|
}
|
|
1205
1223
|
}
|
|
1224
|
+
var bitacoraId = await client.query(`SELECT data_type
|
|
1225
|
+
FROM information_schema.columns
|
|
1226
|
+
WHERE /*table_schema = 'his' AND*/ table_name = 'bitacora' AND column_name = 'id'
|
|
1227
|
+
`).fetchOneRowIfExists();
|
|
1228
|
+
if (bitacoraId.row?.data_type != 'bigint') {
|
|
1229
|
+
var message = `
|
|
1230
|
+
------- hay que cambiar la bitacora de lugar (a his) y agrandar el id (a bigint)
|
|
1231
|
+
alter table ${be.config.db.schema}.bitacora set schema his;
|
|
1232
|
+
alter table ${be.config.db.schema}.tokens set schema his;
|
|
1233
|
+
alter table his.bitacora alter column id type bigint;
|
|
1234
|
+
grant usage on schema his to ${be.config.db.user};
|
|
1235
|
+
grant select, insert, update on his.bitacora to ${be.config.db.user};
|
|
1236
|
+
alter table his.bitacora alter column parameters_definition drop not null;
|
|
1237
|
+
`;
|
|
1238
|
+
throw new Error(message);
|
|
1239
|
+
}
|
|
1206
1240
|
};
|
|
1207
1241
|
|
|
1208
1242
|
AppBackend.prototype.postConfig = function postConfig(){
|
|
@@ -1238,6 +1272,36 @@ AppBackend.prototype.inTransactionProcedureContext = function inTransactionProce
|
|
|
1238
1272
|
});
|
|
1239
1273
|
}
|
|
1240
1274
|
|
|
1275
|
+
AppBackend.prototype.generateInsertSQL = function generateInsertSQL(schemaName, tableName, insertElement){
|
|
1276
|
+
var {db} = this;
|
|
1277
|
+
var cleanKeys = [];
|
|
1278
|
+
var cleanValues = [];
|
|
1279
|
+
for (var key in insertElement) {
|
|
1280
|
+
cleanKeys.push(db.quoteIdent(key));
|
|
1281
|
+
cleanValues.push(db.quoteNullable(insertElement[key]));
|
|
1282
|
+
}
|
|
1283
|
+
var sql = `INSERT INTO ${db.quoteIdent(schemaName)}.${db.quoteIdent(tableName)}
|
|
1284
|
+
(${cleanKeys.join(',')}) VALUES (${cleanValues.join(',')}) returning id`;
|
|
1285
|
+
return sql;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
AppBackend.prototype.updateUpdateSQL = function updateUpdateSQL(schemaName, tableName, updateElement, updateConditions){
|
|
1289
|
+
var {db} = this;
|
|
1290
|
+
var setPairs = [];
|
|
1291
|
+
for (var key in updateElement) {
|
|
1292
|
+
setPairs.push(db.quoteIdent(key) + " = " + db.quoteNullable(updateElement[key]));
|
|
1293
|
+
}
|
|
1294
|
+
var filterPairs = [];
|
|
1295
|
+
for (var key in updateConditions) {
|
|
1296
|
+
filterPairs.push(be.db.quoteIdent(key) + " = " + be.db.quoteLiteral(updateConditions[key]));
|
|
1297
|
+
};
|
|
1298
|
+
var sql = `UPDATE ${db.quoteIdent(schemaName)}.${db.quoteIdent(tableName)}
|
|
1299
|
+
SET ${setPairs.join(',')}
|
|
1300
|
+
WHERE ${filterPairs.join(' AND ')}`;
|
|
1301
|
+
return sql;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
|
|
1241
1305
|
/** @param {boolean} forUnlogged */
|
|
1242
1306
|
AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnlogged){
|
|
1243
1307
|
var be = this;
|
|
@@ -1295,7 +1359,8 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
|
|
|
1295
1359
|
* @param {import('express').NextFunction} next
|
|
1296
1360
|
*/
|
|
1297
1361
|
async function(req, res, next){
|
|
1298
|
-
const
|
|
1362
|
+
const BITACORA_SCHEMA = be.config.server.bitacoraSchema;
|
|
1363
|
+
const BITACORA_TABLENAME = be.config.server.bitacoraTableName;
|
|
1299
1364
|
var getDatetimeString = function getDatetimeString(){
|
|
1300
1365
|
return datetime.now().toPlainString()
|
|
1301
1366
|
}
|
|
@@ -1333,43 +1398,10 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
|
|
|
1333
1398
|
});
|
|
1334
1399
|
return params;
|
|
1335
1400
|
}
|
|
1336
|
-
var generateInsertSQL = function(insertElement){
|
|
1337
|
-
var cleanKeys = [];
|
|
1338
|
-
var cleanValues = [];
|
|
1339
|
-
for (var key in insertElement) {
|
|
1340
|
-
cleanKeys.push(be.db.quoteIdent(key));
|
|
1341
|
-
// if(typeof(insertElement[key]) !== 'string'){ //TODO: revisar si hace falta ahora que ponesmo quoteLiteral
|
|
1342
|
-
// insertElement[key] = insertElement[key].toString();
|
|
1343
|
-
// }
|
|
1344
|
-
cleanValues.push(be.db.quoteLiteral(insertElement[key] || "null"));
|
|
1345
|
-
}
|
|
1346
|
-
var sql = "INSERT INTO " + be.db.quoteIdent(BITACORA_TABLENAME) + " ("+cleanKeys.join(',')+") VALUES ("+ cleanValues.join(',')+") returning id";
|
|
1347
|
-
return sql;
|
|
1348
|
-
}
|
|
1349
|
-
var updateUpdateSQL = function(updateElement, tableName, updateConditions){
|
|
1350
|
-
var keyValues = [];
|
|
1351
|
-
for (var key in updateElement) {
|
|
1352
|
-
// if(typeof(updateElement[key]) !== 'string'){ //TODO: revisar si hace falta ahora que ponesmo quoteLiteral
|
|
1353
|
-
// updateElement[key] = updateElement[key].toString();
|
|
1354
|
-
// }
|
|
1355
|
-
keyValues.push(be.db.quoteIdent(key) + " = " + be.db.quoteLiteral(updateElement[key]));
|
|
1356
|
-
}
|
|
1357
|
-
var sql = "UPDATE " + be.db.quoteIdent(tableName) + " SET " + keyValues.join(',') + " WHERE ";
|
|
1358
|
-
var keyValues = [];
|
|
1359
|
-
for (var key in updateConditions) {
|
|
1360
|
-
// if(typeof(updateConditions[key]) !== 'string'){ //TODO: revisar si hace falta ahora que ponesmo quoteLiteral
|
|
1361
|
-
// updateConditions[key] = updateConditions[key].toString();
|
|
1362
|
-
// }
|
|
1363
|
-
keyValues.push(be.db.quoteIdent(key) + " = " + be.db.quoteLiteral(updateConditions[key]));
|
|
1364
|
-
};
|
|
1365
|
-
sql = sql + keyValues.join(' AND ');
|
|
1366
|
-
return sql;
|
|
1367
|
-
}
|
|
1368
1401
|
var processBitacora = async function(hasError, status){
|
|
1369
1402
|
var params = getParams();
|
|
1370
1403
|
var defInsertBitacoraElement = {
|
|
1371
1404
|
procedure_name : procedureDef.action,
|
|
1372
|
-
parameters_definition: JSON.stringify(procedureDef.parameters),
|
|
1373
1405
|
parameters: JSON.stringify(params),
|
|
1374
1406
|
username: context.username,
|
|
1375
1407
|
machine_id: context.machineId,
|
|
@@ -1387,18 +1419,18 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
|
|
|
1387
1419
|
if(lastBitacoraInsertedId){
|
|
1388
1420
|
await be.inTransaction(req, async function(client){
|
|
1389
1421
|
var updateConditions = { id: lastBitacoraInsertedId };
|
|
1390
|
-
await client.query(updateUpdateSQL(getFinalStatusBitacoraElement(),
|
|
1422
|
+
await client.query(be.updateUpdateSQL(BITACORA_SCHEMA, BITACORA_TABLENAME, getFinalStatusBitacoraElement(), updateConditions)).execute();
|
|
1391
1423
|
});
|
|
1392
1424
|
}else{
|
|
1393
1425
|
await be.inTransaction(req, async function(client){
|
|
1394
|
-
var result = await client.query(generateInsertSQL(defInsertBitacoraElement)).fetchUniqueRow();
|
|
1426
|
+
var result = await client.query(be.generateInsertSQL(BITACORA_SCHEMA, BITACORA_TABLENAME, defInsertBitacoraElement)).fetchUniqueRow();
|
|
1395
1427
|
lastBitacoraInsertedId = result.row.id;
|
|
1396
1428
|
});
|
|
1397
1429
|
}
|
|
1398
1430
|
}else if(hasError && procedureDef.bitacora.error){
|
|
1399
1431
|
await be.inTransaction(req,async function(client){
|
|
1400
1432
|
var insertElement = changing(defInsertBitacoraElement, getFinalStatusBitacoraElement());
|
|
1401
|
-
await client.query(generateInsertSQL(insertElement)).execute();
|
|
1433
|
+
await client.query(be.generateInsertSQL(BITACORA_SCHEMA, BITACORA_TABLENAME, insertElement)).execute();
|
|
1402
1434
|
});
|
|
1403
1435
|
}
|
|
1404
1436
|
//tengo configurada otra tabla para guardar el resultado de la bitacora y tengo la pk de esa tabla
|
|
@@ -1420,7 +1452,7 @@ AppBackend.prototype.addProcedureServices = function addProcedureServices(forUnl
|
|
|
1420
1452
|
targetTableUpdateFieldsCondition.forEach(function(field){
|
|
1421
1453
|
updateConditions[field] = params[field];
|
|
1422
1454
|
});
|
|
1423
|
-
await client.query(updateUpdateSQL(
|
|
1455
|
+
await client.query(be.updateUpdateSQL(BITACORA_SCHEMA, procedureDef.bitacora.targetTable, updateElement, updateConditions)).execute();
|
|
1424
1456
|
})
|
|
1425
1457
|
}
|
|
1426
1458
|
}
|
|
@@ -2566,8 +2598,13 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2566
2598
|
var schema=db.quoteIdent(be.config.db.schema);
|
|
2567
2599
|
linesCreate.push("set role to "+owner+";");
|
|
2568
2600
|
linesCreate.push("drop schema if exists "+schema+' cascade;');
|
|
2601
|
+
if (be.config.install.dump["drop-his"]) {
|
|
2602
|
+
linesCreate.push("drop schema if exists his cascade;");
|
|
2603
|
+
}
|
|
2569
2604
|
linesCreate.push("create schema "+schema+';');
|
|
2570
2605
|
linesCreate.push("grant usage on schema "+schema+' to '+user+';');
|
|
2606
|
+
linesCreate.push("create schema if not exists his;");
|
|
2607
|
+
linesCreate.push("grant usage on schema his to "+user+';');
|
|
2571
2608
|
if(be.config.install.dump["admin-can-create-tables"]){
|
|
2572
2609
|
linesCreate.push("grant create on schema "+schema+' to '+user+';');
|
|
2573
2610
|
}
|
package/lib/procedures-table.js
CHANGED
|
@@ -189,6 +189,9 @@ ProcedureTables = [
|
|
|
189
189
|
var updateTarget = {}
|
|
190
190
|
for(var name in parameters.newRow){
|
|
191
191
|
var defField=mainDefTable.field[name];
|
|
192
|
+
if (!defField) {
|
|
193
|
+
throw new Error("field "+name+" does not exist in "+mainDefTable.name);
|
|
194
|
+
}
|
|
192
195
|
if(!defField.allow[action] && (!opts || !opts.forImport) && (
|
|
193
196
|
!defField.isPk ||
|
|
194
197
|
parameters.primaryKeyValues[defField.isPk-1]!=parameters.newRow[name]
|
package/lib/table-def-adapt.js
CHANGED
|
@@ -317,7 +317,7 @@ function tableDefAdapt(tableDef, context){
|
|
|
317
317
|
resultFieldDef.referencesFields=fkDef.fields;
|
|
318
318
|
resultFieldDef.skipReferenceLookup=fkDef.skipReferenceLookup || fkTableDef.skipReferenceLookup;
|
|
319
319
|
}catch(err){
|
|
320
|
-
console.log('ERROR',fkDef.fields,'in',resultTableDef.field);
|
|
320
|
+
console.log('ERROR',fkDef.fields,'in',resultTableDef.field.name);
|
|
321
321
|
err.context=(err.context||'')+'referencing '+fkDef.fields[lastPos].source+' in '+resultTableDef.name+' to '+fkDef.references+' \n ';
|
|
322
322
|
throw err;
|
|
323
323
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
module.exports = function(context){
|
|
4
|
-
const BITACORA_TABLENAME = context.be.config.server.bitacoraTableName
|
|
4
|
+
const BITACORA_TABLENAME = context.be.config.server.bitacoraTableName;
|
|
5
|
+
const BITACORA_SCHEMA = context.be.config.server.bitacoraSchema;
|
|
5
6
|
return context.be.tableDefAdapt({
|
|
6
7
|
name:'bitacora',
|
|
7
8
|
title:'Bitacora',
|
|
8
9
|
tableName: BITACORA_TABLENAME,
|
|
10
|
+
schema: BITACORA_SCHEMA,
|
|
9
11
|
editable:context.forDump,
|
|
10
12
|
fields:[
|
|
11
|
-
{name:'id' , typeName:'
|
|
13
|
+
{name:'id' , typeName:'bigint' , nullable:false, sequence:{name: 'secuencia_bitacora', firstValue: 1}},
|
|
12
14
|
{name:'procedure_name' , typeName:'text' , nullable:false },
|
|
13
|
-
{name:'parameters_definition' , typeName:'text' , nullable:false },
|
|
14
15
|
{name:'parameters' , typeName:'text' , nullable:false },
|
|
15
16
|
{name:'username' , typeName:'text' , nullable:false },
|
|
16
17
|
{name:'machine_id' , typeName:'text' , nullable:false },
|
|
@@ -21,6 +22,7 @@ module.exports = function(context){
|
|
|
21
22
|
{name:'end_status' , typeName:'text' },
|
|
22
23
|
],
|
|
23
24
|
primaryKey:['id'],
|
|
25
|
+
sql:{skipEnance:true},
|
|
24
26
|
sortColumns:[{column:'id', order:-1}]
|
|
25
27
|
}, context);
|
|
26
28
|
}
|
|
@@ -4,6 +4,7 @@ module.exports = function(context){
|
|
|
4
4
|
var $1_is_num=`$1 ~ '^\\s*(\\d+(\\.\\d*)?|\\.\\d+)\\s*$'`
|
|
5
5
|
return context.be.tableDefAdapt({
|
|
6
6
|
name:'summary',
|
|
7
|
+
schema:'his',
|
|
7
8
|
editable:context.forDump,
|
|
8
9
|
fields:[
|
|
9
10
|
{name:'table_name' , typeName:'text' , visible:false},
|
|
@@ -32,6 +33,7 @@ module.exports = function(context){
|
|
|
32
33
|
],
|
|
33
34
|
primaryKey:['table_name', 'name'],
|
|
34
35
|
// hiddenColunns:['typeName', 'nullable', 'label', 'title', 'description'],
|
|
36
|
+
sql:{skipEnance:true},
|
|
35
37
|
sortColumns:[{column:'ordinal_position', order:1}]
|
|
36
38
|
}, context);
|
|
37
39
|
}
|
|
@@ -5,6 +5,7 @@ module.exports = function(context){
|
|
|
5
5
|
return context.be.tableDefAdapt({
|
|
6
6
|
name:'tokens',
|
|
7
7
|
elementName:'token',
|
|
8
|
+
schema:'his',
|
|
8
9
|
editable:admin,
|
|
9
10
|
fields:[
|
|
10
11
|
{name:'token' , typeName:'text' , nullable:false },
|
|
@@ -21,7 +22,8 @@ module.exports = function(context){
|
|
|
21
22
|
],
|
|
22
23
|
sql:{
|
|
23
24
|
isTable: true,
|
|
24
|
-
from: `(select * from tokens order by date desc)
|
|
25
|
+
from: `(select * from tokens order by date desc)`,
|
|
26
|
+
skipEnance:true,
|
|
25
27
|
},
|
|
26
28
|
}, context);
|
|
27
29
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-plus",
|
|
3
|
-
"description": "Backend for
|
|
4
|
-
"version": "
|
|
3
|
+
"description": "Backend for the anti Pareto rule",
|
|
4
|
+
"version": "2.0.0-beta.10",
|
|
5
5
|
"author": "Codenautas <codenautas@googlegroups.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "codenautas/backend-plus",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"fs-extra": "^11.1.1",
|
|
47
47
|
"js-to-html": "^1.3.2",
|
|
48
48
|
"js-yaml": "^4.1.0",
|
|
49
|
-
"json4all": "^1.
|
|
49
|
+
"json4all": "^1.3.0-beta.1",
|
|
50
50
|
"lazy-some": "^0.1.0",
|
|
51
51
|
"like-ar": "^0.3.9",
|
|
52
52
|
"login-plus": "^1.7.1",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"mini-tools": "^1.12.1",
|
|
55
55
|
"moment": "^2.29.4",
|
|
56
56
|
"multiparty": "^4.2.3",
|
|
57
|
-
"nodemailer": "^6.9.
|
|
57
|
+
"nodemailer": "^6.9.4",
|
|
58
58
|
"numeral": "^2.0.6",
|
|
59
59
|
"pg-promise-strict": "^1.3.3",
|
|
60
60
|
"pikaday": "^1.8.2",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@types/big.js": "^6.
|
|
76
|
+
"@types/big.js": "^6.2.0",
|
|
77
77
|
"@types/expect.js": "~0.3.29",
|
|
78
78
|
"@types/express": "^4.17.17",
|
|
79
79
|
"@types/express-useragent": "^1.0.2",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"@types/js-yaml": "^4.0.5",
|
|
82
82
|
"@types/mocha": "^10.0.1",
|
|
83
83
|
"@types/multiparty": "~0.0.33",
|
|
84
|
-
"@types/node": "^20.
|
|
85
|
-
"@types/nodemailer": "^6.4.
|
|
84
|
+
"@types/node": "^20.5.1",
|
|
85
|
+
"@types/nodemailer": "^6.4.9",
|
|
86
86
|
"@types/numeral": "~2.0.2",
|
|
87
87
|
"@types/session-file-store": "^1.2.2",
|
|
88
88
|
"@types/stack-trace": "~0.0.30",
|
|
@@ -98,11 +98,11 @@
|
|
|
98
98
|
"kill-9": "~0.4.3",
|
|
99
99
|
"mocha": "^10.2.0",
|
|
100
100
|
"nyc": "^15.1.0",
|
|
101
|
-
"puppeteer": "^
|
|
102
|
-
"sinon": "^15.
|
|
101
|
+
"puppeteer": "^21.1.0",
|
|
102
|
+
"sinon": "^15.2.0",
|
|
103
103
|
"supertest": "^6.3.3",
|
|
104
|
-
"types.d.ts": "~0.6.
|
|
105
|
-
"typescript": "^5.1.
|
|
104
|
+
"types.d.ts": "~0.6.18",
|
|
105
|
+
"typescript": "^5.1.6",
|
|
106
106
|
"why-is-node-running": "^2.2.2"
|
|
107
107
|
},
|
|
108
108
|
"engines": {
|