Skip to content

Commit

Permalink
always use returning statement if supported (#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal authored Oct 5, 2024
1 parent 76bc932 commit 3a4b309
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/components/gui/main-connection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function MainConnectionContainer() {
*/
useLayoutEffect(() => {
console.info("Injecting message into window object");
window.internalPubSub = new InternalPubSub();
if (!window.internalPubSub) window.internalPubSub = new InternalPubSub();
}, [driver]);

useEffect(() => {
Expand Down
5 changes: 4 additions & 1 deletion src/components/gui/query-result.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export default function QueryResult({
return { _tag: "EXPLAIN", value: result.result } as const;
}

const state = OptimizeTableState.createFromResult(result.result);
const state = OptimizeTableState.createFromResult(
databaseDriver,
result.result
);
state.setReadOnlyMode(true);
state.mismatchDetection = databaseDriver.getFlags().mismatchDetection;
return { _tag: "QUERY", value: state } as const;
Expand Down
12 changes: 7 additions & 5 deletions src/components/gui/table-optimized/OptimizeTableState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { selectArrayFromIndexList } from "@/components/lib/export-helper";
import { OptimizeTableHeaderProps } from ".";
import { LucideKey, LucideKeySquare, LucideSigma } from "lucide-react";
import {
BaseDriver,
DatabaseResultSet,
DatabaseTableSchema,
TableColumnDataType,
Expand Down Expand Up @@ -37,14 +38,19 @@ export default class OptimizeTableState {
protected changeLogs: Record<number, OptimizeTableRowValue> = {};

static createFromResult(
driver: BaseDriver,
dataResult: DatabaseResultSet,
schemaResult?: DatabaseTableSchema
) {
return new OptimizeTableState(
dataResult.headers.map((header) => {
const headerData = schemaResult
? schemaResult.columns.find((c) => c.name === header.name)
: undefined;

let initialSize = 150;
const headerName = header.name;
const dataType = header.type;
const dataType = header.type ?? driver.inferTypeFromHeader(headerData);

if (
dataType === TableColumnDataType.INTEGER ||
Expand All @@ -67,10 +73,6 @@ export default class OptimizeTableState {
initialSize = Math.max(150, Math.min(500, maxSize * 8));
}

const headerData = schemaResult
? schemaResult.columns.find((c) => c.name === header.name)
: undefined;

// --------------------------------------
// Matching foreign key
// --------------------------------------
Expand Down
1 change: 1 addition & 0 deletions src/components/gui/tabs/table-data-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default function TableDataWindow({
});

const tableState = OptimizeTableState.createFromResult(
databaseDriver,
dataResult,
schemaResult
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/gui/toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function ToolbarButton({
if (tooltip) {
return (
<Tooltip>
<TooltipTrigger>{buttonContent}</TooltipTrigger>
<TooltipTrigger asChild>{buttonContent}</TooltipTrigger>
<TooltipContent>{tooltip}</TooltipContent>
</Tooltip>
);
Expand Down
10 changes: 10 additions & 0 deletions src/drivers/base-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ export interface DriverFlags {
supportModifyColumn: boolean;
mismatchDetection: boolean;
dialect: SupportedDialect;

// If database supports this, we don't need
// to make a separate request to get updated
// data when update
supportInsertReturning: boolean;
supportUpdateReturning: boolean;
}

export interface DatabaseTableColumnChange {
Expand Down Expand Up @@ -252,6 +258,10 @@ export abstract class BaseDriver {
tableName: string
): Promise<DatabaseTableSchema>;

abstract inferTypeFromHeader(
header?: DatabaseTableColumn
): TableColumnDataType | undefined;

abstract trigger(
schemaName: string,
name: string
Expand Down
49 changes: 37 additions & 12 deletions src/drivers/common-sql-imp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,25 @@ export default abstract class CommonSQLImplement extends BaseDriver {

const sqls = ops.map((op) => {
if (op.operation === "INSERT")
return insertInto(this, schemaName, tableName, op.values);
return insertInto(
this,
schemaName,
tableName,
op.values,
this.getFlags().supportInsertReturning
);

if (op.operation === "DELETE")
return deleteFrom(this, schemaName, tableName, op.where);

return updateTable(this, schemaName, tableName, op.values, op.where);
return updateTable(
this,
schemaName,
tableName,
op.values,
op.where,
this.getFlags().supportInsertReturning
);
});

const result = await this.transaction(sqls);
Expand All @@ -57,18 +71,29 @@ export default abstract class CommonSQLImplement extends BaseDriver {
}

if (op.operation === "UPDATE") {
const selectResult = await this.findFirst(
schemaName,
tableName,
op.where
);
if (r.rows.length === 1)
// This is when database support RETURNING
tmp.push({
record: r.rows[0],
});
else {
const selectResult = await this.findFirst(
schemaName,
tableName,
op.where
);

tmp.push({
lastId: r.lastInsertRowid,
record: selectResult.rows[0],
});
tmp.push({
lastId: r.lastInsertRowid,
record: selectResult.rows[0],
});
}
} else if (op.operation === "INSERT") {
if (op.autoIncrementPkColumn) {
if (r.rows.length === 1) {
tmp.push({
record: r.rows[0],
});
} else if (op.autoIncrementPkColumn) {
const selectResult = await this.findFirst(schemaName, tableName, {
[op.autoIncrementPkColumn]: r.lastInsertRowid,
});
Expand Down
8 changes: 8 additions & 0 deletions src/drivers/mysql/mysql-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DriverFlags,
DatabaseSchemaItem,
DatabaseTableColumn,
TableColumnDataType,
} from "../base-driver";
import CommonSQLImplement from "../common-sql-imp";
import { escapeSqlValue } from "../sqlite/sql-helper";
Expand Down Expand Up @@ -53,6 +54,9 @@ export default abstract class MySQLLikeDriver extends CommonSQLImplement {
mismatchDetection: false,
supportCreateUpdateTable: false,
dialect: "mysql",

supportInsertReturning: false,
supportUpdateReturning: false,
};
}

Expand Down Expand Up @@ -153,4 +157,8 @@ export default abstract class MySQLLikeDriver extends CommonSQLImplement {
createUpdateTableSchema(): string[] {
throw new Error("Not implemented");
}

inferTypeFromHeader(): TableColumnDataType | undefined {
return undefined;
}
}
8 changes: 6 additions & 2 deletions src/drivers/query-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,14 @@ export function insertInto(
dialect: BaseDriver,
schema: string,
table: string,
value: Record<string, unknown>
value: Record<string, unknown>,
supportReturning: boolean
) {
return [
"INSERT INTO",
`${dialect.escapeId(schema)}.${dialect.escapeId(table)}`,
generateInsertValue(dialect, value),
supportReturning ? "RETURNING *" : "",
].join(" ");
}

Expand All @@ -78,14 +80,16 @@ export function updateTable(
schema: string,
table: string,
value: Record<string, unknown>,
where: Record<string, unknown>
where: Record<string, unknown>,
supportReturning: boolean
): string {
return [
"UPDATE",
`${dialect.escapeId(schema)}.${dialect.escapeId(table)}`,
"SET",
generateSet(dialect, value),
generateWhere(dialect, where),
supportReturning ? "RETURNING *" : "",
]
.filter(Boolean)
.join(" ");
Expand Down
12 changes: 11 additions & 1 deletion src/drivers/sqlite-base-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import type {
DatabaseValue,
DriverFlags,
SelectFromTableOptions,
TableColumnDataType,
} from "./base-driver";
import { escapeSqlValue } from "@/drivers/sqlite/sql-helper";
import { convertSqliteType, escapeSqlValue } from "@/drivers/sqlite/sql-helper";

import { parseCreateTableScript } from "@/drivers/sqlite/sql-parse-table";
import { parseCreateTriggerScript } from "@/drivers/sqlite/sql-parse-trigger";
Expand All @@ -32,6 +33,8 @@ export abstract class SqliteLikeBaseDriver extends CommonSQLImplement {
return {
supportBigInt: false,
supportModifyColumn: false,
supportInsertReturning: true,
supportUpdateReturning: true,
defaultSchema: "main",
optionalSchema: true,
mismatchDetection: false,
Expand Down Expand Up @@ -170,6 +173,13 @@ export abstract class SqliteLikeBaseDriver extends CommonSQLImplement {
// do nothing
}

inferTypeFromHeader(
header?: DatabaseTableColumn
): TableColumnDataType | undefined {
if (!header) return undefined;
return convertSqliteType(header.type);
}

async tableSchema(
schemaName: string,
tableName: string
Expand Down
6 changes: 0 additions & 6 deletions src/drivers/sqljs-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ export default class SqljsDriver extends SqliteLikeBaseDriver {
rowsWritten: null,
queryDurationMs: endTime - startTime,
},
lastInsertRowid:
headers.length > 0
? undefined
: (this.db.exec("select last_insert_rowid();")[0].values[0][0] as
| number
| undefined),
};
}

Expand Down

0 comments on commit 3a4b309

Please sign in to comment.