mirror of
https://github.com/withastro/astro.git
synced 2025-03-03 22:57:08 -05:00
cleanup primary key support, db push
This commit is contained in:
parent
f249be392f
commit
2c897aea2a
3 changed files with 23 additions and 31 deletions
|
@ -7,13 +7,14 @@ import type { Arguments } from 'yargs-parser';
|
|||
import { appTokenError } from '../../../errors.js';
|
||||
import { collectionToTable, createLocalDatabaseClient } from '../../../internal.js';
|
||||
import {
|
||||
createCurrentSnapshot,
|
||||
createEmptySnapshot,
|
||||
getMigrations,
|
||||
initializeFromMigrations,
|
||||
loadInitialSnapshot,
|
||||
loadMigration,
|
||||
} from '../../../migrations.js';
|
||||
import type { DBCollections } from '../../../types.js';
|
||||
import type { DBCollections, DBSnapshot } from '../../../types.js';
|
||||
import {
|
||||
STUDIO_ADMIN_TABLE_ROW_ID,
|
||||
adminTable,
|
||||
|
@ -30,9 +31,7 @@ export async function cmd({ config, flags }: { config: AstroConfig; flags: Argum
|
|||
const isSeedData = flags.seed;
|
||||
const isDryRun = flags.dryRun;
|
||||
const appToken = flags.token ?? getAstroStudioEnv().ASTRO_STUDIO_APP_TOKEN;
|
||||
|
||||
const currentDb: DBCollections = (config.db?.collections ?? {}) as DBCollections;
|
||||
const currentSnapshot = JSON.parse(JSON.stringify(currentDb));
|
||||
const currentSnapshot = createCurrentSnapshot(config);
|
||||
const allMigrationFiles = await getMigrations();
|
||||
if (allMigrationFiles.length === 0) {
|
||||
console.log('Project not yet initialized!');
|
||||
|
@ -43,6 +42,7 @@ export async function cmd({ config, flags }: { config: AstroConfig; flags: Argum
|
|||
const calculatedDiff = diff(prevSnapshot, currentSnapshot);
|
||||
if (calculatedDiff) {
|
||||
console.log('Changes detected!');
|
||||
console.log(calculatedDiff);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ export async function cmd({ config, flags }: { config: AstroConfig; flags: Argum
|
|||
}
|
||||
if (isSeedData) {
|
||||
console.info('Pushing data...');
|
||||
await tempDataPush({ currentDb, appToken, isDryRun });
|
||||
await pushData({ config, appToken, isDryRun });
|
||||
}
|
||||
console.info('Push complete!');
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ async function pushSchema({
|
|||
appToken: string;
|
||||
isDryRun: boolean;
|
||||
db: ReturnType<typeof createRemoteDatabaseClient>;
|
||||
currentSnapshot: DBCollections;
|
||||
currentSnapshot: DBSnapshot;
|
||||
}) {
|
||||
// load all missing migrations
|
||||
const initialSnapshot = migrations.find((m) => m === '0000_snapshot.json');
|
||||
|
@ -120,28 +120,26 @@ async function pushSchema({
|
|||
}
|
||||
|
||||
/** TODO: refine with migration changes */
|
||||
async function tempDataPush({
|
||||
currentDb,
|
||||
async function pushData({
|
||||
config,
|
||||
appToken,
|
||||
isDryRun,
|
||||
}: {
|
||||
currentDb: DBCollections;
|
||||
config: AstroConfig;
|
||||
appToken: string;
|
||||
isDryRun?: boolean;
|
||||
}) {
|
||||
const db = await createLocalDatabaseClient({
|
||||
collections: JSON.parse(JSON.stringify(currentDb)),
|
||||
collections: config.db!.collections! as DBCollections,
|
||||
dbUrl: ':memory:',
|
||||
seeding: true,
|
||||
});
|
||||
const queries: Query[] = [];
|
||||
|
||||
for (const [name, collection] of Object.entries(currentDb)) {
|
||||
console.log(name, collection);
|
||||
for (const [name, collection] of Object.entries(config.db!.collections! as DBCollections)) {
|
||||
if (collection.writable || !collection.data) continue;
|
||||
const table = collectionToTable(name, collection);
|
||||
const insert = db.insert(table).values(await collection.data());
|
||||
|
||||
queries.push(insert.toSQL());
|
||||
}
|
||||
console.log(queries);
|
||||
|
|
|
@ -15,6 +15,7 @@ import type {
|
|||
import { SQLiteAsyncDialect } from 'drizzle-orm/sqlite-core';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import prompts from 'prompts';
|
||||
import { hasPrimaryKey } from '../internal.js';
|
||||
|
||||
const sqlite = new SQLiteAsyncDialect();
|
||||
const genTempTableName = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
|
||||
|
@ -408,7 +409,7 @@ export function getCreateTableQuery(collectionName: string, collection: DBCollec
|
|||
([, field]) => hasPrimaryKey(field)
|
||||
);
|
||||
if (!colHasPrimaryKey) {
|
||||
colQueries.push('_id INTEGER PRIMARY KEY AUTOINCREMENT');
|
||||
colQueries.push('_id INTEGER PRIMARY KEY');
|
||||
}
|
||||
for (const [columnName, column] of Object.entries(collection.fields)) {
|
||||
const colQuery = `${sqlite.escapeName(columnName)} ${schemaTypeToSqlType(
|
||||
|
@ -570,10 +571,6 @@ type DBFieldWithDefault =
|
|||
| WithDefaultDefined<BooleanField>
|
||||
| WithDefaultDefined<JsonField>;
|
||||
|
||||
function hasPrimaryKey(field: DBField) {
|
||||
return 'primaryKey' in field && !!field.primaryKey;
|
||||
}
|
||||
|
||||
// Type narrowing the default fails on union types, so use a type guard
|
||||
function hasDefault(field: DBField): field is DBFieldWithDefault {
|
||||
if (field.default !== undefined) {
|
||||
|
|
|
@ -39,6 +39,10 @@ export type { Table } from './types.js';
|
|||
|
||||
const sqlite = new SQLiteAsyncDialect();
|
||||
|
||||
export function hasPrimaryKey(field: DBField) {
|
||||
return 'primaryKey' in field && !!field.primaryKey;
|
||||
}
|
||||
|
||||
function isReadableCollection(collection: DBCollection): collection is ReadableDBCollection {
|
||||
return !collection.writable;
|
||||
}
|
||||
|
@ -232,12 +236,6 @@ const jsonType = customType<{ data: unknown; driverData: string }>({
|
|||
},
|
||||
});
|
||||
|
||||
const initialColumns = {
|
||||
id: text('id')
|
||||
.primaryKey()
|
||||
.$default(() => generateId()),
|
||||
};
|
||||
|
||||
type D1ColumnBuilder = SQLiteColumnBuilderBase<
|
||||
ColumnBuilderBaseConfig<ColumnDataType, string> & { data: unknown }
|
||||
>;
|
||||
|
@ -247,17 +245,14 @@ export function collectionToTable(
|
|||
collection: DBCollection,
|
||||
isJsonSerializable = true
|
||||
) {
|
||||
const columns: Record<string, D1ColumnBuilder> & typeof initialColumns = {
|
||||
// Spread to avoid mutating `initialColumns`
|
||||
...initialColumns,
|
||||
};
|
||||
|
||||
const columns: Record<string, D1ColumnBuilder> = {};
|
||||
if (!Object.entries(collection.fields).some(([, field]) => hasPrimaryKey(field))) {
|
||||
columns['_id'] = integer('_id').primaryKey();
|
||||
}
|
||||
for (const [fieldName, field] of Object.entries(collection.fields)) {
|
||||
columns[fieldName] = columnMapper(fieldName, field, isJsonSerializable);
|
||||
}
|
||||
|
||||
const table = sqliteTable(name, columns);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
|
@ -276,11 +271,13 @@ function columnMapper(fieldName: string, field: DBField, isJsonSerializable: boo
|
|||
// Duplicate default logic across cases to preserve type inference.
|
||||
// No clean generic for every column builder.
|
||||
if (field.default !== undefined) c = c.default(field.default);
|
||||
if (field.primaryKey === true) c = c.primaryKey();
|
||||
break;
|
||||
}
|
||||
case 'number': {
|
||||
c = integer(fieldName);
|
||||
if (field.default !== undefined) c = c.default(field.default);
|
||||
if (field.primaryKey === true) c = c.primaryKey({autoIncrement: true});
|
||||
break;
|
||||
}
|
||||
case 'boolean': {
|
||||
|
|
Loading…
Add table
Reference in a new issue