@@ -9,7 +9,7 @@ const ID = require("../id");
9
9
const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection } = 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,9 @@ const {
49
49
databasesListIndexes,
50
50
databasesUpdateCollection
51
51
} = require("./databases");
52
+ const {
53
+ gridsGetDatabase
54
+ } = require("./grids");
52
55
const {
53
56
storageGetBucket, storageUpdateBucket, storageCreateBucket
54
57
} = require("./storage");
@@ -1672,7 +1675,150 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
1672
1675
}
1673
1676
}
1674
1677
1678
+ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1679
+ const tables = [];
1680
+
1681
+ if (attempts) {
1682
+ pollMaxDebounces = attempts;
1683
+ }
1684
+
1685
+ if (cliConfig.all) {
1686
+ checkDeployConditions(localConfig);
1687
+ tables.push(...localConfig.getTables());
1688
+ } else {
1689
+ const answers = await inquirer.prompt(questionsPushTables)
1690
+ if (answers.tables) {
1691
+ const configTables = new Map();
1692
+ localConfig.getTables().forEach((c) => {
1693
+ configTables.set(`${c['databaseId']}|${c['$id']}`, c);
1694
+ });
1695
+ answers.tables.forEach((a) => {
1696
+ const table = configTables.get(a);
1697
+ tables.push(table);
1698
+ })
1699
+ }
1700
+ }
1701
+
1702
+ if (tables.length === 0) {
1703
+ log("No tables found.");
1704
+ hint("Use 'appwrite pull tables' to synchronize existing one, or use 'appwrite init table' to create a new one.");
1705
+ return;
1706
+ }
1707
+
1708
+ const databases = Array.from(new Set(tables.map(table => table['databaseId'])));
1709
+
1710
+ // Parallel db actions
1711
+ await Promise.all(databases.map(async (databaseId) => {
1712
+ const localDatabase = localConfig.getDatabase(databaseId);
1713
+
1714
+ try {
1715
+ const database = await gridsGetDatabase({
1716
+ databaseId: databaseId,
1717
+ parseOutput: false,
1718
+ });
1719
+
1720
+ if (database.name !== (localDatabase.name ?? databaseId)) {
1721
+ await databasesUpdate({
1722
+ databaseId: databaseId,
1723
+ name: localDatabase.name ?? databaseId,
1724
+ parseOutput: false
1725
+ })
1726
+
1727
+ success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
1728
+ }
1729
+ } catch (err) {
1730
+ log(`Database ${databaseId} not found. Creating it now ...`);
1731
+
1732
+ await databasesCreate({
1733
+ databaseId: databaseId,
1734
+ name: localDatabase.name ?? databaseId,
1735
+ parseOutput: false,
1736
+ });
1737
+ }
1738
+ }));
1739
+
1740
+
1741
+ if (!(await approveChanges(tables, databasesGetTable, KeysTable, 'tableId', 'tables', ['attributes', 'indexes'], 'databaseId', 'databaseId',))) {
1742
+ return;
1743
+ }
1744
+ // Parallel collection actions
1745
+ await Promise.all(tables.map(async (table) => {
1746
+ try {
1747
+ const remoteTable = await databasesGetTable({
1748
+ databaseId: table['databaseId'],
1749
+ tableId: table['$id'],
1750
+ parseOutput: false,
1751
+ });
1752
+
1753
+ if (remoteTable.name !== table.name) {
1754
+ await databasesUpdateTable({
1755
+ databaseId: table['databaseId'],
1756
+ tableId: table['$id'],
1757
+ name: table.name,
1758
+ name: table.name,
1759
+ parseOutput: false
1760
+ })
1761
+
1762
+ success(`Updated ${table.name} ( ${table['$id']} ) name`);
1763
+ }
1764
+ table.remoteVersion = remoteTable;
1765
+
1766
+ table.isExisted = true;
1767
+ } catch
1768
+ (e) {
1769
+ if (Number(e.code) === 404) {
1770
+ log(`Table ${table.name} does not exist in the project. Creating ... `);
1771
+ await databasesCreateTable({
1772
+ databaseId: table['databaseId'],
1773
+ tableId: table['$id'],
1774
+ name: table.name,
1775
+ documentSecurity: table.documentSecurity,
1776
+ permissions: table['$permissions'],
1777
+ parseOutput: false
1778
+ })
1779
+ } else {
1780
+ throw e;
1781
+ }
1782
+ }
1783
+ }))
1784
+ let numberOfTables = 0;
1785
+ // Serialize attribute actions
1786
+ for (let table of tables) {
1787
+ let attributes = table.attributes;
1788
+ let indexes = table.indexes;
1789
+
1790
+ if (table.isExisted) {
1791
+ attributes = await attributesToCreate(table.remoteVersion.attributes, table.attributes, table);
1792
+ indexes = await attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
1793
+
1794
+ if ((Array.isArray(attributes) && attributes.length < = 0) && (Array.isArray(indexes) && indexes.length < = 0)) {
1795
+ continue;
1796
+ }
1797
+
1798
+ }
1799
+
1800
+ log(`Pushing table ${table.name} ( ${table['databaseId']} - ${table['$id']} ) attributes`)
1801
+
1802
+ try {
1803
+ await createAttributes(attributes, table)
1804
+ } catch (e) {
1805
+ throw e;
1806
+ }
1807
+
1808
+ try {
1809
+ await createIndexes(indexes, table);
1810
+ } catch (e) {
1811
+ throw e;
1812
+ }
1813
+ numberOfTables++;
1814
+ success(`Successfully pushed ${table.name} ( ${table['$id']} )`);
1815
+ }
1816
+
1817
+ success(`Successfully pushed ${numberOfTables} tables`);
1818
+ }
1819
+
1675
1820
const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1821
+ warn("⚠️ DEPRECATED: Use 'appwrite push table' instead. This command might be removed in the future");
1676
1822
const collections = [];
1677
1823
1678
1824
if (attempts) {
@@ -2080,6 +2226,13 @@ push
2080
2226
.option("--with-variables", `Push site variables.`)
2081
2227
.action(actionRunner(pushSite));
2082
2228
2229
+ push
2230
+ .command("table")
2231
+ .alias("tables")
2232
+ .description("Push tables in the current project.")
2233
+ .option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
2234
+ .action(actionRunner(pushTable));
2235
+
2083
2236
push
2084
2237
.command("collection")
2085
2238
.alias("collections")
0 commit comments