Skip to content

Commit

Permalink
Ensure --force-reset drops previous tables (#10506)
Browse files Browse the repository at this point in the history
* Ensure --force-reset drops previous tables

* Remove unused import

* Do suggestions
  • Loading branch information
matthewp authored Mar 20, 2024
1 parent fdceed5 commit 980020c
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/large-trees-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/db": patch
---

Ensure --force-reset drops previous tables
3 changes: 2 additions & 1 deletion packages/db/src/core/cli/commands/push/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ export async function cmd({
const appToken = await getManagedAppTokenOrExit(flags.token);
const productionSnapshot = await getProductionCurrentSnapshot({ appToken: appToken.token });
const currentSnapshot = createCurrentSnapshot(dbConfig);
const isFromScratch = isForceReset || !productionSnapshot;
const isFromScratch = !productionSnapshot;
const { queries: migrationQueries, confirmations } = await getMigrationQueries({
oldSnapshot: isFromScratch ? createEmptySnapshot() : productionSnapshot,
newSnapshot: currentSnapshot,
reset: isForceReset
});

// // push the database schema
Expand Down
20 changes: 20 additions & 0 deletions packages/db/src/core/cli/migration-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,23 @@ const genTempTableName = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
export async function getMigrationQueries({
oldSnapshot,
newSnapshot,
reset = false
}: {
oldSnapshot: DBSnapshot;
newSnapshot: DBSnapshot;
reset?: boolean;
}): Promise<{ queries: string[]; confirmations: string[] }> {
const queries: string[] = [];
const confirmations: string[] = [];

// When doing a reset, first create DROP TABLE statements, then treat everything
// else as creation.
if(reset) {
const currentSnapshot = oldSnapshot;
oldSnapshot = createEmptySnapshot();
queries.push(...getDropTableQueriesForSnapshot(currentSnapshot));
}

const addedCollections = getAddedCollections(oldSnapshot, newSnapshot);
const droppedTables = getDroppedCollections(oldSnapshot, newSnapshot);
const notDeprecatedDroppedTables = Object.fromEntries(
Expand Down Expand Up @@ -449,6 +460,15 @@ export async function getProductionCurrentSnapshot({
return result.data;
}

function getDropTableQueriesForSnapshot(snapshot: DBSnapshot) {
const queries = [];
for(const collectionName of Object.keys(snapshot.schema)) {
const dropQuery = `DROP TABLE ${sqlite.escapeName(collectionName)}`;
queries.unshift(dropQuery);
}
return queries;
}

export function createCurrentSnapshot({ tables = {} }: DBConfig): DBSnapshot {
const schema = JSON.parse(JSON.stringify(tables));
return { version: MIGRATION_VERSION, schema };
Expand Down
56 changes: 56 additions & 0 deletions packages/db/test/unit/reset-queries.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { expect } from 'chai';
import { describe, it } from 'mocha';
import {
getMigrationQueries,
} from '../../dist/core/cli/migration-queries.js';
import { MIGRATION_VERSION } from '../../dist/core/consts.js';
import { tableSchema } from '../../dist/core/schemas.js';
import { column, defineTable } from '../../dist/runtime/config.js';

const TABLE_NAME = 'Users';

// `parse` to resolve schema transformations
// ex. convert column.date() to ISO strings
const userInitial = tableSchema.parse(
defineTable({
columns: {
name: column.text(),
age: column.number(),
email: column.text({ unique: true }),
mi: column.text({ optional: true }),
},
})
);

describe('force reset', () => {
describe('getMigrationQueries', () => {
it('should drop table and create new version', async () => {
const oldCollections = { [TABLE_NAME]: userInitial };
const newCollections = { [TABLE_NAME]: userInitial };
const { queries } = await getMigrationQueries({
oldSnapshot: { schema: oldCollections, version: MIGRATION_VERSION },
newSnapshot: { schema: newCollections, version: MIGRATION_VERSION },
reset: true,
});

expect(queries).to.deep.equal([
`DROP TABLE "${TABLE_NAME}"`,
`CREATE TABLE "${TABLE_NAME}" (_id INTEGER PRIMARY KEY, "name" text NOT NULL, "age" integer NOT NULL, "email" text NOT NULL UNIQUE, "mi" text)`,
]);
});

it('should not drop table when previous snapshot did not have it', async () => {
const oldCollections = {};
const newCollections = { [TABLE_NAME]: userInitial };
const { queries } = await getMigrationQueries({
oldSnapshot: { schema: oldCollections, version: MIGRATION_VERSION },
newSnapshot: { schema: newCollections, version: MIGRATION_VERSION },
reset: true,
});

expect(queries).to.deep.equal([
`CREATE TABLE "${TABLE_NAME}" (_id INTEGER PRIMARY KEY, "name" text NOT NULL, "age" integer NOT NULL, "email" text NOT NULL UNIQUE, "mi" text)`,
]);
});
});
});

0 comments on commit 980020c

Please sign in to comment.