@payloadcms/db-sqlite 3.0.0-canary.518fabe → 3.0.0-canary.5624723
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/dist/connect.d.ts.map +1 -1
- package/dist/connect.js.map +1 -1
- package/dist/countDistinct.d.ts.map +1 -1
- package/dist/countDistinct.js +2 -3
- package/dist/countDistinct.js.map +1 -1
- package/dist/defaultSnapshot.d.ts.map +1 -1
- package/dist/defaultSnapshot.js +2 -1
- package/dist/defaultSnapshot.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +23 -4
- package/dist/init.js.map +1 -1
- package/dist/schema/build.d.ts +4 -1
- package/dist/schema/build.d.ts.map +1 -1
- package/dist/schema/build.js +32 -7
- package/dist/schema/build.js.map +1 -1
- package/dist/schema/createIndex.d.ts +2 -3
- package/dist/schema/createIndex.d.ts.map +1 -1
- package/dist/schema/createIndex.js +3 -3
- package/dist/schema/createIndex.js.map +1 -1
- package/dist/schema/traverseFields.d.ts +3 -1
- package/dist/schema/traverseFields.d.ts.map +1 -1
- package/dist/schema/traverseFields.js +286 -260
- package/dist/schema/traverseFields.js.map +1 -1
- package/dist/types.d.ts +29 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/license.md +22 -0
- package/package.json +16 -9
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { createTableName, hasLocalesTable, validateExistingBlockIsIdentical } from '@payloadcms/drizzle';
|
|
1
|
+
import { buildIndexName, createTableName, hasLocalesTable, validateExistingBlockIsIdentical } from '@payloadcms/drizzle';
|
|
2
2
|
import { relations } from 'drizzle-orm';
|
|
3
3
|
import { foreignKey, index, integer, numeric, SQLiteIntegerBuilder, SQLiteNumericBuilder, SQLiteTextBuilder, text } from 'drizzle-orm/sqlite-core';
|
|
4
4
|
import { InvalidConfiguration } from 'payload';
|
|
5
|
-
import { fieldAffectsData, optionIsObject } from 'payload/shared';
|
|
5
|
+
import { fieldAffectsData, fieldIsVirtual, optionIsObject } from 'payload/shared';
|
|
6
6
|
import toSnakeCase from 'to-snake-case';
|
|
7
7
|
import { buildTable } from './build.js';
|
|
8
8
|
import { createIndex } from './createIndex.js';
|
|
9
9
|
import { getIDColumn } from './getIDColumn.js';
|
|
10
10
|
import { idToUUID } from './idToUUID.js';
|
|
11
11
|
import { withDefault } from './withDefault.js';
|
|
12
|
-
export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, versions, withinLocalizedArrayOrBlock })=>{
|
|
12
|
+
export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull, disableRelsTableUnique, disableUnique = false, fieldPrefix, fields, forceLocalized, indexes, locales, localesColumns, localesIndexes, newTableName, parentTableName, relationships, relationsToBuild, rootRelationsToBuild, rootTableIDColType, rootTableName, uniqueRelationships, versions, withinLocalizedArrayOrBlock })=>{
|
|
13
13
|
let hasLocalizedField = false;
|
|
14
14
|
let hasLocalizedRelationshipField = false;
|
|
15
15
|
let hasManyTextField = false;
|
|
@@ -30,6 +30,9 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
30
30
|
if ('name' in field && field.name === 'id') {
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
+
if (fieldIsVirtual(field)) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
33
36
|
let columnName;
|
|
34
37
|
let fieldName;
|
|
35
38
|
let targetTable = columns;
|
|
@@ -44,14 +47,15 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
44
47
|
targetTable = localesColumns;
|
|
45
48
|
targetIndexes = localesIndexes;
|
|
46
49
|
}
|
|
47
|
-
if ((field.unique || field.index
|
|
50
|
+
if ((field.unique || field.index || [
|
|
51
|
+
'relationship',
|
|
52
|
+
'upload'
|
|
53
|
+
].includes(field.type)) && ![
|
|
48
54
|
'array',
|
|
49
55
|
'blocks',
|
|
50
56
|
'group',
|
|
51
|
-
'point'
|
|
52
|
-
|
|
53
|
-
'upload'
|
|
54
|
-
].includes(field.type) && !('hasMany' in field && field.hasMany === true)) {
|
|
57
|
+
'point'
|
|
58
|
+
].includes(field.type) && !('hasMany' in field && field.hasMany === true) && !('relationTo' in field && Array.isArray(field.relationTo))) {
|
|
55
59
|
const unique = disableUnique !== true && field.unique;
|
|
56
60
|
if (unique) {
|
|
57
61
|
const constraintValue = `${fieldPrefix || ''}${field.name}`;
|
|
@@ -60,173 +64,21 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
60
64
|
}
|
|
61
65
|
adapter.fieldConstraints[rootTableName][`${columnName}_idx`] = constraintValue;
|
|
62
66
|
}
|
|
63
|
-
|
|
64
|
-
name:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
const indexName = buildIndexName({
|
|
68
|
+
name: `${newTableName}_${columnName}`,
|
|
69
|
+
adapter: adapter
|
|
70
|
+
});
|
|
71
|
+
targetIndexes[indexName] = createIndex({
|
|
72
|
+
name: field.localized ? [
|
|
73
|
+
fieldName,
|
|
74
|
+
'_locale'
|
|
75
|
+
] : fieldName,
|
|
76
|
+
indexName,
|
|
67
77
|
unique
|
|
68
78
|
});
|
|
69
79
|
}
|
|
70
80
|
}
|
|
71
81
|
switch(field.type){
|
|
72
|
-
case 'text':
|
|
73
|
-
{
|
|
74
|
-
if (field.hasMany) {
|
|
75
|
-
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
|
|
76
|
-
if (isLocalized) {
|
|
77
|
-
hasLocalizedManyTextField = true;
|
|
78
|
-
}
|
|
79
|
-
if (field.index) {
|
|
80
|
-
hasManyTextField = 'index';
|
|
81
|
-
} else if (!hasManyTextField) {
|
|
82
|
-
hasManyTextField = true;
|
|
83
|
-
}
|
|
84
|
-
if (field.unique) {
|
|
85
|
-
throw new InvalidConfiguration('Unique is not supported in SQLite for hasMany text fields.');
|
|
86
|
-
}
|
|
87
|
-
} else {
|
|
88
|
-
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
89
|
-
}
|
|
90
|
-
break;
|
|
91
|
-
}
|
|
92
|
-
case 'email':
|
|
93
|
-
case 'code':
|
|
94
|
-
case 'textarea':
|
|
95
|
-
{
|
|
96
|
-
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
case 'number':
|
|
100
|
-
{
|
|
101
|
-
if (field.hasMany) {
|
|
102
|
-
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
|
|
103
|
-
if (isLocalized) {
|
|
104
|
-
hasLocalizedManyNumberField = true;
|
|
105
|
-
}
|
|
106
|
-
if (field.index) {
|
|
107
|
-
hasManyNumberField = 'index';
|
|
108
|
-
} else if (!hasManyNumberField) {
|
|
109
|
-
hasManyNumberField = true;
|
|
110
|
-
}
|
|
111
|
-
if (field.unique) {
|
|
112
|
-
throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany number fields.');
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
targetTable[fieldName] = withDefault(numeric(columnName), field);
|
|
116
|
-
}
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
case 'richText':
|
|
120
|
-
case 'json':
|
|
121
|
-
{
|
|
122
|
-
targetTable[fieldName] = withDefault(text(columnName, {
|
|
123
|
-
mode: 'json'
|
|
124
|
-
}), field);
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
case 'date':
|
|
128
|
-
{
|
|
129
|
-
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
case 'point':
|
|
133
|
-
{
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
case 'radio':
|
|
137
|
-
case 'select':
|
|
138
|
-
{
|
|
139
|
-
const options = field.options.map((option)=>{
|
|
140
|
-
if (optionIsObject(option)) {
|
|
141
|
-
return option.value;
|
|
142
|
-
}
|
|
143
|
-
return option;
|
|
144
|
-
});
|
|
145
|
-
if (field.type === 'select' && field.hasMany) {
|
|
146
|
-
const selectTableName = createTableName({
|
|
147
|
-
adapter,
|
|
148
|
-
config: field,
|
|
149
|
-
parentTableName: newTableName,
|
|
150
|
-
prefix: `${newTableName}_`,
|
|
151
|
-
versionsCustomName: versions
|
|
152
|
-
});
|
|
153
|
-
const baseColumns = {
|
|
154
|
-
order: integer('order').notNull(),
|
|
155
|
-
parent: getIDColumn({
|
|
156
|
-
name: 'parent_id',
|
|
157
|
-
type: parentIDColType,
|
|
158
|
-
notNull: true,
|
|
159
|
-
primaryKey: false
|
|
160
|
-
}),
|
|
161
|
-
value: text('value', {
|
|
162
|
-
enum: options
|
|
163
|
-
})
|
|
164
|
-
};
|
|
165
|
-
const baseExtraConfig = {
|
|
166
|
-
orderIdx: (cols)=>index(`${selectTableName}_order_idx`).on(cols.order),
|
|
167
|
-
parentFk: (cols)=>foreignKey({
|
|
168
|
-
name: `${selectTableName}_parent_fk`,
|
|
169
|
-
columns: [
|
|
170
|
-
cols.parent
|
|
171
|
-
],
|
|
172
|
-
foreignColumns: [
|
|
173
|
-
adapter.tables[parentTableName].id
|
|
174
|
-
]
|
|
175
|
-
}).onDelete('cascade'),
|
|
176
|
-
parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
|
|
177
|
-
};
|
|
178
|
-
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
|
|
179
|
-
if (isLocalized) {
|
|
180
|
-
baseColumns.locale = text('locale', {
|
|
181
|
-
enum: locales
|
|
182
|
-
}).notNull();
|
|
183
|
-
baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
|
|
184
|
-
}
|
|
185
|
-
if (field.index) {
|
|
186
|
-
baseExtraConfig.value = (cols)=>index(`${selectTableName}_value_idx`).on(cols.value);
|
|
187
|
-
}
|
|
188
|
-
buildTable({
|
|
189
|
-
adapter,
|
|
190
|
-
baseColumns,
|
|
191
|
-
baseExtraConfig,
|
|
192
|
-
disableNotNull,
|
|
193
|
-
disableUnique,
|
|
194
|
-
fields: [],
|
|
195
|
-
rootTableName,
|
|
196
|
-
tableName: selectTableName,
|
|
197
|
-
versions
|
|
198
|
-
});
|
|
199
|
-
relationsToBuild.set(fieldName, {
|
|
200
|
-
type: 'many',
|
|
201
|
-
// selects have their own localized table, independent of the base table.
|
|
202
|
-
localized: false,
|
|
203
|
-
target: selectTableName
|
|
204
|
-
});
|
|
205
|
-
adapter.relations[`relations_${selectTableName}`] = relations(adapter.tables[selectTableName], ({ one })=>({
|
|
206
|
-
parent: one(adapter.tables[parentTableName], {
|
|
207
|
-
fields: [
|
|
208
|
-
adapter.tables[selectTableName].parent
|
|
209
|
-
],
|
|
210
|
-
references: [
|
|
211
|
-
adapter.tables[parentTableName].id
|
|
212
|
-
],
|
|
213
|
-
relationName: fieldName
|
|
214
|
-
})
|
|
215
|
-
}));
|
|
216
|
-
} else {
|
|
217
|
-
targetTable[fieldName] = withDefault(text(fieldName, {
|
|
218
|
-
enum: options
|
|
219
|
-
}), field);
|
|
220
|
-
}
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
case 'checkbox':
|
|
224
|
-
{
|
|
225
|
-
targetTable[fieldName] = withDefault(integer(columnName, {
|
|
226
|
-
mode: 'boolean'
|
|
227
|
-
}), field);
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
82
|
case 'array':
|
|
231
83
|
{
|
|
232
84
|
const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
|
|
@@ -259,7 +111,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
259
111
|
}).onDelete('cascade'),
|
|
260
112
|
_parentIDIdx: (cols)=>index(`${arrayTableName}_parent_id_idx`).on(cols._parentID)
|
|
261
113
|
};
|
|
262
|
-
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
|
|
114
|
+
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
|
|
263
115
|
if (isLocalized) {
|
|
264
116
|
baseColumns._locale = text('_locale', {
|
|
265
117
|
enum: locales
|
|
@@ -271,12 +123,14 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
271
123
|
baseColumns,
|
|
272
124
|
baseExtraConfig,
|
|
273
125
|
disableNotNull: disableNotNullFromHere,
|
|
126
|
+
disableRelsTableUnique: true,
|
|
274
127
|
disableUnique,
|
|
275
128
|
fields: disableUnique ? idToUUID(field.fields) : field.fields,
|
|
276
129
|
rootRelationships: relationships,
|
|
277
130
|
rootRelationsToBuild,
|
|
278
131
|
rootTableIDColType,
|
|
279
132
|
rootTableName,
|
|
133
|
+
rootUniqueRelationships: uniqueRelationships,
|
|
280
134
|
tableName: arrayTableName,
|
|
281
135
|
versions,
|
|
282
136
|
withinLocalizedArrayOrBlock: isLocalized
|
|
@@ -382,7 +236,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
382
236
|
_parentIDIdx: (cols)=>index(`${blockTableName}_parent_id_idx`).on(cols._parentID),
|
|
383
237
|
_pathIdx: (cols)=>index(`${blockTableName}_path_idx`).on(cols._path)
|
|
384
238
|
};
|
|
385
|
-
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock;
|
|
239
|
+
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
|
|
386
240
|
if (isLocalized) {
|
|
387
241
|
baseColumns._locale = text('_locale', {
|
|
388
242
|
enum: locales
|
|
@@ -394,12 +248,14 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
394
248
|
baseColumns,
|
|
395
249
|
baseExtraConfig,
|
|
396
250
|
disableNotNull: disableNotNullFromHere,
|
|
251
|
+
disableRelsTableUnique: true,
|
|
397
252
|
disableUnique,
|
|
398
253
|
fields: disableUnique ? idToUUID(block.fields) : block.fields,
|
|
399
254
|
rootRelationships: relationships,
|
|
400
255
|
rootRelationsToBuild,
|
|
401
256
|
rootTableIDColType,
|
|
402
257
|
rootTableName,
|
|
258
|
+
rootUniqueRelationships: uniqueRelationships,
|
|
403
259
|
tableName: blockTableName,
|
|
404
260
|
versions,
|
|
405
261
|
withinLocalizedArrayOrBlock: isLocalized
|
|
@@ -480,8 +336,75 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
480
336
|
});
|
|
481
337
|
break;
|
|
482
338
|
}
|
|
483
|
-
case '
|
|
339
|
+
case 'checkbox':
|
|
340
|
+
{
|
|
341
|
+
targetTable[fieldName] = withDefault(integer(columnName, {
|
|
342
|
+
mode: 'boolean'
|
|
343
|
+
}), field);
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
case 'code':
|
|
347
|
+
case 'email':
|
|
348
|
+
case 'textarea':
|
|
349
|
+
{
|
|
350
|
+
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
case 'collapsible':
|
|
354
|
+
case 'row':
|
|
355
|
+
{
|
|
356
|
+
const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
|
|
357
|
+
const { hasLocalizedField: rowHasLocalizedField, hasLocalizedManyNumberField: rowHasLocalizedManyNumberField, hasLocalizedManyTextField: rowHasLocalizedManyTextField, hasLocalizedRelationshipField: rowHasLocalizedRelationshipField, hasManyNumberField: rowHasManyNumberField, hasManyTextField: rowHasManyTextField } = traverseFields({
|
|
358
|
+
adapter,
|
|
359
|
+
columnPrefix,
|
|
360
|
+
columns,
|
|
361
|
+
disableNotNull: disableNotNullFromHere,
|
|
362
|
+
disableUnique,
|
|
363
|
+
fieldPrefix,
|
|
364
|
+
fields: field.fields,
|
|
365
|
+
forceLocalized,
|
|
366
|
+
indexes,
|
|
367
|
+
locales,
|
|
368
|
+
localesColumns,
|
|
369
|
+
localesIndexes,
|
|
370
|
+
newTableName,
|
|
371
|
+
parentTableName,
|
|
372
|
+
relationships,
|
|
373
|
+
relationsToBuild,
|
|
374
|
+
rootRelationsToBuild,
|
|
375
|
+
rootTableIDColType,
|
|
376
|
+
rootTableName,
|
|
377
|
+
uniqueRelationships,
|
|
378
|
+
versions,
|
|
379
|
+
withinLocalizedArrayOrBlock
|
|
380
|
+
});
|
|
381
|
+
if (rowHasLocalizedField) {
|
|
382
|
+
hasLocalizedField = true;
|
|
383
|
+
}
|
|
384
|
+
if (rowHasLocalizedRelationshipField) {
|
|
385
|
+
hasLocalizedRelationshipField = true;
|
|
386
|
+
}
|
|
387
|
+
if (rowHasManyTextField) {
|
|
388
|
+
hasManyTextField = true;
|
|
389
|
+
}
|
|
390
|
+
if (rowHasLocalizedManyTextField) {
|
|
391
|
+
hasLocalizedManyTextField = true;
|
|
392
|
+
}
|
|
393
|
+
if (rowHasManyNumberField) {
|
|
394
|
+
hasManyNumberField = true;
|
|
395
|
+
}
|
|
396
|
+
if (rowHasLocalizedManyNumberField) {
|
|
397
|
+
hasLocalizedManyNumberField = true;
|
|
398
|
+
}
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
case 'date':
|
|
402
|
+
{
|
|
403
|
+
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
484
406
|
case 'group':
|
|
407
|
+
case 'tab':
|
|
485
408
|
{
|
|
486
409
|
if (!('name' in field)) {
|
|
487
410
|
const { hasLocalizedField: groupHasLocalizedField, hasLocalizedManyNumberField: groupHasLocalizedManyNumberField, hasLocalizedManyTextField: groupHasLocalizedManyTextField, hasLocalizedRelationshipField: groupHasLocalizedRelationshipField, hasManyNumberField: groupHasManyNumberField, hasManyTextField: groupHasManyTextField } = traverseFields({
|
|
@@ -504,6 +427,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
504
427
|
rootRelationsToBuild,
|
|
505
428
|
rootTableIDColType,
|
|
506
429
|
rootTableName,
|
|
430
|
+
uniqueRelationships,
|
|
507
431
|
versions,
|
|
508
432
|
withinLocalizedArrayOrBlock
|
|
509
433
|
});
|
|
@@ -548,8 +472,9 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
548
472
|
rootRelationsToBuild,
|
|
549
473
|
rootTableIDColType,
|
|
550
474
|
rootTableName,
|
|
475
|
+
uniqueRelationships,
|
|
551
476
|
versions,
|
|
552
|
-
withinLocalizedArrayOrBlock
|
|
477
|
+
withinLocalizedArrayOrBlock: withinLocalizedArrayOrBlock || field.localized
|
|
553
478
|
});
|
|
554
479
|
if (groupHasLocalizedField) {
|
|
555
480
|
hasLocalizedField = true;
|
|
@@ -571,6 +496,176 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
571
496
|
}
|
|
572
497
|
break;
|
|
573
498
|
}
|
|
499
|
+
case 'json':
|
|
500
|
+
case 'richText':
|
|
501
|
+
{
|
|
502
|
+
targetTable[fieldName] = withDefault(text(columnName, {
|
|
503
|
+
mode: 'json'
|
|
504
|
+
}), field);
|
|
505
|
+
break;
|
|
506
|
+
}
|
|
507
|
+
case 'number':
|
|
508
|
+
{
|
|
509
|
+
if (field.hasMany) {
|
|
510
|
+
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
|
|
511
|
+
if (isLocalized) {
|
|
512
|
+
hasLocalizedManyNumberField = true;
|
|
513
|
+
}
|
|
514
|
+
if (field.index) {
|
|
515
|
+
hasManyNumberField = 'index';
|
|
516
|
+
} else if (!hasManyNumberField) {
|
|
517
|
+
hasManyNumberField = true;
|
|
518
|
+
}
|
|
519
|
+
if (field.unique) {
|
|
520
|
+
throw new InvalidConfiguration('Unique is not supported in Postgres for hasMany number fields.');
|
|
521
|
+
}
|
|
522
|
+
} else {
|
|
523
|
+
targetTable[fieldName] = withDefault(numeric(columnName), field);
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
case 'point':
|
|
528
|
+
{
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case 'radio':
|
|
532
|
+
case 'select':
|
|
533
|
+
{
|
|
534
|
+
const options = field.options.map((option)=>{
|
|
535
|
+
if (optionIsObject(option)) {
|
|
536
|
+
return option.value;
|
|
537
|
+
}
|
|
538
|
+
return option;
|
|
539
|
+
});
|
|
540
|
+
if (field.type === 'select' && field.hasMany) {
|
|
541
|
+
const selectTableName = createTableName({
|
|
542
|
+
adapter,
|
|
543
|
+
config: field,
|
|
544
|
+
parentTableName: newTableName,
|
|
545
|
+
prefix: `${newTableName}_`,
|
|
546
|
+
versionsCustomName: versions
|
|
547
|
+
});
|
|
548
|
+
const baseColumns = {
|
|
549
|
+
order: integer('order').notNull(),
|
|
550
|
+
parent: getIDColumn({
|
|
551
|
+
name: 'parent_id',
|
|
552
|
+
type: parentIDColType,
|
|
553
|
+
notNull: true,
|
|
554
|
+
primaryKey: false
|
|
555
|
+
}),
|
|
556
|
+
value: text('value', {
|
|
557
|
+
enum: options
|
|
558
|
+
})
|
|
559
|
+
};
|
|
560
|
+
const baseExtraConfig = {
|
|
561
|
+
orderIdx: (cols)=>index(`${selectTableName}_order_idx`).on(cols.order),
|
|
562
|
+
parentFk: (cols)=>foreignKey({
|
|
563
|
+
name: `${selectTableName}_parent_fk`,
|
|
564
|
+
columns: [
|
|
565
|
+
cols.parent
|
|
566
|
+
],
|
|
567
|
+
foreignColumns: [
|
|
568
|
+
adapter.tables[parentTableName].id
|
|
569
|
+
]
|
|
570
|
+
}).onDelete('cascade'),
|
|
571
|
+
parentIdx: (cols)=>index(`${selectTableName}_parent_idx`).on(cols.parent)
|
|
572
|
+
};
|
|
573
|
+
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
|
|
574
|
+
if (isLocalized) {
|
|
575
|
+
baseColumns.locale = text('locale', {
|
|
576
|
+
enum: locales
|
|
577
|
+
}).notNull();
|
|
578
|
+
baseExtraConfig.localeIdx = (cols)=>index(`${selectTableName}_locale_idx`).on(cols.locale);
|
|
579
|
+
}
|
|
580
|
+
if (field.index) {
|
|
581
|
+
baseExtraConfig.value = (cols)=>index(`${selectTableName}_value_idx`).on(cols.value);
|
|
582
|
+
}
|
|
583
|
+
buildTable({
|
|
584
|
+
adapter,
|
|
585
|
+
baseColumns,
|
|
586
|
+
baseExtraConfig,
|
|
587
|
+
disableNotNull,
|
|
588
|
+
disableUnique,
|
|
589
|
+
fields: [],
|
|
590
|
+
rootTableName,
|
|
591
|
+
tableName: selectTableName,
|
|
592
|
+
versions
|
|
593
|
+
});
|
|
594
|
+
relationsToBuild.set(fieldName, {
|
|
595
|
+
type: 'many',
|
|
596
|
+
// selects have their own localized table, independent of the base table.
|
|
597
|
+
localized: false,
|
|
598
|
+
target: selectTableName
|
|
599
|
+
});
|
|
600
|
+
adapter.relations[`relations_${selectTableName}`] = relations(adapter.tables[selectTableName], ({ one })=>({
|
|
601
|
+
parent: one(adapter.tables[parentTableName], {
|
|
602
|
+
fields: [
|
|
603
|
+
adapter.tables[selectTableName].parent
|
|
604
|
+
],
|
|
605
|
+
references: [
|
|
606
|
+
adapter.tables[parentTableName].id
|
|
607
|
+
],
|
|
608
|
+
relationName: fieldName
|
|
609
|
+
})
|
|
610
|
+
}));
|
|
611
|
+
} else {
|
|
612
|
+
targetTable[fieldName] = withDefault(text(columnName, {
|
|
613
|
+
enum: options
|
|
614
|
+
}), field);
|
|
615
|
+
}
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
case 'relationship':
|
|
619
|
+
case 'upload':
|
|
620
|
+
if (Array.isArray(field.relationTo)) {
|
|
621
|
+
field.relationTo.forEach((relation)=>{
|
|
622
|
+
relationships.add(relation);
|
|
623
|
+
if (field.unique && !disableUnique && !disableRelsTableUnique) {
|
|
624
|
+
uniqueRelationships.add(relation);
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
} else if (field.hasMany) {
|
|
628
|
+
relationships.add(field.relationTo);
|
|
629
|
+
if (field.unique && !disableUnique && !disableRelsTableUnique) {
|
|
630
|
+
uniqueRelationships.add(field.relationTo);
|
|
631
|
+
}
|
|
632
|
+
} else {
|
|
633
|
+
// simple relationships get a column on the targetTable with a foreign key to the relationTo table
|
|
634
|
+
const relationshipConfig = adapter.payload.collections[field.relationTo].config;
|
|
635
|
+
const tableName = adapter.tableNameMap.get(toSnakeCase(field.relationTo));
|
|
636
|
+
// get the id type of the related collection
|
|
637
|
+
let colType = 'integer';
|
|
638
|
+
const relatedCollectionCustomID = relationshipConfig.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
|
|
639
|
+
if (relatedCollectionCustomID?.type === 'number') {
|
|
640
|
+
colType = 'numeric';
|
|
641
|
+
}
|
|
642
|
+
if (relatedCollectionCustomID?.type === 'text') {
|
|
643
|
+
colType = 'text';
|
|
644
|
+
}
|
|
645
|
+
// make the foreign key column for relationship using the correct id column type
|
|
646
|
+
targetTable[fieldName] = getIDColumn({
|
|
647
|
+
name: `${columnName}_id`,
|
|
648
|
+
type: colType,
|
|
649
|
+
primaryKey: false
|
|
650
|
+
}).references(()=>adapter.tables[tableName].id, {
|
|
651
|
+
onDelete: 'set null'
|
|
652
|
+
});
|
|
653
|
+
// add relationship to table
|
|
654
|
+
relationsToBuild.set(fieldName, {
|
|
655
|
+
type: 'one',
|
|
656
|
+
localized: adapter.payload.config.localization && (field.localized || forceLocalized),
|
|
657
|
+
target: tableName
|
|
658
|
+
});
|
|
659
|
+
// add notNull when not required
|
|
660
|
+
if (!disableNotNull && field.required && !field.admin?.condition) {
|
|
661
|
+
targetTable[fieldName].notNull();
|
|
662
|
+
}
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
if (Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock) {
|
|
666
|
+
hasLocalizedRelationshipField = true;
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
574
669
|
case 'tabs':
|
|
575
670
|
{
|
|
576
671
|
const disableNotNullFromHere = Boolean(field.admin?.condition) || disableNotNull;
|
|
@@ -597,6 +692,7 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
597
692
|
rootRelationsToBuild,
|
|
598
693
|
rootTableIDColType,
|
|
599
694
|
rootTableName,
|
|
695
|
+
uniqueRelationships,
|
|
600
696
|
versions,
|
|
601
697
|
withinLocalizedArrayOrBlock
|
|
602
698
|
});
|
|
@@ -620,96 +716,26 @@ export const traverseFields = ({ adapter, columnPrefix, columns, disableNotNull,
|
|
|
620
716
|
}
|
|
621
717
|
break;
|
|
622
718
|
}
|
|
623
|
-
case '
|
|
624
|
-
case 'collapsible':
|
|
719
|
+
case 'text':
|
|
625
720
|
{
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
parentTableName,
|
|
642
|
-
relationships,
|
|
643
|
-
relationsToBuild,
|
|
644
|
-
rootRelationsToBuild,
|
|
645
|
-
rootTableIDColType,
|
|
646
|
-
rootTableName,
|
|
647
|
-
versions,
|
|
648
|
-
withinLocalizedArrayOrBlock
|
|
649
|
-
});
|
|
650
|
-
if (rowHasLocalizedField) {
|
|
651
|
-
hasLocalizedField = true;
|
|
652
|
-
}
|
|
653
|
-
if (rowHasLocalizedRelationshipField) {
|
|
654
|
-
hasLocalizedRelationshipField = true;
|
|
655
|
-
}
|
|
656
|
-
if (rowHasManyTextField) {
|
|
657
|
-
hasManyTextField = true;
|
|
658
|
-
}
|
|
659
|
-
if (rowHasLocalizedManyTextField) {
|
|
660
|
-
hasLocalizedManyTextField = true;
|
|
661
|
-
}
|
|
662
|
-
if (rowHasManyNumberField) {
|
|
663
|
-
hasManyNumberField = true;
|
|
664
|
-
}
|
|
665
|
-
if (rowHasLocalizedManyNumberField) {
|
|
666
|
-
hasLocalizedManyNumberField = true;
|
|
667
|
-
}
|
|
668
|
-
break;
|
|
669
|
-
}
|
|
670
|
-
case 'relationship':
|
|
671
|
-
case 'upload':
|
|
672
|
-
if (Array.isArray(field.relationTo)) {
|
|
673
|
-
field.relationTo.forEach((relation)=>relationships.add(relation));
|
|
674
|
-
} else if (field.hasMany) {
|
|
675
|
-
relationships.add(field.relationTo);
|
|
676
|
-
} else {
|
|
677
|
-
// simple relationships get a column on the targetTable with a foreign key to the relationTo table
|
|
678
|
-
const relationshipConfig = adapter.payload.collections[field.relationTo].config;
|
|
679
|
-
const tableName = adapter.tableNameMap.get(toSnakeCase(field.relationTo));
|
|
680
|
-
// get the id type of the related collection
|
|
681
|
-
let colType = 'integer';
|
|
682
|
-
const relatedCollectionCustomID = relationshipConfig.fields.find((field)=>fieldAffectsData(field) && field.name === 'id');
|
|
683
|
-
if (relatedCollectionCustomID?.type === 'number') {
|
|
684
|
-
colType = 'numeric';
|
|
685
|
-
}
|
|
686
|
-
if (relatedCollectionCustomID?.type === 'text') {
|
|
687
|
-
colType = 'text';
|
|
688
|
-
}
|
|
689
|
-
// make the foreign key column for relationship using the correct id column type
|
|
690
|
-
targetTable[fieldName] = getIDColumn({
|
|
691
|
-
name: `${columnName}_id`,
|
|
692
|
-
type: colType,
|
|
693
|
-
primaryKey: false
|
|
694
|
-
}).references(()=>adapter.tables[tableName].id, {
|
|
695
|
-
onDelete: 'set null'
|
|
696
|
-
});
|
|
697
|
-
// add relationship to table
|
|
698
|
-
relationsToBuild.set(fieldName, {
|
|
699
|
-
type: 'one',
|
|
700
|
-
localized: adapter.payload.config.localization && field.localized,
|
|
701
|
-
target: tableName
|
|
702
|
-
});
|
|
703
|
-
// add notNull when not required
|
|
704
|
-
if (!disableNotNull && field.required && !field.admin?.condition) {
|
|
705
|
-
targetTable[fieldName].notNull();
|
|
721
|
+
if (field.hasMany) {
|
|
722
|
+
const isLocalized = Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock || forceLocalized;
|
|
723
|
+
if (isLocalized) {
|
|
724
|
+
hasLocalizedManyTextField = true;
|
|
725
|
+
}
|
|
726
|
+
if (field.index) {
|
|
727
|
+
hasManyTextField = 'index';
|
|
728
|
+
} else if (!hasManyTextField) {
|
|
729
|
+
hasManyTextField = true;
|
|
730
|
+
}
|
|
731
|
+
if (field.unique) {
|
|
732
|
+
throw new InvalidConfiguration('Unique is not supported in SQLite for hasMany text fields.');
|
|
733
|
+
}
|
|
734
|
+
} else {
|
|
735
|
+
targetTable[fieldName] = withDefault(text(columnName), field);
|
|
706
736
|
}
|
|
707
737
|
break;
|
|
708
738
|
}
|
|
709
|
-
if (Boolean(field.localized && adapter.payload.config.localization) || withinLocalizedArrayOrBlock) {
|
|
710
|
-
hasLocalizedRelationshipField = true;
|
|
711
|
-
}
|
|
712
|
-
break;
|
|
713
739
|
default:
|
|
714
740
|
break;
|
|
715
741
|
}
|