@@ -55,7 +55,10 @@ const {
5555 tablesDBUpdate,
5656 tablesDBCreateTable,
5757 tablesDBGetTable,
58- tablesDBUpdateTable
58+ tablesDBUpdateTable,
59+ tablesDBList,
60+ tablesDBDelete,
61+ tablesDBListTables
5962} = require ( "./tables-db" ) ;
6063const {
6164 storageGetBucket, storageUpdateBucket, storageCreateBucket
@@ -1700,13 +1703,173 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
17001703 }
17011704}
17021705
1706+ const checkAndApplyTablesDBChanges = async ( ) => {
1707+ log ( 'Checking for tablesDB changes ...' ) ;
1708+
1709+ const localTablesDBs = localConfig . getTablesDBs ( ) ;
1710+ const { databases : remoteTablesDBs } = await paginate ( tablesDBList , { parseOutput : false } , 100 , 'databases' ) ;
1711+
1712+ if ( localTablesDBs . length === 0 && remoteTablesDBs . length === 0 ) {
1713+ return { applied : false , resyncNeeded : false } ;
1714+ }
1715+
1716+ const changes = [ ] ;
1717+ const toCreate = [ ] ;
1718+ const toUpdate = [ ] ;
1719+ const toDelete = [ ] ;
1720+
1721+ // Check for deletions - remote DBs that aren't in local config
1722+ for ( const remoteDB of remoteTablesDBs ) {
1723+ const localDB = localTablesDBs . find ( db => db . $id === remoteDB . $id ) ;
1724+ if ( ! localDB ) {
1725+ toDelete . push ( remoteDB ) ;
1726+ changes . push ( {
1727+ id : remoteDB . $id ,
1728+ key : 'Database' ,
1729+ remote : chalk . red ( `${ remoteDB . name } (${ remoteDB . $id } )` ) ,
1730+ local : chalk . green ( '(deleted locally)' )
1731+ } ) ;
1732+ }
1733+ }
1734+
1735+ // Check for additions and updates
1736+ for ( const localDB of localTablesDBs ) {
1737+ const remoteDB = remoteTablesDBs . find ( db => db . $id === localDB . $id ) ;
1738+
1739+ if ( ! remoteDB ) {
1740+ toCreate . push ( localDB ) ;
1741+ changes . push ( {
1742+ id : localDB . $id ,
1743+ key : 'Database' ,
1744+ remote : chalk . red ( '(does not exist)' ) ,
1745+ local : chalk . green ( `${ localDB . name } (${ localDB . $id } )` )
1746+ } ) ;
1747+ } else {
1748+ let hasChanges = false ;
1749+
1750+ if ( remoteDB . name !== localDB . name ) {
1751+ hasChanges = true ;
1752+ changes . push ( {
1753+ id : localDB . $id ,
1754+ key : 'Name' ,
1755+ remote : chalk . red ( remoteDB . name ) ,
1756+ local : chalk . green ( localDB . name )
1757+ } ) ;
1758+ }
1759+
1760+ if ( remoteDB . enabled !== localDB . enabled ) {
1761+ hasChanges = true ;
1762+ changes . push ( {
1763+ id : localDB . $id ,
1764+ key : 'Enabled?' ,
1765+ remote : chalk . red ( remoteDB . enabled ) ,
1766+ local : chalk . green ( localDB . enabled )
1767+ } ) ;
1768+ }
1769+
1770+ if ( hasChanges ) {
1771+ toUpdate . push ( localDB ) ;
1772+ }
1773+ }
1774+ }
1775+
1776+ if ( changes . length === 0 ) {
1777+ return { applied : false , resyncNeeded : false } ;
1778+ }
1779+
1780+ log ( 'Found changes in tablesDB resources:' ) ;
1781+ drawTable ( changes ) ;
1782+
1783+ if ( toDelete . length > 0 ) {
1784+ console . log ( `${ chalk . red ( '-------------------------------------------------------------------' ) } ` ) ;
1785+ console . log ( `${ chalk . red ( '| WARNING: Database deletion will also delete all related tables |' ) } ` ) ;
1786+ console . log ( `${ chalk . red ( '-------------------------------------------------------------------' ) } ` ) ;
1787+ }
1788+
1789+ if ( ( await getConfirmation ( ) ) !== true ) {
1790+ return { applied : false , resyncNeeded : false } ;
1791+ }
1792+
1793+ // Apply deletions first
1794+ let needsResync = false ;
1795+ for ( const db of toDelete ) {
1796+ try {
1797+ log ( `Deleting database ${ db . name } ( ${ db . $id } ) ...` ) ;
1798+ await tablesDBDelete ( {
1799+ databaseId : db . $id ,
1800+ parseOutput : false
1801+ } ) ;
1802+ success ( `Deleted ${ db . name } ( ${ db . $id } )` ) ;
1803+ needsResync = true ;
1804+ } catch ( e ) {
1805+ error ( `Failed to delete database ${ db . name } ( ${ db . $id } ): ${ e . message } ` ) ;
1806+ throw new Error ( `Database sync failed during deletion of ${ db . $id } . Some changes may have been applied.` ) ;
1807+ }
1808+ }
1809+
1810+ // Apply creations
1811+ for ( const db of toCreate ) {
1812+ try {
1813+ log ( `Creating database ${ db . name } ( ${ db . $id } ) ...` ) ;
1814+ await tablesDBCreate ( {
1815+ databaseId : db . $id ,
1816+ name : db . name ,
1817+ enabled : db . enabled ,
1818+ parseOutput : false
1819+ } ) ;
1820+ success ( `Created ${ db . name } ( ${ db . $id } )` ) ;
1821+ } catch ( e ) {
1822+ error ( `Failed to create database ${ db . name } ( ${ db . $id } ): ${ e . message } ` ) ;
1823+ throw new Error ( `Database sync failed during creation of ${ db . $id } . Some changes may have been applied.` ) ;
1824+ }
1825+ }
1826+
1827+ // Apply updates
1828+ for ( const db of toUpdate ) {
1829+ try {
1830+ log ( `Updating database ${ db . name } ( ${ db . $id } ) ...` ) ;
1831+ await tablesDBUpdate ( {
1832+ databaseId : db . $id ,
1833+ name : db . name ,
1834+ enabled : db . enabled ,
1835+ parseOutput : false
1836+ } ) ;
1837+ success ( `Updated ${ db . name } ( ${ db . $id } )` ) ;
1838+ } catch ( e ) {
1839+ error ( `Failed to update database ${ db . name } ( ${ db . $id } ): ${ e . message } ` ) ;
1840+ throw new Error ( `Database sync failed during update of ${ db . $id } . Some changes may have been applied.` ) ;
1841+ }
1842+ }
1843+
1844+ return { applied : true , resyncNeeded : needsResync } ;
1845+ } ;
1846+
17031847const pushTable = async ( { returnOnZero, attempts } = { returnOnZero : false } ) => {
17041848 const tables = [ ] ;
17051849
17061850 if ( attempts ) {
17071851 pollMaxDebounces = attempts ;
17081852 }
17091853
1854+ const { applied : tablesDBApplied , resyncNeeded } = await checkAndApplyTablesDBChanges ( ) ;
1855+ if ( resyncNeeded ) {
1856+ log ( 'Resyncing configuration due to tablesDB deletions ...' ) ;
1857+
1858+ const remoteTablesDBs = ( await paginate ( tablesDBList , { parseOutput : false } , 100 , 'databases' ) ) . databases ;
1859+ const localTablesDBs = localConfig . getTablesDBs ( ) ;
1860+
1861+ const remoteDatabaseIds = new Set ( remoteTablesDBs . map ( db => db . $id ) ) ;
1862+ const localTables = localConfig . getTables ( ) ;
1863+ const validTables = localTables . filter ( table => remoteDatabaseIds . has ( table . databaseId ) ) ;
1864+
1865+ localConfig . set ( 'tables' , validTables ) ;
1866+
1867+ const validTablesDBs = localTablesDBs . filter ( db => remoteDatabaseIds . has ( db . $id ) ) ;
1868+ localConfig . set ( 'tablesDB' , validTablesDBs ) ;
1869+
1870+ success ( 'Configuration resynced successfully.' ) ;
1871+ }
1872+
17101873 if ( cliConfig . all ) {
17111874 checkDeployConditions ( localConfig ) ;
17121875 tables . push ( ...localConfig . getTables ( ) ) ;
@@ -1730,39 +1893,6 @@ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) =
17301893 return ;
17311894 }
17321895
1733- const databases = Array . from ( new Set ( tables . map ( table => table [ 'databaseId' ] ) ) ) ;
1734-
1735- // Parallel tablesDB actions
1736- await Promise . all ( databases . map ( async ( databaseId ) => {
1737- const localDatabase = localConfig . getTablesDB ( databaseId ) ;
1738-
1739- try {
1740- const database = await tablesDBGet ( {
1741- databaseId : databaseId ,
1742- parseOutput : false ,
1743- } ) ;
1744-
1745- if ( database . name !== ( localDatabase . name ?? databaseId ) ) {
1746- await tablesDBUpdate ( {
1747- databaseId : databaseId ,
1748- name : localDatabase . name ?? databaseId ,
1749- parseOutput : false
1750- } )
1751-
1752- success ( `Updated ${ localDatabase . name } ( ${ databaseId } ) name` ) ;
1753- }
1754- } catch ( err ) {
1755- log ( `Database ${ databaseId } not found. Creating it now ...` ) ;
1756-
1757- await tablesDBCreate ( {
1758- databaseId : databaseId ,
1759- name : localDatabase . name ?? databaseId ,
1760- parseOutput : false ,
1761- } ) ;
1762- }
1763- } ) ) ;
1764-
1765-
17661896 if ( ! ( await approveChanges ( tables , tablesDBGetTable , KeysTable , 'tableId' , 'tables' , [ 'columns' , 'indexes' ] , 'databaseId' , 'databaseId' ) ) ) {
17671897 return ;
17681898 }
0 commit comments