Change table update strategy to full recreation every time
This commit is contained in:
parent
b46ff44dc7
commit
685d47d91f
135
dist/lib/sqlite/db-schema-manager.js
vendored
135
dist/lib/sqlite/db-schema-manager.js
vendored
@ -102,7 +102,9 @@ class SQLiteSchemaManager {
|
|||||||
* Create a new table
|
* Create a new table
|
||||||
*/
|
*/
|
||||||
async createTable(table) {
|
async createTable(table) {
|
||||||
console.log(`Creating table: ${table.tableName}`);
|
if (!table.tableName.match(/_temp_\d+$/)) {
|
||||||
|
console.log(`Creating table: ${table.tableName}`);
|
||||||
|
}
|
||||||
let new_table = _.cloneDeep(table);
|
let new_table = _.cloneDeep(table);
|
||||||
if (new_table.parentTableName) {
|
if (new_table.parentTableName) {
|
||||||
const parent_table = this.db_schema.tables.find((t) => t.tableName === new_table.parentTableName);
|
const parent_table = this.db_schema.tables.find((t) => t.tableName === new_table.parentTableName);
|
||||||
@ -148,26 +150,42 @@ class SQLiteSchemaManager {
|
|||||||
*/
|
*/
|
||||||
async updateTable(table) {
|
async updateTable(table) {
|
||||||
console.log(`Updating table: ${table.tableName}`);
|
console.log(`Updating table: ${table.tableName}`);
|
||||||
const existingColumns = this.getTableColumns(table.tableName);
|
// const existingColumns = this.getTableColumns(table.tableName);
|
||||||
const schemaColumns = table.fields.map((f) => f.fieldName || "");
|
// const schemaColumns = table.fields.map((f) => f.fieldName || "");
|
||||||
// SQLite has limited ALTER TABLE support
|
// // SQLite has limited ALTER TABLE support
|
||||||
// We need to use the recreation strategy for complex changes
|
// // We need to use the recreation strategy for complex changes
|
||||||
const columnsToAdd = table.fields.filter((f) => f.fieldName &&
|
// const columnsToAdd = table.fields.filter(
|
||||||
!existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f)));
|
// (f) =>
|
||||||
const columnsToRemove = existingColumns.filter((c) => !schemaColumns.includes(c.name));
|
// f.fieldName &&
|
||||||
const columnsToUpdate = table.fields.filter((f) => f.fieldName &&
|
// !existingColumns.find(
|
||||||
f.updatedField &&
|
// (c) =>
|
||||||
existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f)));
|
// c.name == f.fieldName && c.type == this.mapDataType(f),
|
||||||
// Simple case: only adding columns
|
// ),
|
||||||
if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) {
|
// );
|
||||||
for (const field of columnsToAdd) {
|
// // const columnsToRemove = existingColumns.filter(
|
||||||
await this.addColumn(table.tableName, field);
|
// // (c) => !schemaColumns.includes(c.name),
|
||||||
}
|
// // );
|
||||||
}
|
// // const columnsToUpdate = table.fields.filter(
|
||||||
else {
|
// // (f) =>
|
||||||
// Complex case: need to recreate table
|
// // f.fieldName &&
|
||||||
await this.recreateTable(table);
|
// // f.updatedField &&
|
||||||
}
|
// // existingColumns.find(
|
||||||
|
// // (c) =>
|
||||||
|
// // c.name == f.fieldName && c.type == this.mapDataType(f),
|
||||||
|
// // ),
|
||||||
|
// // );
|
||||||
|
// for (const field of columnsToAdd) {
|
||||||
|
// await this.addColumn(table.tableName, field);
|
||||||
|
// }
|
||||||
|
// // // Simple case: only adding columns
|
||||||
|
// // if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) {
|
||||||
|
// // for (const field of columnsToAdd) {
|
||||||
|
// // await this.addColumn(table.tableName, field);
|
||||||
|
// // }
|
||||||
|
// // } else {
|
||||||
|
// // // Complex case: need to recreate table
|
||||||
|
// // }
|
||||||
|
await this.recreateTable(table);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Get existing columns for a table
|
* Get existing columns for a table
|
||||||
@ -382,79 +400,4 @@ class SQLiteSchemaManager {
|
|||||||
this.db.close();
|
this.db.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Example usage
|
|
||||||
async function main() {
|
|
||||||
const schema = {
|
|
||||||
dbName: "example_db",
|
|
||||||
tables: [
|
|
||||||
{
|
|
||||||
tableName: "users",
|
|
||||||
tableDescription: "User accounts",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldName: "id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "username",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "email",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "created_at",
|
|
||||||
dataType: "TEXT",
|
|
||||||
defaultValueLiteral: "CURRENT_TIMESTAMP",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
indexes: [
|
|
||||||
{
|
|
||||||
indexName: "idx_users_email",
|
|
||||||
indexType: "regular",
|
|
||||||
indexTableFields: [
|
|
||||||
{ value: "email", dataType: "TEXT" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "posts",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldName: "id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "user_id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
notNullValue: true,
|
|
||||||
foreignKey: {
|
|
||||||
destinationTableName: "users",
|
|
||||||
destinationTableColumnName: "id",
|
|
||||||
cascadeDelete: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "title",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "content",
|
|
||||||
dataType: "TEXT",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
export { SQLiteSchemaManager };
|
export { SQLiteSchemaManager };
|
||||||
|
|||||||
1
dist/types/index.d.ts
vendored
1
dist/types/index.d.ts
vendored
@ -110,7 +110,6 @@ export type BUN_SQLITE_FieldSchemaType = {
|
|||||||
fieldName?: string;
|
fieldName?: string;
|
||||||
fieldDescription?: string;
|
fieldDescription?: string;
|
||||||
originName?: string;
|
originName?: string;
|
||||||
updatedField?: boolean;
|
|
||||||
dataType: (typeof BUN_SQLITE_DATATYPES)[number]["value"];
|
dataType: (typeof BUN_SQLITE_DATATYPES)[number]["value"];
|
||||||
nullValue?: boolean;
|
nullValue?: boolean;
|
||||||
notNullValue?: boolean;
|
notNullValue?: boolean;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@moduletrace/bun-sqlite",
|
"name": "@moduletrace/bun-sqlite",
|
||||||
"version": "1.0.19",
|
"version": "1.0.20",
|
||||||
"description": "SQLite manager for Bun",
|
"description": "SQLite manager for Bun",
|
||||||
"author": "Benjamin Toby",
|
"author": "Benjamin Toby",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@ -155,7 +155,9 @@ class SQLiteSchemaManager {
|
|||||||
private async createTable(
|
private async createTable(
|
||||||
table: BUN_SQLITE_TableSchemaType,
|
table: BUN_SQLITE_TableSchemaType,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
console.log(`Creating table: ${table.tableName}`);
|
if (!table.tableName.match(/_temp_\d+$/)) {
|
||||||
|
console.log(`Creating table: ${table.tableName}`);
|
||||||
|
}
|
||||||
|
|
||||||
let new_table = _.cloneDeep(table);
|
let new_table = _.cloneDeep(table);
|
||||||
|
|
||||||
@ -225,42 +227,49 @@ class SQLiteSchemaManager {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
console.log(`Updating table: ${table.tableName}`);
|
console.log(`Updating table: ${table.tableName}`);
|
||||||
|
|
||||||
const existingColumns = this.getTableColumns(table.tableName);
|
// const existingColumns = this.getTableColumns(table.tableName);
|
||||||
const schemaColumns = table.fields.map((f) => f.fieldName || "");
|
// const schemaColumns = table.fields.map((f) => f.fieldName || "");
|
||||||
|
|
||||||
// SQLite has limited ALTER TABLE support
|
// // SQLite has limited ALTER TABLE support
|
||||||
// We need to use the recreation strategy for complex changes
|
// // We need to use the recreation strategy for complex changes
|
||||||
|
|
||||||
const columnsToAdd = table.fields.filter(
|
// const columnsToAdd = table.fields.filter(
|
||||||
(f) =>
|
// (f) =>
|
||||||
f.fieldName &&
|
// f.fieldName &&
|
||||||
!existingColumns.find(
|
// !existingColumns.find(
|
||||||
(c) =>
|
// (c) =>
|
||||||
c.name == f.fieldName && c.type == this.mapDataType(f),
|
// c.name == f.fieldName && c.type == this.mapDataType(f),
|
||||||
),
|
// ),
|
||||||
);
|
// );
|
||||||
const columnsToRemove = existingColumns.filter(
|
|
||||||
(c) => !schemaColumns.includes(c.name),
|
|
||||||
);
|
|
||||||
const columnsToUpdate = table.fields.filter(
|
|
||||||
(f) =>
|
|
||||||
f.fieldName &&
|
|
||||||
f.updatedField &&
|
|
||||||
existingColumns.find(
|
|
||||||
(c) =>
|
|
||||||
c.name == f.fieldName && c.type == this.mapDataType(f),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Simple case: only adding columns
|
// // const columnsToRemove = existingColumns.filter(
|
||||||
if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) {
|
// // (c) => !schemaColumns.includes(c.name),
|
||||||
for (const field of columnsToAdd) {
|
// // );
|
||||||
await this.addColumn(table.tableName, field);
|
|
||||||
}
|
// // const columnsToUpdate = table.fields.filter(
|
||||||
} else {
|
// // (f) =>
|
||||||
// Complex case: need to recreate table
|
// // f.fieldName &&
|
||||||
await this.recreateTable(table);
|
// // f.updatedField &&
|
||||||
}
|
// // existingColumns.find(
|
||||||
|
// // (c) =>
|
||||||
|
// // c.name == f.fieldName && c.type == this.mapDataType(f),
|
||||||
|
// // ),
|
||||||
|
// // );
|
||||||
|
|
||||||
|
// for (const field of columnsToAdd) {
|
||||||
|
// await this.addColumn(table.tableName, field);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // // Simple case: only adding columns
|
||||||
|
// // if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) {
|
||||||
|
// // for (const field of columnsToAdd) {
|
||||||
|
// // await this.addColumn(table.tableName, field);
|
||||||
|
// // }
|
||||||
|
// // } else {
|
||||||
|
// // // Complex case: need to recreate table
|
||||||
|
// // }
|
||||||
|
|
||||||
|
await this.recreateTable(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -558,80 +567,4 @@ class SQLiteSchemaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example usage
|
|
||||||
async function main() {
|
|
||||||
const schema: BUN_SQLITE_DatabaseSchemaType = {
|
|
||||||
dbName: "example_db",
|
|
||||||
tables: [
|
|
||||||
{
|
|
||||||
tableName: "users",
|
|
||||||
tableDescription: "User accounts",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldName: "id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "username",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "email",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "created_at",
|
|
||||||
dataType: "TEXT",
|
|
||||||
defaultValueLiteral: "CURRENT_TIMESTAMP",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
indexes: [
|
|
||||||
{
|
|
||||||
indexName: "idx_users_email",
|
|
||||||
indexType: "regular",
|
|
||||||
indexTableFields: [
|
|
||||||
{ value: "email", dataType: "TEXT" },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: "posts",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
fieldName: "id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
primaryKey: true,
|
|
||||||
autoIncrement: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "user_id",
|
|
||||||
dataType: "INTEGER",
|
|
||||||
notNullValue: true,
|
|
||||||
foreignKey: {
|
|
||||||
destinationTableName: "users",
|
|
||||||
destinationTableColumnName: "id",
|
|
||||||
cascadeDelete: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "title",
|
|
||||||
dataType: "TEXT",
|
|
||||||
notNullValue: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldName: "content",
|
|
||||||
dataType: "TEXT",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { SQLiteSchemaManager };
|
export { SQLiteSchemaManager };
|
||||||
|
|||||||
@ -111,7 +111,7 @@ export type BUN_SQLITE_FieldSchemaType = {
|
|||||||
fieldName?: string;
|
fieldName?: string;
|
||||||
fieldDescription?: string;
|
fieldDescription?: string;
|
||||||
originName?: string;
|
originName?: string;
|
||||||
updatedField?: boolean;
|
// updatedField?: boolean;
|
||||||
dataType: (typeof BUN_SQLITE_DATATYPES)[number]["value"];
|
dataType: (typeof BUN_SQLITE_DATATYPES)[number]["value"];
|
||||||
nullValue?: boolean;
|
nullValue?: boolean;
|
||||||
notNullValue?: boolean;
|
notNullValue?: boolean;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user