backend-plus 1.18.2 → 1.18.3
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/lib/backend-plus.js +146 -139
- package/package.json +4 -4
package/lib/backend-plus.js
CHANGED
|
@@ -2756,157 +2756,164 @@ AppBackend.prototype.dumpDbSchemaPartial = async function dumpDbSchemaPartial(pa
|
|
|
2756
2756
|
}
|
|
2757
2757
|
var enancePart= 'do $SQL_ENANCE$\n begin\n' + enanceLines.join('\n')+'\n' + 'end\n$SQL_ENANCE$;';
|
|
2758
2758
|
var someNotFound=false;
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
buscarEn=[
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2759
|
+
try {
|
|
2760
|
+
var allTableData = await fs.readFile('install/local-data-dump.psql','utf-8');
|
|
2761
|
+
} catch(err) {
|
|
2762
|
+
if (err.code != 'ENOENT') throw err;
|
|
2763
|
+
}
|
|
2764
|
+
if (allTableData) {
|
|
2765
|
+
dataText = [allTableData]
|
|
2766
|
+
} else {
|
|
2767
|
+
await Promise.all(likeAr(partialTableStructures).map(function(tableDef, tableName, _, i){
|
|
2768
|
+
if(tableDef?.sql?.isTable === false) return;
|
|
2769
|
+
// TODO: buscar
|
|
2770
|
+
var buscarEn=[Path.join('local-install',tableName+'.tab')].concat(
|
|
2771
|
+
be.appStack.map(function(stackNode){
|
|
2772
|
+
return Path.join(stackNode.path,'../install',tableName+'.tab').replace(regexpDistReplacer,'$1$2');
|
|
2773
|
+
})
|
|
2774
|
+
);
|
|
2775
|
+
if(be.config.install['table-data-dir'] instanceof Array){
|
|
2776
|
+
buscarEn=be.config.install['table-data-dir'].map(path=>Path.join(path,tableName+'.tab')).concat(buscarEn);
|
|
2777
|
+
}else if(be.config.install['table-data-dir']){
|
|
2778
|
+
buscarEn=[].concat(Path.join(be.config.install['table-data-dir'],tableName+'.tab')).concat(buscarEn);
|
|
2778
2779
|
}
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
var rows;
|
|
2786
|
-
var tableDef=partialTableStructures[tableName](contextForDump);
|
|
2787
|
-
var filterField=function(fieldName){
|
|
2788
|
-
if(fieldName==null){
|
|
2789
|
-
throw new Error('ERROR empty name or extra column in '+tableName+'.tab')
|
|
2790
|
-
}
|
|
2791
|
-
var defField=tableDef.field[fieldName];
|
|
2792
|
-
if(!defField && !fieldName.startsWith('!')){
|
|
2793
|
-
throw new Error('field '+fieldName+' does no exists in .tab for '+tableName+' in '+path);
|
|
2780
|
+
if(!i) console.log('buscar en', buscarEn)
|
|
2781
|
+
return locatePath(buscarEn).then(function(theTableFileName){
|
|
2782
|
+
if(theTableFileName==undefined){
|
|
2783
|
+
var err = new Error('not found');
|
|
2784
|
+
err.code='ENOENT'
|
|
2785
|
+
throw err;
|
|
2794
2786
|
}
|
|
2795
|
-
return
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2787
|
+
return fs.readFile(theTableFileName, {encoding:'UTF8'}).then(function(content){
|
|
2788
|
+
return {path:Path.relative(process.cwd(),theTableFileName),content};
|
|
2789
|
+
});
|
|
2790
|
+
}).then(function({path,content}){
|
|
2791
|
+
dataText.push("\n-- table data: "+path);
|
|
2792
|
+
var lines;
|
|
2793
|
+
var rows;
|
|
2794
|
+
var tableDef=partialTableStructures[tableName](contextForDump);
|
|
2795
|
+
var filterField=function(fieldName){
|
|
2796
|
+
if(fieldName==null){
|
|
2797
|
+
throw new Error('ERROR empty name or extra column in '+tableName+'.tab')
|
|
2802
2798
|
}
|
|
2803
|
-
|
|
2799
|
+
var defField=tableDef.field[fieldName];
|
|
2800
|
+
if(!defField && !fieldName.startsWith('!')){
|
|
2801
|
+
throw new Error('field '+fieldName+' does no exists in .tab for '+tableName+' in '+path);
|
|
2802
|
+
}
|
|
2803
|
+
return !fieldName.startsWith('!') && defField.inTable!==false && !defField.inJoin && (!defField.clientSide || defField.serverSide) && !defField.generatedAs;
|
|
2804
2804
|
}
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
}).join(', ')+");\n";
|
|
2813
|
-
dataText.push(dataString);
|
|
2814
|
-
});
|
|
2815
|
-
rows=lines;
|
|
2816
|
-
}else{
|
|
2817
|
-
var lines=content.split(/\r?\n/)
|
|
2818
|
-
.filter(line => !(/^[-| ]*$/.test(line)) )
|
|
2819
|
-
.map(line => line.split(/(?<!(?:^|[^\\])(?:\\\\)*\\)\|/).map(item => item.trimRight().replace(/\\(.)/g,(_,l)=>(l=='t'?'\t':l=='r'?'\r':l=='n'?'\n':l=='s'?' ':l))) )
|
|
2820
|
-
.filter(line => line.length>1 || line.length==1 && line[0].trim() );
|
|
2821
|
-
if(lines.length>1){
|
|
2822
|
-
if(lines[0][0].startsWith('\ufeff')){
|
|
2823
|
-
lines[0][0]=lines[0][0].replace('\ufeff','')
|
|
2805
|
+
if(/[-[]/.test(content[0])){
|
|
2806
|
+
var filterField2=function(_value,fieldName){
|
|
2807
|
+
var fieldDef = tableDef.field[fieldName];
|
|
2808
|
+
if(!fieldDef){
|
|
2809
|
+
console.log('lack of field',fieldName,'in table',tableName,'filtering fields')
|
|
2810
|
+
}
|
|
2811
|
+
return (!fieldDef.sequence || fieldDef.sequence.name) && filterField(fieldName);
|
|
2824
2812
|
}
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
var dataString="COPY "+db.quoteIdent(tableName)+" ("+
|
|
2828
|
-
lines[0].filter(filterField).map(db.quoteIdent).join(', ')+
|
|
2829
|
-
') FROM stdin;\n'+
|
|
2830
|
-
rows.map(function(line){
|
|
2831
|
-
return line.filter(function(_,i){ return filterField(lines[0][i]);}).map(function(value){
|
|
2832
|
-
return value===''?'\\N':value.replace(/\\/g,'\\\\').replace(/\t/g,'\\t').replace(/\n/g,'\\n').replace(/\r/g,'\\r');
|
|
2833
|
-
}).join('\t')+'\n';
|
|
2834
|
-
}).join('')+'\\.\n';
|
|
2835
|
-
}else{
|
|
2813
|
+
lines = jsYaml.load(content);
|
|
2814
|
+
lines.forEach(function(line){
|
|
2836
2815
|
var dataString="insert into "+db.quoteIdent(tableName)+" ("+
|
|
2837
|
-
|
|
2838
|
-
') values
|
|
2839
|
-
|
|
2840
|
-
return
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2816
|
+
likeAr(line).filter(filterField2).keys().map(db.quoteIdent).join(', ')+
|
|
2817
|
+
') values ('+
|
|
2818
|
+
likeAr(line).filter(filterField2).map(function(value){
|
|
2819
|
+
return db.quoteNullable(value);
|
|
2820
|
+
}).join(', ')+");\n";
|
|
2821
|
+
dataText.push(dataString);
|
|
2822
|
+
});
|
|
2823
|
+
rows=lines;
|
|
2824
|
+
}else{
|
|
2825
|
+
var lines=content.split(/\r?\n/)
|
|
2826
|
+
.filter(line => !(/^[-| ]*$/.test(line)) )
|
|
2827
|
+
.map(line => line.split(/(?<!(?:^|[^\\])(?:\\\\)*\\)\|/).map(item => item.trimRight().replace(/\\(.)/g,(_,l)=>(l=='t'?'\t':l=='r'?'\r':l=='n'?'\n':l=='s'?' ':l))) )
|
|
2828
|
+
.filter(line => line.length>1 || line.length==1 && line[0].trim() );
|
|
2829
|
+
if(lines.length>1){
|
|
2830
|
+
if(lines[0][0].startsWith('\ufeff')){
|
|
2831
|
+
lines[0][0]=lines[0][0].replace('\ufeff','')
|
|
2832
|
+
}
|
|
2833
|
+
rows=lines.slice(1);
|
|
2834
|
+
if(tablesWithStrictSequence[tableName]){
|
|
2835
|
+
var dataString="COPY "+db.quoteIdent(tableName)+" ("+
|
|
2836
|
+
lines[0].filter(filterField).map(db.quoteIdent).join(', ')+
|
|
2837
|
+
') FROM stdin;\n'+
|
|
2838
|
+
rows.map(function(line){
|
|
2839
|
+
return line.filter(function(_,i){ return filterField(lines[0][i]);}).map(function(value){
|
|
2840
|
+
return value===''?'\\N':value.replace(/\\/g,'\\\\').replace(/\t/g,'\\t').replace(/\n/g,'\\n').replace(/\r/g,'\\r');
|
|
2841
|
+
}).join('\t')+'\n';
|
|
2842
|
+
}).join('')+'\\.\n';
|
|
2843
|
+
}else{
|
|
2844
|
+
var dataString="insert into "+db.quoteIdent(tableName)+" ("+
|
|
2845
|
+
lines[0].filter(filterField).map(db.quoteIdent).join(', ')+
|
|
2846
|
+
') values\n'+
|
|
2847
|
+
rows.map(function(line){
|
|
2848
|
+
return "("+line.filter(function(_,i){ return filterField(lines[0][i]);}).map(function(value){
|
|
2849
|
+
return value===''?'null':db.quoteNullable(value);
|
|
2850
|
+
}).join(', ')+")";
|
|
2851
|
+
}).join(',\n')+';\n';
|
|
2852
|
+
}
|
|
2853
|
+
dataText.push(dataString);
|
|
2844
2854
|
}
|
|
2845
|
-
|
|
2855
|
+
// tablesWithStrictSequence[tableName]
|
|
2846
2856
|
}
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2857
|
+
}).catch(function(err){
|
|
2858
|
+
if(err.code=='ENOENT'){
|
|
2859
|
+
if(!be.config.install.dump["skip-content"]){
|
|
2860
|
+
console.log('skipping content for','install/'+tableName+'.tab');
|
|
2861
|
+
someNotFound=true;
|
|
2862
|
+
}
|
|
2863
|
+
}else{
|
|
2864
|
+
throw err;
|
|
2854
2865
|
}
|
|
2855
|
-
}
|
|
2856
|
-
|
|
2857
|
-
}
|
|
2858
|
-
});
|
|
2859
|
-
}).array()).then(function(){
|
|
2866
|
+
});
|
|
2867
|
+
}).array())
|
|
2860
2868
|
if(someNotFound){
|
|
2861
2869
|
console.log('silence "skipping content" messages in "local-config.yaml".install.dump.skip-content=true');
|
|
2862
2870
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
})
|
|
2878
|
-
)
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
});
|
|
2871
|
+
}
|
|
2872
|
+
let texts = await Promise.all(
|
|
2873
|
+
['prepare.sql','pre-adapt.sql','adapt.sql']
|
|
2874
|
+
.concat(be.config.install.dump.scripts['prepare'])
|
|
2875
|
+
.concat(be.config.install.dump.scripts['post-adapt'])
|
|
2876
|
+
.map(function(fileName){
|
|
2877
|
+
return fs.readFile(be.rootPath+'/install/'+fileName, {encoding:'UTF8'}).catch(function(err){
|
|
2878
|
+
if(err.code!='ENOENT'){
|
|
2879
|
+
throw err;
|
|
2880
|
+
}
|
|
2881
|
+
console.log("err:",err);
|
|
2882
|
+
return '-- no '+fileName+'\n';
|
|
2883
|
+
}).then(function(content){
|
|
2884
|
+
return '-- '+fileName+'\n'+content;
|
|
2885
|
+
});
|
|
2886
|
+
})
|
|
2887
|
+
);
|
|
2888
|
+
var prepareList=(be.config.install.dump.scripts['prepare']||[]);
|
|
2889
|
+
var mainSql=(
|
|
2890
|
+
(complete? linesCreate.join('\n'): '')+
|
|
2891
|
+
(complete||opts.forDump? searchPathline.join('\n'): '')+
|
|
2892
|
+
(complete? '\n\n--prepare.sql\n'+ texts[0]+'\n\n' :'' )+
|
|
2893
|
+
(complete? texts.slice(3,3+prepareList.length).join('\n\n')+'\n\n' : '' )+
|
|
2894
|
+
'\n-- functions\n' + functionLines.join('\n')+
|
|
2895
|
+
'\n-- lines \n' + lines.join('\n')+
|
|
2896
|
+
(complete? ('\n\n-- pre-ADAPTs\n'+texts[1]+'\n\n') : '' )+
|
|
2897
|
+
(complete? ('\n\n-- DATA\n'+ dataText.join('\n')) : '' )+
|
|
2898
|
+
(complete? ('\n\n-- ADAPTs\n'+ texts[2]+'\n\n') : '' )+
|
|
2899
|
+
'\n-- conss\n' + consLines.join('\n')+
|
|
2900
|
+
'\n-- FKs\n' + fkLines.join('\n')+
|
|
2901
|
+
'\n-- index\n' + indexLines.join('\n')+
|
|
2902
|
+
'\n-- policies\n' + policyLines.join('\n')+
|
|
2903
|
+
(complete? texts.slice(3+prepareList.length).join('\n\n')+'\n\n' : '' )+
|
|
2904
|
+
(complete? (be.config.install.dump.enances==='inline'?enancePart:'') :'')
|
|
2905
|
+
).replace(/\uFEFF/g /*inner BOM replacing*/,'\n\n').replace(
|
|
2906
|
+
new RegExp(escapeRegExp(db.quoteIdent(be.config.install.dump.db["owner4special-scripts"])),'g'),
|
|
2907
|
+
db.quoteIdent(be.config.install.dump.db.owner)
|
|
2908
|
+
).replace(
|
|
2909
|
+
new RegExp(escapeRegExp(db.quoteIdent(be.config.install.dump.db["user4special-scripts"])),'g'),
|
|
2910
|
+
db.quoteIdent(be.config.db.user)
|
|
2911
|
+
);
|
|
2912
|
+
if(be.config.install.dump.db["apply-generic-user-replaces"]){
|
|
2913
|
+
mainSql=mainSql.replace(/((\bto\s|=)\s*"?)\w+(_user\b)/ig, "$1"+user);
|
|
2914
|
+
mainSql=mainSql.replace(/((\bto\s|=)\s*"?)\w+(_owner\b)/ig, "$1"+owner);
|
|
2915
|
+
}
|
|
2916
|
+
return {mainSql,enancePart};
|
|
2910
2917
|
}
|
|
2911
2918
|
|
|
2912
2919
|
AppBackend.prototype.getDbFunctions = async function (){
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-plus",
|
|
3
3
|
"description": "Backend for typed controls",
|
|
4
|
-
"version": "1.18.
|
|
4
|
+
"version": "1.18.3",
|
|
5
5
|
"author": "Codenautas <codenautas@googlegroups.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "codenautas/backend-plus",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"json4all": "^1.2.1",
|
|
50
50
|
"lazy-some": "^0.1.0",
|
|
51
51
|
"like-ar": "^0.3.9",
|
|
52
|
-
"login-plus": "^1.7.
|
|
52
|
+
"login-plus": "^1.7.1",
|
|
53
53
|
"memorystore": "^1.6.7",
|
|
54
54
|
"mini-tools": "^1.12.0",
|
|
55
55
|
"moment": "^2.29.4",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"pug": "^3.0.2",
|
|
62
62
|
"read-yaml-promise": "^1.0.2",
|
|
63
63
|
"regexplicit": "^0.1.3",
|
|
64
|
-
"require-bro": "^0.3.
|
|
64
|
+
"require-bro": "^0.3.1",
|
|
65
65
|
"self-explain": "^0.10.22",
|
|
66
66
|
"serve-content": "^0.3.18",
|
|
67
67
|
"session-file-store": "^1.5.0",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"why-is-node-running": "^2.2.2"
|
|
107
107
|
},
|
|
108
108
|
"engines": {
|
|
109
|
-
"node": ">=
|
|
109
|
+
"node": ">= 18"
|
|
110
110
|
},
|
|
111
111
|
"scripts": {
|
|
112
112
|
"test": "(npm run prepublish || echo \"continue w/error\") && mocha --reporter spec --single-run --bail test/test-*.js",
|