@@ -9,7 +9,7 @@ const ID = require("../id");
99const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection } = 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,9 @@ const {
4949 databasesListIndexes,
5050 databasesUpdateCollection
5151} = require("./databases");
52+ const {
53+ gridsGetDatabase
54+ } = require("./grids");
5255const {
5356 storageGetBucket, storageUpdateBucket, storageCreateBucket
5457} = require("./storage");
@@ -1672,7 +1675,150 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
16721675 }
16731676}
16741677
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+
16751820const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1821+ warn("⚠️ DEPRECATED: Use 'appwrite push table' instead. This command might be removed in the future");
16761822 const collections = [];
16771823
16781824 if (attempts) {
@@ -2080,6 +2226,13 @@ push
20802226 .option("--with-variables", `Push site variables.`)
20812227 .action(actionRunner(pushSite));
20822228
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+
20832236push
20842237 .command("collection")
20852238 .alias("collections")
0 commit comments