backend-plus 2.2.5 → 2.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.
@@ -1,359 +1,359 @@
1
- "use strict";
2
-
3
- var likeAr = require('like-ar');
4
- var changing = require('best-globals').changing;
5
- var coalesce = require('best-globals').coalesce;
6
- var bestGlobals = require('best-globals');
7
- var TypeStore = require('type-store');
8
-
9
- const escapeRegExp = bestGlobals.escapeRegExp;
10
-
11
- function completeEditablesProperties(def,defaultValue,otherAllow){
12
- otherAllow = otherAllow || {};
13
- ['insert','delete','update','select'].forEach(function(actionName){
14
- if(!(actionName in def.allow)){
15
- def.allow[actionName] = (
16
- actionName!=='select' && 'editable' in def ?
17
- !!def.editable :
18
- (actionName in otherAllow?otherAllow[actionName]:defaultValue)
19
- );
20
- }
21
- });
22
- def.allow.filter = coalesce(def.allow.filter,true);
23
- def.allow.import = coalesce(def.allow.import,def.allow.export && def.allow.update,otherAllow.import,false);
24
- }
25
-
26
- function tableDefAdapt(tableDef, context){
27
- var be = this;
28
- var fieldDomain = be.fieldDomain || {};
29
- if(false && !be.fieldDomain){
30
- throw new Error('lack of fieldDomain in backend. postConfig must call super.postConfig');
31
- }
32
- var resultTableDef = changing({
33
- title: tableDef.name,
34
- field: {},
35
- allow: {select: true, orientation: false, "vertical-edit": tableDefAdapt["vertical-edit"], export:true},
36
- actionNamesList: [],
37
- foreignKeys: [],
38
- softForeignKeys: [],
39
- filterColumns: [],
40
- detailTables: [],
41
- sql:{
42
- fields:{},
43
- policies:{
44
- all:{using:false, check:false},
45
- select:{using:false, check:false},
46
- insert:{using:false, check:false},
47
- update:{using:false, check:false},
48
- delete:{using:false, check:false},
49
- }
50
- },
51
- layout:{
52
- styleColumns:[],
53
- vertical:false,
54
- errorList:false,
55
- extraRows: 0,
56
- },
57
- constraints:[],
58
- registerImports:{
59
- inTable:null,
60
- fieldNames:{
61
- tableName:'table_name',
62
- fieldName:'field',
63
- fieldIndex:'field_index',
64
- originalFileName:null,
65
- serverPath:null,
66
- lastUpload:null,
67
- }
68
- },
69
- offline:{
70
- mode:false,
71
- details:null
72
- },
73
- refrescable: false
74
- },tableDef);
75
- var JSONFieldForOtherFields = tableDef.fields.filter(function findDefaultForOthers(field) {
76
- return field.defaultForOtherFields === true;
77
- });
78
- if(JSONFieldForOtherFields.length === 0){
79
- resultTableDef.JSONFieldForOtherFields = false;
80
- }else if(JSONFieldForOtherFields.length === 1){
81
- resultTableDef.JSONFieldForOtherFields = JSONFieldForOtherFields[0];
82
- }else{
83
- throw new Error("multiple defaultForOtherFields in field definition in "+tableDef.name);
84
- }
85
- completeEditablesProperties(resultTableDef, false);
86
- var prefixRegExp;
87
- if(resultTableDef.prefix){
88
- prefixRegExp=new RegExp('^'+escapeRegExp(resultTableDef.prefix)+'_');
89
- }else{
90
- prefixRegExp=/^/;
91
- }
92
- resultTableDef.nameFields = [];
93
- if(resultTableDef.offline.mode){
94
- if(!resultTableDef.fields.find(fieldDef=>fieldDef.name=='$lock')){
95
- resultTableDef.fields.unshift({ name:"$lock", title: '🔑', typeName: 'text', clientSide:'$lock' });
96
- }
97
- if(resultTableDef.offline.mode && !resultTableDef.offline.details){
98
- throw new Error("lack of offline.details in table "+tableDef.name);
99
- }
100
- }
101
- resultTableDef.fields = resultTableDef.fields.map(function(fieldDef){
102
- var resultFieldDef = changing(changing({
103
- visible: true,
104
- allow:{},
105
- defaultForOtherFields: false,
106
- extraRow: resultTableDef.layout.extraRows,
107
- title: fieldDef.name.replace(prefixRegExp,'').replace(/_/g, ' '),
108
- },fieldDomain[fieldDef.name]||{}), fieldDef);
109
- if(!resultFieldDef.visible && resultFieldDef.clientSide){
110
- console.log("fieldDef: ", fieldDef);
111
- throw Error("FieldDef Error: Invisible field can't be set as clientSide")
112
- }
113
- TypeStore.completeTypeInfo(resultFieldDef);
114
- resultFieldDef.label = resultFieldDef.label||resultFieldDef.title;
115
- completeEditablesProperties(resultFieldDef, !!resultTableDef.editableFieldDef, resultTableDef.allow);
116
- if(resultFieldDef.nullable == null && resultFieldDef.sequence && ! resultFieldDef.sequence.name){
117
- resultFieldDef.nullable = true;
118
- resultFieldDef.editable = false;
119
- resultFieldDef.allow.insert = false;
120
- resultFieldDef.allow.update = false;
121
- }else if(resultTableDef.allow.insert){
122
- resultFieldDef.allow.insert=true;
123
- }
124
- if(fieldDef.typeName==='enum'){
125
- resultFieldDef.options = resultFieldDef.options.map(function(option){
126
- if(typeof option !== 'object'){
127
- return {option:option, label:option};
128
- }else{
129
- return option;
130
- }
131
- });
132
- }
133
- return resultFieldDef;
134
- }).filter(function(fieldDef){
135
- return fieldDef.allow.select || context && context.forDump;
136
- }).map(function(fieldDef){
137
- resultTableDef.field[fieldDef.name]=fieldDef;
138
- if(fieldDef.isName){
139
- resultTableDef.nameFields.push(fieldDef.name);
140
- }
141
- return fieldDef;
142
- });
143
- (resultTableDef.primaryKey||[]).forEach(function(fieldName, i){
144
- if(!(fieldName in resultTableDef.field)){
145
- console.error('Lack of field '+JSON.stringify(fieldName)+' in '+JSON.stringify(resultTableDef.name))
146
- }
147
- resultTableDef.field[fieldName].isPk=i+1;
148
- });
149
- resultTableDef.foreignKeys.map(function(fk){
150
- fk.fields.forEach(function(pair, i, pairs){
151
- if(typeof pair === "string"){
152
- pairs[i] = {source: pair, target: pair};
153
- }
154
- });
155
- });
156
- resultTableDef.softForeignKeys.map(function(sfk){
157
- sfk.fields.forEach(function(pair, i, pairs){
158
- if(typeof pair === "string"){
159
- pairs[i] = {source: pair, target: pair};
160
- }
161
- });
162
- });
163
- resultTableDef.detailTables.map(function(detail){
164
- detail.label=detail.label||detail.table;
165
- detail.fields.forEach(function(pair, i, pairs){
166
- if(typeof pair === "string"){
167
- pairs[i] = {source: pair, target: pair};
168
- }
169
- });
170
- });
171
- if(!resultTableDef.sortColumns && resultTableDef?.sql?.orderBy){
172
- resultTableDef.sortColumns = resultTableDef.sql.orderBy.map(column=>({column}))
173
- }
174
- if(resultTableDef.sortColumns){
175
- resultTableDef.sortColumns.map(function(sortColumn){
176
- sortColumn.order = sortColumn.order || 1;
177
- });
178
- }
179
- resultTableDef.tableName = resultTableDef.tableName || resultTableDef.name;
180
- resultTableDef.alias = resultTableDef.alias || resultTableDef.tableName;
181
- resultTableDef.sql.tableName = resultTableDef.sql.tableName || resultTableDef.tableName;
182
- if(resultTableDef.functionDef){
183
- }
184
- resultTableDef.sql.select = resultTableDef.sql.select || resultTableDef.fields.map(function(fieldDef){
185
- var resultName = be.db.quoteIdent(fieldDef.name)
186
- var exprAs='';
187
- if(/__/.test(fieldDef.name) && !be.config.db.allow_double_lodash_fields){
188
- return null;
189
- }else{
190
- if(fieldDef.clientSide && !fieldDef.inTable && !fieldDef.serverSide){
191
- exprAs="null::text as ";
192
- }else if((resultTableDef.sql.fields[fieldDef.name]||{}).expr){
193
- if(!('inTable' in resultTableDef.field[fieldDef.name])){
194
- console.error('DEPRECATED!!!',fieldDef.name,'in table',tableDef.name,'has sql.fields.expr. Must has "inTable" prop also.');
195
- }
196
- exprAs=resultTableDef.sql.fields[fieldDef.name].expr+' as ';
197
- }else{
198
- resultName=be.db.quoteIdent(fieldDef.inJoin ?? resultTableDef.alias)+'.'+resultName;
199
- }
200
- return exprAs+resultName;
201
- }
202
- }).filter(function(expr){ return expr });
203
- var otherColumns = [];
204
- var pol = resultTableDef.sql.policies;
205
- if(resultTableDef.sql.policies.enabled==null){
206
- var pol = resultTableDef.sql.policies;
207
- pol.enabled = (
208
- pol.all.using || pol.select.using || pol.insert.using || pol.update.using || pol.delete.using ||
209
- pol.all.check || pol.select.check || pol.insert.check || pol.update.check || pol.delete.check ||
210
- false
211
- ) && true;
212
- }
213
- if(pol && pol.enabled){
214
- resultTableDef.sql.select.push(`${be.db.quoteIdent(resultTableDef.alias)}."$allow.update"`);
215
- resultTableDef.sql.select.push(`${be.db.quoteIdent(resultTableDef.alias)}."$allow.delete"`);
216
- }
217
- resultTableDef.sql.isTable = coalesce(resultTableDef.sql.isTable, !resultTableDef.sql.from);
218
- resultTableDef.sql.originalFrom = resultTableDef.sql.from;
219
- resultTableDef.sql.from = (resultTableDef.sql.from || (
220
- be.db.quoteIdent(resultTableDef.tableName)+(resultTableDef.functionDef?
221
- '('+resultTableDef.functionDef.parameters.map(function(x,i){return '$'+(i+1);}).join(',')+')'
222
- :'')
223
- ));
224
- if(resultTableDef.sql.from.endsWith(' x')){
225
- console.log('hay que quitar el " as x"')
226
- throw Error('tableDefAdapt from ends with x "'+resultTableDef.tableName+'"');
227
- }
228
- resultTableDef.sql.fromWoAs = resultTableDef.sql.from;
229
- if(be.db.quoteIdent(resultTableDef.alias)!==resultTableDef.sql.from){
230
- resultTableDef.sql.from += ' as ' + be.db.quoteIdent(resultTableDef.alias);
231
- }
232
- if(pol.enabled){
233
- var otherColumns = [];
234
- var pol = resultTableDef.sql.policies;
235
- if(pol && pol.enabled){
236
- otherColumns.push(`(${(pol.enabled && (pol.update.using || pol.all.using) || 'true' )}) is true as "$allow.update"`);
237
- otherColumns.push(`(${(pol.enabled && (pol.delete.using || pol.all.using) || 'true' )}) is true as "$allow.delete"`);
238
- }
239
- resultTableDef.sql.from = `( select *, ${otherColumns} from ${resultTableDef.sql.from}) as ${be.db.quoteIdent(resultTableDef.alias)}`
240
- }
241
- if(resultTableDef.sql.join){
242
- resultTableDef.sql.from += '\n'+resultTableDef.sql.join;
243
- }
244
- if(resultTableDef.sql.logicalDeletes){
245
- resultTableDef.sql.where=(resultTableDef.sql.where?'('+resultTableDef.sql.where+') and ':'')+
246
- be.db.quoteIdent(resultTableDef.sql.logicalDeletes.fieldName)+
247
- " is distinct from "+be.db.quoteNullable(resultTableDef.sql.logicalDeletes.valueToDelete);
248
- }
249
- if(context && !context.plainStructure){
250
- resultTableDef.foreignKeys.concat(resultTableDef.softForeignKeys).forEach(function(fkDef){
251
- if(fkDef.definingSubclass){
252
- return;
253
- }
254
- var fkTableDef = be.tableStructures[fkDef.references];
255
- if(!fkTableDef){
256
- throw new Error('tableDefAdapt: table "'+fkDef.references+'" must be declared before "'+resultTableDef.tableName+'"');
257
- }
258
- fkTableDef=fkTableDef(changing(context,{plainStructure: true}));
259
- var lastSourceField=null;
260
- fkDef.alias = fkDef.alias || fkDef.label || fkTableDef.alias;
261
- fkDef.displayFields = fkDef.displayAllFields?
262
- (fkTableDef.fields.filter(fd=>fd.visible && !fd.clientSide && !resultTableDef.field[fd.name] && !fd.inJoin && !fkTableDef.sql.fields[fd.name]).map(fd=>fd.name)): //EVALUAR SI ESTÁ BIEN COMENTARLO
263
- fkDef.displayFields || fkTableDef.nameFields;
264
- resultTableDef.sql.from += '\n left join ' + fkTableDef.sql.fromWoAs + ' as ' + be.db.quoteIdent(fkDef.alias) + ' on ' +
265
- fkDef.fields.map(function(pair){
266
- lastSourceField = pair.source;
267
- return be.db.quoteIdent(resultTableDef.alias)+'.'+be.db.quoteIdent(pair.source)
268
- + ' = ' + be.db.quoteIdent(fkDef.alias)+'.'+be.db.quoteIdent(pair.target);
269
- }).join(' AND ');
270
- var iLastSourceField = fkDef.displayAfterFieldName === true ? resultTableDef.fields.length-1 : resultTableDef.fields.findIndex(function(fieldDef){ return fieldDef.name == (fkDef.displayAfterFieldName || lastSourceField) });
271
- fkDef.displayFields.forEach(function(fieldName,iField){
272
- var fieldNameAdded=fkDef.alias+'__'+fieldName;
273
- var fieldDefAdded=changing(fkTableDef.field[fieldName], {
274
- name:fieldNameAdded,
275
- editable:false,
276
- allow:{update:false, insert:false},
277
- references:fkDef.references,
278
- referencesField:lastSourceField,
279
- inTable:false,
280
- referencedName:fieldName,
281
- referencedAlias:fkDef.alias,
282
- nullable:true,
283
- });
284
- var lastSourceFieldDef=resultTableDef.field[lastSourceField];
285
- if(lastSourceFieldDef == null){
286
- console.log("not found lastSourceField:", lastSourceFieldDef, "in", resultTableDef.name, "fk:", fkDef)
287
- }
288
- if(lastSourceFieldDef.orderForInsertOnly){
289
- fieldDefAdded.orderForInsertOnly=lastSourceFieldDef.orderForInsertOnly+' '+(iField+1);
290
- }
291
- if(fieldNameAdded in resultTableDef.field){
292
- fieldDefAdded = changing(resultTableDef.field[fieldNameAdded], fieldDefAdded)
293
- }else{
294
- iLastSourceField++;
295
- resultTableDef.fields.splice(iLastSourceField,0,fieldDefAdded);
296
- }
297
- resultTableDef.field[fieldNameAdded]=fieldDefAdded;
298
- // resultTableDef.field[fieldNameAdded]=changing(fieldDefAdded,resultTableDef.field[fieldNameAdded]||{});
299
- resultTableDef.sql.select.push(
300
- be.db.quoteIdent(fkDef.alias)+'.'+be.db.quoteIdent(fieldName)+' as '+
301
- be.db.quoteIdent(fkDef.alias+'__'+fieldName)
302
- );
303
- });
304
- if(fkDef.fields.length===1 || "busqueda en fk compuesta experimental"){
305
- var lastPos=fkDef.fields.length-1;
306
- if(!(fkDef.fields[lastPos].target in fkTableDef.field)){
307
- throw new Error('ERROR in tableDef '+JSON.stringify(resultTableDef.name)+' in FKs, field '+JSON.stringify(fkDef.fields[lastPos].target)+' not present in table '+JSON.stringify(resultTableDef.name));
308
- }
309
- if(fkTableDef.field[fkDef.fields[lastPos].target].isPk){
310
- try{
311
- var resultFieldDef=resultTableDef.field[fkDef.fields[lastPos].source];
312
- if(!resultFieldDef){
313
- throw new Error('ERROR in tableDef '+JSON.stringify(resultTableDef.name)+' fk.fields.source '+JSON.stringify(fkDef.fields[lastPos].source)+' not found')
314
- }
315
- resultFieldDef.references=fkDef.references;
316
- resultFieldDef.referencesAlias=fkDef.alias;
317
- resultFieldDef.referencesFields=fkDef.fields;
318
- resultFieldDef.skipReferenceLookup=fkDef.skipReferenceLookup || fkTableDef.skipReferenceLookup;
319
- }catch(err){
320
- console.log('ERROR',fkDef.fields,'in',resultTableDef.field.name);
321
- err.context=(err.context||'')+'referencing '+fkDef.fields[lastPos].source+' in '+resultTableDef.name+' to '+fkDef.references+' \n ';
322
- throw err;
323
- }
324
- }
325
- }
326
- });
327
- }else if(!context){
328
- if(resultTableDef.foreignKeys.length){
329
- console.log("ATENCIÓN. Conviene pasar context como segundo parámetro a tableDefAdapt para que tome las FK en tabla "+resultTableDef.tableName)
330
- }
331
- }
332
- resultTableDef.sql.postCreateSqls = resultTableDef.sql.postCreateSqls || '';
333
- resultTableDef.adapted = (resultTableDef.adapted||0)+1;
334
- return resultTableDef;
335
- }
336
-
337
- tableDefAdapt["vertical-edit"] = true;
338
-
339
- tableDefAdapt.forInsertOnly = function forInsertOnly(tableDef){
340
- if(tableDef.forInsertOnlyMode){
341
- tableDef.field = likeAr(tableDef.field).filter(function(fieldDef){
342
- return fieldDef.orderForInsertOnly;
343
- });
344
- tableDef.fields = likeAr(tableDef.field).array();
345
- tableDef.fields.sort(bestGlobals.compareForOrder([{column:'orderForInsertOnly'}]))
346
- tableDef.sql.select = tableDef.fields.map(function(fieldDef){
347
- var typer=TypeStore.typerFrom(fieldDef);
348
- return (fieldDef.inTable===false || fieldDef.inJoin) && tableDef.sql.fields[fieldDef.name] ?"null::"+typer.typeDbPg+" as "+be.db.quoteIdent(fieldDef.name):(
349
- fieldDef.referencedName?(
350
- be.db.quoteIdent(fieldDef.referencedAlias)+"."+be.db.quoteIdent(fieldDef.referencedName)+" as "+be.db.quoteIdent(fieldDef.name)
351
- ):(
352
- be.db.quoteIdent(tableDef.alias)+"."+be.db.quoteIdent(fieldDef.name)
353
- )
354
- );
355
- });
356
- }
357
- }
358
-
1
+ "use strict";
2
+
3
+ var likeAr = require('like-ar');
4
+ var changing = require('best-globals').changing;
5
+ var coalesce = require('best-globals').coalesce;
6
+ var bestGlobals = require('best-globals');
7
+ var TypeStore = require('type-store');
8
+
9
+ const escapeRegExp = bestGlobals.escapeRegExp;
10
+
11
+ function completeEditablesProperties(def,defaultValue,otherAllow){
12
+ otherAllow = otherAllow || {};
13
+ ['insert','delete','update','select'].forEach(function(actionName){
14
+ if(!(actionName in def.allow)){
15
+ def.allow[actionName] = (
16
+ actionName!=='select' && 'editable' in def ?
17
+ !!def.editable :
18
+ (actionName in otherAllow?otherAllow[actionName]:defaultValue)
19
+ );
20
+ }
21
+ });
22
+ def.allow.filter = coalesce(def.allow.filter,true);
23
+ def.allow.import = coalesce(def.allow.import,def.allow.export && def.allow.update,otherAllow.import,false);
24
+ }
25
+
26
+ function tableDefAdapt(tableDef, context){
27
+ var be = this;
28
+ var fieldDomain = be.fieldDomain || {};
29
+ if(false && !be.fieldDomain){
30
+ throw new Error('lack of fieldDomain in backend. postConfig must call super.postConfig');
31
+ }
32
+ var resultTableDef = changing({
33
+ title: tableDef.name,
34
+ field: {},
35
+ allow: {select: true, orientation: false, "vertical-edit": tableDefAdapt["vertical-edit"], export:true},
36
+ actionNamesList: [],
37
+ foreignKeys: [],
38
+ softForeignKeys: [],
39
+ filterColumns: [],
40
+ detailTables: [],
41
+ sql:{
42
+ fields:{},
43
+ policies:{
44
+ all:{using:false, check:false},
45
+ select:{using:false, check:false},
46
+ insert:{using:false, check:false},
47
+ update:{using:false, check:false},
48
+ delete:{using:false, check:false},
49
+ }
50
+ },
51
+ layout:{
52
+ styleColumns:[],
53
+ vertical:false,
54
+ errorList:false,
55
+ extraRows: 0,
56
+ },
57
+ constraints:[],
58
+ registerImports:{
59
+ inTable:null,
60
+ fieldNames:{
61
+ tableName:'table_name',
62
+ fieldName:'field',
63
+ fieldIndex:'field_index',
64
+ originalFileName:null,
65
+ serverPath:null,
66
+ lastUpload:null,
67
+ }
68
+ },
69
+ offline:{
70
+ mode:false,
71
+ details:null
72
+ },
73
+ refrescable: false
74
+ },tableDef);
75
+ var JSONFieldForOtherFields = tableDef.fields.filter(function findDefaultForOthers(field) {
76
+ return field.defaultForOtherFields === true;
77
+ });
78
+ if(JSONFieldForOtherFields.length === 0){
79
+ resultTableDef.JSONFieldForOtherFields = false;
80
+ }else if(JSONFieldForOtherFields.length === 1){
81
+ resultTableDef.JSONFieldForOtherFields = JSONFieldForOtherFields[0];
82
+ }else{
83
+ throw new Error("multiple defaultForOtherFields in field definition in "+tableDef.name);
84
+ }
85
+ completeEditablesProperties(resultTableDef, false);
86
+ var prefixRegExp;
87
+ if(resultTableDef.prefix){
88
+ prefixRegExp=new RegExp('^'+escapeRegExp(resultTableDef.prefix)+'_');
89
+ }else{
90
+ prefixRegExp=/^/;
91
+ }
92
+ resultTableDef.nameFields = [];
93
+ if(resultTableDef.offline.mode){
94
+ if(!resultTableDef.fields.find(fieldDef=>fieldDef.name=='$lock')){
95
+ resultTableDef.fields.unshift({ name:"$lock", title: '🔑', typeName: 'text', clientSide:'$lock' });
96
+ }
97
+ if(resultTableDef.offline.mode && !resultTableDef.offline.details){
98
+ throw new Error("lack of offline.details in table "+tableDef.name);
99
+ }
100
+ }
101
+ resultTableDef.fields = resultTableDef.fields.map(function(fieldDef){
102
+ var resultFieldDef = changing(changing({
103
+ visible: true,
104
+ allow:{},
105
+ defaultForOtherFields: false,
106
+ extraRow: resultTableDef.layout.extraRows,
107
+ title: fieldDef.name.replace(prefixRegExp,'').replace(/_/g, ' '),
108
+ },fieldDomain[fieldDef.name]||{}), fieldDef);
109
+ if(!resultFieldDef.visible && resultFieldDef.clientSide){
110
+ console.log("fieldDef: ", fieldDef);
111
+ throw Error("FieldDef Error: Invisible field can't be set as clientSide")
112
+ }
113
+ TypeStore.completeTypeInfo(resultFieldDef);
114
+ resultFieldDef.label = resultFieldDef.label||resultFieldDef.title;
115
+ completeEditablesProperties(resultFieldDef, !!resultTableDef.editableFieldDef, resultTableDef.allow);
116
+ if(resultFieldDef.nullable == null && resultFieldDef.sequence && ! resultFieldDef.sequence.name){
117
+ resultFieldDef.nullable = true;
118
+ resultFieldDef.editable = false;
119
+ resultFieldDef.allow.insert = false;
120
+ resultFieldDef.allow.update = false;
121
+ }else if(resultTableDef.allow.insert){
122
+ resultFieldDef.allow.insert=true;
123
+ }
124
+ if(fieldDef.typeName==='enum'){
125
+ resultFieldDef.options = resultFieldDef.options.map(function(option){
126
+ if(typeof option !== 'object'){
127
+ return {option:option, label:option};
128
+ }else{
129
+ return option;
130
+ }
131
+ });
132
+ }
133
+ return resultFieldDef;
134
+ }).filter(function(fieldDef){
135
+ return fieldDef.allow.select || context && context.forDump;
136
+ }).map(function(fieldDef){
137
+ resultTableDef.field[fieldDef.name]=fieldDef;
138
+ if(fieldDef.isName){
139
+ resultTableDef.nameFields.push(fieldDef.name);
140
+ }
141
+ return fieldDef;
142
+ });
143
+ (resultTableDef.primaryKey||[]).forEach(function(fieldName, i){
144
+ if(!(fieldName in resultTableDef.field)){
145
+ console.error('Lack of field '+JSON.stringify(fieldName)+' in '+JSON.stringify(resultTableDef.name))
146
+ }
147
+ resultTableDef.field[fieldName].isPk=i+1;
148
+ });
149
+ resultTableDef.foreignKeys.map(function(fk){
150
+ fk.fields.forEach(function(pair, i, pairs){
151
+ if(typeof pair === "string"){
152
+ pairs[i] = {source: pair, target: pair};
153
+ }
154
+ });
155
+ });
156
+ resultTableDef.softForeignKeys.map(function(sfk){
157
+ sfk.fields.forEach(function(pair, i, pairs){
158
+ if(typeof pair === "string"){
159
+ pairs[i] = {source: pair, target: pair};
160
+ }
161
+ });
162
+ });
163
+ resultTableDef.detailTables.map(function(detail){
164
+ detail.label=detail.label||detail.table;
165
+ detail.fields.forEach(function(pair, i, pairs){
166
+ if(typeof pair === "string"){
167
+ pairs[i] = {source: pair, target: pair};
168
+ }
169
+ });
170
+ });
171
+ if(!resultTableDef.sortColumns && resultTableDef?.sql?.orderBy){
172
+ resultTableDef.sortColumns = resultTableDef.sql.orderBy.map(column=>({column}))
173
+ }
174
+ if(resultTableDef.sortColumns){
175
+ resultTableDef.sortColumns.map(function(sortColumn){
176
+ sortColumn.order = sortColumn.order || 1;
177
+ });
178
+ }
179
+ resultTableDef.tableName = resultTableDef.tableName || resultTableDef.name;
180
+ resultTableDef.alias = resultTableDef.alias || resultTableDef.tableName;
181
+ resultTableDef.sql.tableName = resultTableDef.sql.tableName || resultTableDef.tableName;
182
+ if(resultTableDef.functionDef){
183
+ }
184
+ resultTableDef.sql.select = resultTableDef.sql.select || resultTableDef.fields.map(function(fieldDef){
185
+ var resultName = be.db.quoteIdent(fieldDef.name)
186
+ var exprAs='';
187
+ if(/__/.test(fieldDef.name) && !be.config.db.allow_double_lodash_fields){
188
+ return null;
189
+ }else{
190
+ if(fieldDef.clientSide && !fieldDef.inTable && !fieldDef.serverSide){
191
+ exprAs="null::text as ";
192
+ }else if((resultTableDef.sql.fields[fieldDef.name]||{}).expr){
193
+ if(!('inTable' in resultTableDef.field[fieldDef.name])){
194
+ console.error('DEPRECATED!!!',fieldDef.name,'in table',tableDef.name,'has sql.fields.expr. Must has "inTable" prop also.');
195
+ }
196
+ exprAs=resultTableDef.sql.fields[fieldDef.name].expr+' as ';
197
+ }else{
198
+ resultName=be.db.quoteIdent(fieldDef.inJoin ?? resultTableDef.alias)+'.'+resultName;
199
+ }
200
+ return exprAs+resultName;
201
+ }
202
+ }).filter(function(expr){ return expr });
203
+ var otherColumns = [];
204
+ var pol = resultTableDef.sql.policies;
205
+ if(resultTableDef.sql.policies.enabled==null){
206
+ var pol = resultTableDef.sql.policies;
207
+ pol.enabled = (
208
+ pol.all.using || pol.select.using || pol.insert.using || pol.update.using || pol.delete.using ||
209
+ pol.all.check || pol.select.check || pol.insert.check || pol.update.check || pol.delete.check ||
210
+ false
211
+ ) && true;
212
+ }
213
+ if(pol && pol.enabled){
214
+ resultTableDef.sql.select.push(`${be.db.quoteIdent(resultTableDef.alias)}."$allow.update"`);
215
+ resultTableDef.sql.select.push(`${be.db.quoteIdent(resultTableDef.alias)}."$allow.delete"`);
216
+ }
217
+ resultTableDef.sql.isTable = coalesce(resultTableDef.sql.isTable, !resultTableDef.sql.from);
218
+ resultTableDef.sql.originalFrom = resultTableDef.sql.from;
219
+ resultTableDef.sql.from = (resultTableDef.sql.from || (
220
+ be.db.quoteIdent(resultTableDef.tableName)+(resultTableDef.functionDef?
221
+ '('+resultTableDef.functionDef.parameters.map(function(x,i){return '$'+(i+1);}).join(',')+')'
222
+ :'')
223
+ ));
224
+ if(resultTableDef.sql.from.endsWith(' x')){
225
+ console.log('hay que quitar el " as x"')
226
+ throw Error('tableDefAdapt from ends with x "'+resultTableDef.tableName+'"');
227
+ }
228
+ resultTableDef.sql.fromWoAs = resultTableDef.sql.from;
229
+ if(be.db.quoteIdent(resultTableDef.alias)!==resultTableDef.sql.from){
230
+ resultTableDef.sql.from += ' as ' + be.db.quoteIdent(resultTableDef.alias);
231
+ }
232
+ if(pol.enabled){
233
+ var otherColumns = [];
234
+ var pol = resultTableDef.sql.policies;
235
+ if(pol && pol.enabled){
236
+ otherColumns.push(`(${(pol.enabled && (pol.update.using || pol.all.using) || 'true' )}) is true as "$allow.update"`);
237
+ otherColumns.push(`(${(pol.enabled && (pol.delete.using || pol.all.using) || 'true' )}) is true as "$allow.delete"`);
238
+ }
239
+ resultTableDef.sql.from = `( select *, ${otherColumns} from ${resultTableDef.sql.from}) as ${be.db.quoteIdent(resultTableDef.alias)}`
240
+ }
241
+ if(resultTableDef.sql.join){
242
+ resultTableDef.sql.from += '\n'+resultTableDef.sql.join;
243
+ }
244
+ if(resultTableDef.sql.logicalDeletes){
245
+ resultTableDef.sql.where=(resultTableDef.sql.where?'('+resultTableDef.sql.where+') and ':'')+
246
+ be.db.quoteIdent(resultTableDef.sql.logicalDeletes.fieldName)+
247
+ " is distinct from "+be.db.quoteNullable(resultTableDef.sql.logicalDeletes.valueToDelete);
248
+ }
249
+ if(context && !context.plainStructure){
250
+ resultTableDef.foreignKeys.concat(resultTableDef.softForeignKeys).forEach(function(fkDef){
251
+ if(fkDef.definingSubclass){
252
+ return;
253
+ }
254
+ var fkTableDef = be.tableStructures[fkDef.references];
255
+ if(!fkTableDef){
256
+ throw new Error('tableDefAdapt: table "'+fkDef.references+'" must be declared before "'+resultTableDef.tableName+'"');
257
+ }
258
+ fkTableDef=fkTableDef(changing(context,{plainStructure: true}));
259
+ var lastSourceField=null;
260
+ fkDef.alias = fkDef.alias || fkDef.label || fkTableDef.alias;
261
+ fkDef.displayFields = fkDef.displayAllFields?
262
+ (fkTableDef.fields.filter(fd=>fd.visible && !fd.clientSide && !resultTableDef.field[fd.name] && !fd.inJoin && !fkTableDef.sql.fields[fd.name]).map(fd=>fd.name)): //EVALUAR SI ESTÁ BIEN COMENTARLO
263
+ fkDef.displayFields || fkTableDef.nameFields;
264
+ resultTableDef.sql.from += '\n left join ' + fkTableDef.sql.fromWoAs + ' as ' + be.db.quoteIdent(fkDef.alias) + ' on ' +
265
+ fkDef.fields.map(function(pair){
266
+ lastSourceField = pair.source;
267
+ return be.db.quoteIdent(resultTableDef.alias)+'.'+be.db.quoteIdent(pair.source)
268
+ + ' = ' + be.db.quoteIdent(fkDef.alias)+'.'+be.db.quoteIdent(pair.target);
269
+ }).join(' AND ');
270
+ var iLastSourceField = fkDef.displayAfterFieldName === true ? resultTableDef.fields.length-1 : resultTableDef.fields.findIndex(function(fieldDef){ return fieldDef.name == (fkDef.displayAfterFieldName || lastSourceField) });
271
+ fkDef.displayFields.forEach(function(fieldName,iField){
272
+ var fieldNameAdded=fkDef.alias+'__'+fieldName;
273
+ var fieldDefAdded=changing(fkTableDef.field[fieldName], {
274
+ name:fieldNameAdded,
275
+ editable:false,
276
+ allow:{update:false, insert:false},
277
+ references:fkDef.references,
278
+ referencesField:lastSourceField,
279
+ inTable:false,
280
+ referencedName:fieldName,
281
+ referencedAlias:fkDef.alias,
282
+ nullable:true,
283
+ });
284
+ var lastSourceFieldDef=resultTableDef.field[lastSourceField];
285
+ if(lastSourceFieldDef == null){
286
+ console.log("not found lastSourceField:", lastSourceFieldDef, "in", resultTableDef.name, "fk:", fkDef)
287
+ }
288
+ if(lastSourceFieldDef.orderForInsertOnly){
289
+ fieldDefAdded.orderForInsertOnly=lastSourceFieldDef.orderForInsertOnly+' '+(iField+1);
290
+ }
291
+ if(fieldNameAdded in resultTableDef.field){
292
+ fieldDefAdded = changing(resultTableDef.field[fieldNameAdded], fieldDefAdded)
293
+ }else{
294
+ iLastSourceField++;
295
+ resultTableDef.fields.splice(iLastSourceField,0,fieldDefAdded);
296
+ }
297
+ resultTableDef.field[fieldNameAdded]=fieldDefAdded;
298
+ // resultTableDef.field[fieldNameAdded]=changing(fieldDefAdded,resultTableDef.field[fieldNameAdded]||{});
299
+ resultTableDef.sql.select.push(
300
+ be.db.quoteIdent(fkDef.alias)+'.'+be.db.quoteIdent(fieldName)+' as '+
301
+ be.db.quoteIdent(fkDef.alias+'__'+fieldName)
302
+ );
303
+ });
304
+ if(fkDef.fields.length===1 || "busqueda en fk compuesta experimental"){
305
+ var lastPos=fkDef.fields.length-1;
306
+ if(!(fkDef.fields[lastPos].target in fkTableDef.field)){
307
+ throw new Error('ERROR in tableDef '+JSON.stringify(resultTableDef.name)+' in FKs, field '+JSON.stringify(fkDef.fields[lastPos].target)+' not present in table '+JSON.stringify(resultTableDef.name));
308
+ }
309
+ if(fkTableDef.field[fkDef.fields[lastPos].target].isPk){
310
+ try{
311
+ var resultFieldDef=resultTableDef.field[fkDef.fields[lastPos].source];
312
+ if(!resultFieldDef){
313
+ throw new Error('ERROR in tableDef '+JSON.stringify(resultTableDef.name)+' fk.fields.source '+JSON.stringify(fkDef.fields[lastPos].source)+' not found')
314
+ }
315
+ resultFieldDef.references=fkDef.references;
316
+ resultFieldDef.referencesAlias=fkDef.alias;
317
+ resultFieldDef.referencesFields=fkDef.fields;
318
+ resultFieldDef.skipReferenceLookup=fkDef.skipReferenceLookup || fkTableDef.skipReferenceLookup;
319
+ }catch(err){
320
+ console.log('ERROR',fkDef.fields,'in',resultTableDef.field.name);
321
+ err.context=(err.context||'')+'referencing '+fkDef.fields[lastPos].source+' in '+resultTableDef.name+' to '+fkDef.references+' \n ';
322
+ throw err;
323
+ }
324
+ }
325
+ }
326
+ });
327
+ }else if(!context){
328
+ if(resultTableDef.foreignKeys.length){
329
+ console.log("ATENCIÓN. Conviene pasar context como segundo parámetro a tableDefAdapt para que tome las FK en tabla "+resultTableDef.tableName)
330
+ }
331
+ }
332
+ resultTableDef.sql.postCreateSqls = resultTableDef.sql.postCreateSqls || '';
333
+ resultTableDef.adapted = (resultTableDef.adapted||0)+1;
334
+ return resultTableDef;
335
+ }
336
+
337
+ tableDefAdapt["vertical-edit"] = true;
338
+
339
+ tableDefAdapt.forInsertOnly = function forInsertOnly(tableDef){
340
+ if(tableDef.forInsertOnlyMode){
341
+ tableDef.field = likeAr(tableDef.field).filter(function(fieldDef){
342
+ return fieldDef.orderForInsertOnly;
343
+ });
344
+ tableDef.fields = likeAr(tableDef.field).array();
345
+ tableDef.fields.sort(bestGlobals.compareForOrder([{column:'orderForInsertOnly'}]))
346
+ tableDef.sql.select = tableDef.fields.map(function(fieldDef){
347
+ var typer=TypeStore.typerFrom(fieldDef);
348
+ return (fieldDef.inTable===false || fieldDef.inJoin) && tableDef.sql.fields[fieldDef.name] ?"null::"+typer.typeDbPg+" as "+be.db.quoteIdent(fieldDef.name):(
349
+ fieldDef.referencedName?(
350
+ be.db.quoteIdent(fieldDef.referencedAlias)+"."+be.db.quoteIdent(fieldDef.referencedName)+" as "+be.db.quoteIdent(fieldDef.name)
351
+ ):(
352
+ be.db.quoteIdent(tableDef.alias)+"."+be.db.quoteIdent(fieldDef.name)
353
+ )
354
+ );
355
+ });
356
+ }
357
+ }
358
+
359
359
  module.exports = tableDefAdapt;