@@ -6,10 +6,10 @@ const inquirer = require("inquirer");
66const JSONbig = require("json-bigint")({ storeAsString: false });
77const { Command } = require("commander");
88const 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");
1010const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
1111const { 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");
1313const { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable } = require("../parser");
1414const { proxyCreateFunctionRule, proxyCreateSiteRule, proxyListRules } = require('./proxy');
1515const { consoleVariables } = require('./console');
@@ -49,6 +49,10 @@ const {
4949 databasesListIndexes,
5050 databasesUpdateCollection
5151} = require("./databases");
52+ const {
53+ gridsGetDatabase,
54+ gridsGetTable
55+ } = require("./grids");
5256const {
5357 storageGetBucket, storageUpdateBucket, storageCreateBucket
5458} = require("./storage");
@@ -919,6 +923,7 @@ const pushResources = async () => {
919923 functions: pushFunction,
920924 sites: pushSite,
921925 collections: pushCollection,
926+ tables: pushTable,
922927 buckets: pushBucket,
923928 teams: pushTeam,
924929 messages: pushMessagingTopic
@@ -1672,7 +1677,150 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
16721677 }
16731678}
16741679
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+
16751822const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1823+ warn("appwrite push collection has been deprecated. Please consider using 'appwrite push tables' instead");
16761824 const collections = [];
16771825
16781826 if (attempts) {
@@ -2083,10 +2231,17 @@ push
20832231push
20842232 .command("collection")
20852233 .alias("collections")
2086- .description("Push collections in the current project.")
2234+ .description("Push collections in the current project. (deprecated, please use 'push tables' instead) ")
20872235 .option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
20882236 .action(actionRunner(pushCollection));
20892237
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+
20902245push
20912246 .command("bucket")
20922247 .alias("buckets")
0 commit comments