@@ -2,7 +2,7 @@ const chalk = require('chalk');
2
2
const inquirer = require("inquirer");
3
3
const JSONbig = require("json-bigint")({ storeAsString: false });
4
4
const { Command } = require("commander");
5
- const { localConfig, globalConfig } = require("../config");
5
+ const { localConfig, globalConfig, KeyAttributes } = require("../config");
6
6
const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
7
7
const { paginate } = require('../paginate');
8
8
const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsGetEntrypoint, questionsPushCollections, questionsConfirmPushCollections, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
@@ -37,6 +37,7 @@ const {
37
37
databasesUpdateRelationshipAttribute,
38
38
databasesCreateRelationshipAttribute,
39
39
databasesDeleteAttribute,
40
+ databasesDeleteIndex,
40
41
databasesListAttributes,
41
42
databasesListIndexes,
42
43
databasesUpdateCollection
@@ -254,6 +255,41 @@ const awaitPools = {
254
255
iteration + 1
255
256
);
256
257
},
258
+ deleteIndexes: async (databaseId, collectionId, indexesKeys, iteration = 1) => {
259
+ if (iteration > pollMaxDebounces) {
260
+ return false;
261
+ }
262
+
263
+ if (pollMaxDebounces === POLL_DEFAULT_VALUE) {
264
+ let steps = Math.max(1, Math.ceil(attributeKeys.length / STEP_SIZE));
265
+ if (steps > 1 && iteration === 1) {
266
+ pollMaxDebounces *= steps;
267
+
268
+ log('Found a large number of indexes to be deleted. Increasing timeout to ' + (pollMaxDebounces * POLL_DEBOUNCE / 1000 / 60) + ' minutes')
269
+ }
270
+ }
271
+
272
+ const { indexes } = await paginate(databasesListIndexes, {
273
+ databaseId,
274
+ collectionId,
275
+ parseOutput: false
276
+ }, 100, 'indexes');
277
+
278
+ const ready = indexesKeys.filter(index => indexes.includes(index.key));
279
+
280
+ if (ready.length === 0) {
281
+ return true;
282
+ }
283
+
284
+ await new Promise(resolve => setTimeout(resolve, POLL_DEBOUNCE));
285
+
286
+ return await awaitPools.expectIndexes(
287
+ databaseId,
288
+ collectionId,
289
+ indexesKeys,
290
+ iteration + 1
291
+ );
292
+ },
257
293
expectIndexes: async (databaseId, collectionId, indexKeys, iteration = 1) => {
258
294
if (iteration > pollMaxDebounces) {
259
295
return false;
@@ -536,8 +572,18 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
536
572
})
537
573
}
538
574
}
539
- const deleteAttribute = async (collection, attribute) => {
540
- log(`Deleting attribute ${attribute.key} of ${collection.name} ( ${collection['$id']} )`);
575
+ const deleteAttribute = async (collection, attribute, isIndex = false) => {
576
+ log(`Deleting ${isIndex ? 'index' : 'attribute'} ${attribute.key} of ${collection.name} ( ${collection['$id']} )`);
577
+
578
+ if (isIndex) {
579
+ await databasesDeleteIndex({
580
+ databaseId: collection['databaseId'],
581
+ collectionId: collection['$id'],
582
+ key: attribute.key,
583
+ parseOutput: false
584
+ });
585
+ return;
586
+ }
541
587
542
588
await databasesDeleteAttribute({
543
589
databaseId: collection['databaseId'],
@@ -568,6 +614,10 @@ const checkAttributeChanges = (remote, local, collection, recraeting = true) =>
568
614
let attribute = remote;
569
615
570
616
for (let key of Object.keys(remote)) {
617
+ if (!KeyAttributes.has(key)) {
618
+ continue;
619
+ }
620
+
571
621
if (changeableKeys.includes(key)) {
572
622
if (!recraeting) {
573
623
if (remote[key] !== local[key]) {
@@ -583,7 +633,12 @@ const checkAttributeChanges = (remote, local, collection, recraeting = true) =>
583
633
continue;
584
634
}
585
635
586
- if (remote[key] !== local[key]) {
636
+ if (Array.isArray(remote[key]) && Array.isArray(local[key])) {
637
+ if (JSON.stringify(remote[key]) !== JSON.stringify(local[key])) {
638
+ const bol = reason === '' ? '' : '\n';
639
+ reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
640
+ }
641
+ } else if (remote[key] !== local[key]) {
587
642
const bol = reason === '' ? '' : '\n';
588
643
reason += `${bol}${key} changed from ${chalk.red(remote[key])} to ${chalk.green(local[key])}`;
589
644
}
@@ -612,12 +667,9 @@ const generateChangesObject = (attribute, collection, isAdding) => {
612
667
/**
613
668
* Filter deleted and recreated attributes,
614
669
* return list of attributes to create
615
- * @param remoteAttributes
616
- * @param localAttributes
617
- * @param collection
618
670
* @returns {Promise< *|*[]>}
619
671
*/
620
- const attributesToCreate = async (remoteAttributes, localAttributes, collection) => {
672
+ const attributesToCreate = async (remoteAttributes, localAttributes, collection, isIndex = false ) => {
621
673
622
674
const deleting = remoteAttributes.filter((attribute) => !attributesContains(attribute, localAttributes)).map((attr) => generateChangesObject(attr, collection, false));
623
675
const adding = localAttributes.filter((attribute) => !attributesContains(attribute, remoteAttributes)).map((attr) => generateChangesObject(attr, collection, true));
@@ -639,10 +691,10 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection)
639
691
}));
640
692
641
693
if (!cliConfig.force) {
642
- if (deleting.length > 0) {
694
+ if (deleting.length > 0 && !isIndex ) {
643
695
log(`Attribute deletion will cause ${chalk.red('loss of data')}`);
644
696
}
645
- if (conflicts.length > 0) {
697
+ if (conflicts.length > 0 && !isIndex ) {
646
698
log(`Attribute recreation will cause ${chalk.red('loss of data')}`);
647
699
}
648
700
@@ -655,7 +707,7 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection)
655
707
656
708
if (conflicts.length > 0) {
657
709
changedAttributes = conflicts.map((change) => change.attribute);
658
- await Promise.all(changedAttributes.map((changed) => deleteAttribute(collection, changed)));
710
+ await Promise.all(changedAttributes.map((changed) => deleteAttribute(collection, changed, isIndex )));
659
711
remoteAttributes = remoteAttributes.filter((attribute) => !attributesContains(attribute, changedAttributes))
660
712
}
661
713
@@ -665,7 +717,7 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection)
665
717
}
666
718
667
719
const deletingAttributes = deleting.map((change) => change.attribute);
668
- await Promise.all(deletingAttributes.map((attribute) => deleteAttribute(collection, attribute)));
720
+ await Promise.all(deletingAttributes.map((attribute) => deleteAttribute(collection, attribute, isIndex )));
669
721
const attributeKeys = [...remoteAttributes.map(attribute => attribute.key), ...deletingAttributes.map(attribute => attribute.key)]
670
722
671
723
if (attributeKeys.length) {
@@ -1149,13 +1201,16 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
1149
1201
// Serialize attribute actions
1150
1202
for (let collection of collections) {
1151
1203
let attributes = collection.attributes;
1204
+ let indexes = collection.indexes;
1152
1205
1153
1206
if (collection.isExisted) {
1154
1207
attributes = await attributesToCreate(collection.remoteVersion.attributes, collection.attributes, collection);
1208
+ indexes = await attributesToCreate(collection.remoteVersion.indexes, collection.indexes, collection, true);
1155
1209
1156
- if (Array.isArray(attributes) && attributes.length < = 0) {
1210
+ if (( Array.isArray(attributes) && attributes.length < = 0) && (Array.isArray(indexes) && indexes.length < = 0) ) {
1157
1211
continue;
1158
1212
}
1213
+
1159
1214
}
1160
1215
1161
1216
log(`Pushing collection ${collection.name} ( ${collection['databaseId']} - ${collection['$id']} ) attributes`)
@@ -1167,7 +1222,7 @@ const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false
1167
1222
}
1168
1223
1169
1224
try {
1170
- await createIndexes(collection. indexes, collection);
1225
+ await createIndexes(indexes, collection);
1171
1226
} catch (e) {
1172
1227
throw e;
1173
1228
}
0 commit comments