@@ -6,10 +6,10 @@ const inquirer = require("inquirer");
6
6
const JSONbig = require("json-bigint")({ storeAsString: false });
7
7
const { Command } = require("commander");
8
8
const ID = require("../id");
9
- const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection } = require("../config");
9
+ const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection, KeysTable } = require("../config");
10
10
const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
11
11
const { paginate } = require('../paginate');
12
- const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionPushChanges, questionPushChangesConfirmation, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
12
+ const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionsPushTables, questionPushChanges, questionPushChangesConfirmation, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
13
13
const { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable } = require("../parser");
14
14
const { proxyCreateFunctionRule, proxyCreateSiteRule, proxyListRules } = require('./proxy');
15
15
const { consoleVariables } = require('./console');
@@ -49,6 +49,10 @@ const {
49
49
databasesListIndexes,
50
50
databasesUpdateCollection
51
51
} = require("./databases");
52
+ const {
53
+ gridsGetDatabase,
54
+ gridsGetTable
55
+ } = require("./grids");
52
56
const {
53
57
storageGetBucket, storageUpdateBucket, storageCreateBucket
54
58
} = require("./storage");
@@ -919,6 +923,7 @@ const pushResources = async () => {
919
923
functions: pushFunction,
920
924
sites: pushSite,
921
925
collections: pushCollection,
926
+ tables: pushTable,
922
927
buckets: pushBucket,
923
928
teams: pushTeam,
924
929
messages: pushMessagingTopic
@@ -1672,7 +1677,150 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
1672
1677
}
1673
1678
}
1674
1679
1680
+ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1681
+ const tables = [];
1682
+
1683
+ if (attempts) {
1684
+ pollMaxDebounces = attempts;
1685
+ }
1686
+
1687
+ if (cliConfig.all) {
1688
+ checkDeployConditions(localConfig);
1689
+ tables.push(...localConfig.getTables());
1690
+ } else {
1691
+ const answers = await inquirer.prompt(questionsPushTables)
1692
+ if (answers.tables) {
1693
+ const configTables = new Map();
1694
+ localConfig.getTables().forEach((c) => {
1695
+ configTables.set(`${c['databaseId']}|${c['$id']}`, c);
1696
+ });
1697
+ answers.tables.forEach((a) => {
1698
+ const table = configTables.get(a);
1699
+ tables.push(table);
1700
+ })
1701
+ }
1702
+ }
1703
+
1704
+ if (tables.length === 0) {
1705
+ log("No tables found.");
1706
+ hint("Use 'appwrite pull tables' to synchronize existing one, or use 'appwrite init table' to create a new one.");
1707
+ return;
1708
+ }
1709
+
1710
+ const databases = Array.from(new Set(tables.map(table => table['databaseId'])));
1711
+
1712
+ // Parallel db actions
1713
+ await Promise.all(databases.map(async (databaseId) => {
1714
+ const localDatabase = localConfig.getDatabase(databaseId);
1715
+
1716
+ try {
1717
+ const database = await gridsGetDatabase({
1718
+ databaseId: databaseId,
1719
+ parseOutput: false,
1720
+ });
1721
+
1722
+ if (database.name !== (localDatabase.name ?? databaseId)) {
1723
+ await databasesUpdate({
1724
+ databaseId: databaseId,
1725
+ name: localDatabase.name ?? databaseId,
1726
+ parseOutput: false
1727
+ })
1728
+
1729
+ success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
1730
+ }
1731
+ } catch (err) {
1732
+ log(`Database ${databaseId} not found. Creating it now ...`);
1733
+
1734
+ await databasesCreate({
1735
+ databaseId: databaseId,
1736
+ name: localDatabase.name ?? databaseId,
1737
+ parseOutput: false,
1738
+ });
1739
+ }
1740
+ }));
1741
+
1742
+
1743
+ if (!(await approveChanges(tables, gridsGetTable, KeysTable, 'tableId', 'tables', ['columns', 'indexes'], 'databaseId', 'databaseId',))) {
1744
+ return;
1745
+ }
1746
+ // Parallel collection actions
1747
+ await Promise.all(tables.map(async (table) => {
1748
+ try {
1749
+ const remoteTable = await gridsGetTable({
1750
+ databaseId: table['databaseId'],
1751
+ tableId: table['$id'],
1752
+ parseOutput: false,
1753
+ });
1754
+
1755
+ if (remoteTable.name !== table.name) {
1756
+ await databasesUpdateTable({
1757
+ databaseId: table['databaseId'],
1758
+ tableId: table['$id'],
1759
+ name: table.name,
1760
+ name: table.name,
1761
+ parseOutput: false
1762
+ })
1763
+
1764
+ success(`Updated ${table.name} ( ${table['$id']} ) name`);
1765
+ }
1766
+ table.remoteVersion = remoteTable;
1767
+
1768
+ table.isExisted = true;
1769
+ } catch
1770
+ (e) {
1771
+ if (Number(e.code) === 404) {
1772
+ log(`Table ${table.name} does not exist in the project. Creating ... `);
1773
+ await databasesCreateTable({
1774
+ databaseId: table['databaseId'],
1775
+ tableId: table['$id'],
1776
+ name: table.name,
1777
+ documentSecurity: table.documentSecurity,
1778
+ permissions: table['$permissions'],
1779
+ parseOutput: false
1780
+ })
1781
+ } else {
1782
+ throw e;
1783
+ }
1784
+ }
1785
+ }))
1786
+ let numberOfTables = 0;
1787
+ // Serialize attribute actions
1788
+ for (let table of tables) {
1789
+ let columns = table.columns;
1790
+ let indexes = table.indexes;
1791
+
1792
+ if (table.isExisted) {
1793
+ columns = await attributesToCreate(table.remoteVersion.columns, table.columns, table);
1794
+ indexes = await attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
1795
+
1796
+ if ((Array.isArray(columns) && columns.length < = 0) && (Array.isArray(indexes) && indexes.length < = 0)) {
1797
+ continue;
1798
+ }
1799
+
1800
+ }
1801
+
1802
+ log(`Pushing table ${table.name} ( ${table['databaseId']} - ${table['$id']} ) attributes`)
1803
+
1804
+ try {
1805
+ await createAttributes(columns, table)
1806
+ } catch (e) {
1807
+ throw e;
1808
+ }
1809
+
1810
+ try {
1811
+ await createIndexes(indexes, table);
1812
+ } catch (e) {
1813
+ throw e;
1814
+ }
1815
+ numberOfTables++;
1816
+ success(`Successfully pushed ${table.name} ( ${table['$id']} )`);
1817
+ }
1818
+
1819
+ success(`Successfully pushed ${numberOfTables} tables`);
1820
+ }
1821
+
1675
1822
const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1823
+ warn("appwrite push collection has been deprecated. Please consider using 'appwrite push tables' instead");
1676
1824
const collections = [];
1677
1825
1678
1826
if (attempts) {
@@ -2083,10 +2231,17 @@ push
2083
2231
push
2084
2232
.command("collection")
2085
2233
.alias("collections")
2086
- .description("Push collections in the current project.")
2234
+ .description("Push collections in the current project. (deprecated, please use 'push tables' instead) ")
2087
2235
.option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
2088
2236
.action(actionRunner(pushCollection));
2089
2237
2238
+ push
2239
+ .command("table")
2240
+ .alias("tables")
2241
+ .description("Push tables in the current project.")
2242
+ .option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
2243
+ .action(actionRunner(pushTable));
2244
+
2090
2245
push
2091
2246
.command("bucket")
2092
2247
.alias("buckets")
0 commit comments