Skip to content

Commit

Permalink
improved sqlite table generation config and improved unit testing
Browse files Browse the repository at this point in the history
  • Loading branch information
brandon-schabel committed Nov 3, 2023
1 parent c6aabdd commit f18fb16
Show file tree
Hide file tree
Showing 17 changed files with 494 additions and 164 deletions.
6 changes: 3 additions & 3 deletions modules/sqlite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Next, define your schema and use `sqliteTableFactory` to generate your table.

```javascript
const userSchema = {
id: "TEXT",
name: "TEXT",
email: "TEXT",
id: { type: "TEXT" },
name: { type: "TEXT" },
email: { type: "TEXT" },
}

const db = new Database({filename: "./mydb.sqlite"})
Expand Down
2 changes: 1 addition & 1 deletion modules/sqlite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export {
readItems,
updateItem
} from "./sqlite-utils/crud-fn-utils";
export { createTableQuery } from "./sqlite-utils/table-query-string";
export { createTableQuery } from "./sqlite-utils/table-query-gen";

4 changes: 2 additions & 2 deletions modules/sqlite/sqlite-factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { SchemaMap, createSqliteFactory } from "./sqlite-factory";
let db = new Database(":memory:");

const noteSchema = {
id: "TEXT",
text: "TEXT",
id: { type: "TEXT" },
text: { type: "TEXT" },
} satisfies SchemaMap;

describe("createSqliteFactory", () => {
Expand Down
60 changes: 34 additions & 26 deletions modules/sqlite/sqlite-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import {
} from "./sqlite-table-factory";

export type CreateSqliteFactory<Schema extends SchemaMap> = {
create: (item: SQLiteSchemaToTypeScript<Schema>) => Promise<void>;
read: () => Promise<SQLiteSchemaToTypeScript<Schema>[]>;
create: (item: SQLiteSchemaInfer<Schema>) => Promise<void>;
read: () => Promise<SQLiteSchemaInfer<Schema>[]>;
update: (
id: number,
item: Partial<SQLiteSchemaToTypeScript<Schema>>
item: Partial<SQLiteSchemaInfer<Schema>>
) => Promise<void>;
deleteById: (id: number) => Promise<void>;
};
Expand Down Expand Up @@ -38,44 +38,52 @@ export type SQLiteToTypeScriptTypes = {
DATE: Date;
};

export type SchemaKeys = keyof SQLiteToTypeScriptTypes;
export type SQLiteDataTypes = keyof SQLiteToTypeScriptTypes;

export type SchemaMap = Partial<Record<string, SchemaKeys>>;

export const createTableSchema = <Schema extends SchemaMap>(
schema: Schema
): string => {
return undefined as any as string;
export type FieldDefinition = {
type: SQLiteDataTypes; // The data type of the field
primaryKey?: boolean; // Whether the field is a primary key
unique?: boolean; // Whether the field should be unique
foreignKey?: string; // Reference to another table (foreign key)
notNull?: boolean; // Whether the field can be null
defaultValue?: string | number; // Default value for the field
};

// Mapped type that takes a schema with SQLite types and returns a schema with TypeScript types.
export type SQLiteSchemaToTypeScript<T extends SchemaMap> = {
[K in keyof T]: T[K] extends SchemaKeys
? SQLiteToTypeScriptTypes[T[K]]
export type SQLiteSchemaInfer<T extends SchemaMap> = {
[K in keyof T]: T[K] extends FieldDefinition
? SQLiteToTypeScriptTypes[T[K]["type"]]
: never;
};

// Example usage.
export type SchemaMap = Partial<Record<string, FieldDefinition>>;

// example
const sqlitePersonTableSchema = {
id: "TEXT",
age: "INTEGER",
name: "TEXT",
createdAt: "DATE",
id: { type: "TEXT" },
age: { type: "INTEGER" },
name: { type: "TEXT" },
createdAt: { type: "DATE" },
} satisfies SchemaMap;

type Person = SQLiteSchemaInfer<typeof sqlitePersonTableSchema>;

// TODO implement into the sqlite factory
type PersonTableSchema = SQLiteSchemaInfer<typeof sqlitePersonTableSchema>;

export const createTableSchema = <Schema extends SchemaMap>(
schema: Schema
): string => {
return undefined as any as string;
};

export const getType = <T extends SchemaMap>(
schema: T
): SQLiteSchemaToTypeScript<T> => {
return undefined as any as SQLiteSchemaToTypeScript<T>;
): SQLiteSchemaInfer<T> => {
return undefined as any as SQLiteSchemaInfer<T>;
};

type Person = SQLiteSchemaToTypeScript<typeof sqlitePersonTableSchema>;
// => schema;

// TODO implement into the sqlite factory
type PersonTableSchema = SQLiteSchemaToTypeScript<
typeof sqlitePersonTableSchema
>;

// This should now have the correct types.
let person: PersonTableSchema = {
Expand Down
6 changes: 3 additions & 3 deletions modules/sqlite/sqlite-table-factory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { sqliteTableFactory } from "./sqlite-table-factory";

const mockDb = new Database(":memory:");
const testSchema = {
id: "TEXT",
name: "TEXT",
age: "INTEGER",
id: { type: "TEXT" },
name: { type: "TEXT" },
age: { type: "INTEGER" },
} satisfies SchemaMap;

const factoryOptions = {
Expand Down
12 changes: 6 additions & 6 deletions modules/sqlite/sqlite-table-factory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Database from "bun:sqlite";
import {
CreateSqliteFactory,
SQLiteSchemaToTypeScript,
SQLiteSchemaInfer,
SchemaMap,
} from "./sqlite-factory";
import {
Expand All @@ -10,7 +10,7 @@ import {
readItems,
updateItem,
} from "./sqlite-utils/crud-fn-utils";
import { createTableQuery } from "./sqlite-utils/table-query-string";
import { createTableQuery } from "./sqlite-utils/table-query-gen";

export type ForeignKeysT<Schema> =
| { column: keyof Schema; references: string }[]
Expand Down Expand Up @@ -39,17 +39,17 @@ function logger(debug: boolean) {

export function sqliteTableFactory<
Schema extends SchemaMap,
TranslatedSchema extends SQLiteSchemaToTypeScript<Schema> = SQLiteSchemaToTypeScript<Schema>
TranslatedSchema extends SQLiteSchemaInfer<Schema> = SQLiteSchemaInfer<Schema>
>(
params: SqliteTableFactoryParams<Schema>,
options: SqliteTableOptions<Schema> = {}
) {
const { db, schema, tableName } = params;
const { debug = false, foreignKeys = null } = options;
const { debug = false } = options;

const log = logger(debug);

db.query(createTableQuery({ tableName, schema, foreignKeys, debug })).run();
db.query(createTableQuery({ tableName, schema, debug })).run();

// Pass necessary context to external CRUD functions
function create(item: TranslatedSchema) {
Expand All @@ -67,7 +67,7 @@ export function sqliteTableFactory<
updateItem<Schema>(db, tableName, log, id, item);
}

function deleteById(id: number| string) {
function deleteById(id: number | string) {
deleteItemById(db, tableName, log, id);
}

Expand Down
Empty file added modules/sqlite/sqlite-types.ts
Empty file.
6 changes: 3 additions & 3 deletions modules/sqlite/sqlite-utils/crud-fn-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import {
} from "./crud-fn-utils"; // replace with the path to your file

const testSchema = {
id: "TEXT",
name: "TEXT",
age: "INTEGER",
id: { type: "TEXT" },
name: { type: "TEXT" },
age: { type: "INTEGER" },
} satisfies SchemaMap;

let db = new Database(":memory:");
Expand Down
8 changes: 4 additions & 4 deletions modules/sqlite/sqlite-utils/crud-fn-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Database from "bun:sqlite";
import { SchemaMap, SQLiteSchemaToTypeScript } from "../sqlite-factory";
import { SchemaMap, SQLiteSchemaInfer } from "../sqlite-factory";
import {
deleteQueryString,
insertQueryString,
Expand All @@ -9,7 +9,7 @@ import {

export function createItem<
Schema extends SchemaMap,
TranslatedSchema extends SQLiteSchemaToTypeScript<Schema> = SQLiteSchemaToTypeScript<Schema>
TranslatedSchema extends SQLiteSchemaInfer<Schema> = SQLiteSchemaInfer<Schema>
>(
db: Database,
tableName: string,
Expand All @@ -25,7 +25,7 @@ export function createItem<

export function readItems<
Schema extends SchemaMap,
TranslatedSchema extends SQLiteSchemaToTypeScript<Schema> = SQLiteSchemaToTypeScript<Schema>
TranslatedSchema extends SQLiteSchemaInfer<Schema> = SQLiteSchemaInfer<Schema>
>(
db: Database,
tableName: string,
Expand All @@ -39,7 +39,7 @@ export function readItems<

export function updateItem<
Schema extends SchemaMap,
TranslatedSchema extends SQLiteSchemaToTypeScript<Schema> = SQLiteSchemaToTypeScript<Schema>
TranslatedSchema extends SQLiteSchemaInfer<Schema> = SQLiteSchemaInfer<Schema>
>(
db: Database,
tableName: string,
Expand Down
14 changes: 0 additions & 14 deletions modules/sqlite/sqlite-utils/format-foreign-keys.test.ts

This file was deleted.

13 changes: 0 additions & 13 deletions modules/sqlite/sqlite-utils/format-foreign-keys.ts

This file was deleted.

8 changes: 5 additions & 3 deletions modules/sqlite/sqlite-utils/format-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { formatSchema } from "./format-schema";

test("formatSchema formats schema correctly", () => {
const schema = {
id: "INTEGER",
name: "TEXT",
id: { type: "INTEGER" },
name: { type: "TEXT" },
} satisfies SchemaMap;

// TODO need to fix schema type
const result = formatSchema(schema);
expect(result).toBe("id INTEGER, name TEXT");

expect(result[0]).toBe("id INTEGER");
expect(result[1]).toBe("name TEXT");
});
13 changes: 6 additions & 7 deletions modules/sqlite/sqlite-utils/format-schema.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { SchemaMap } from "../sqlite-factory";

export function formatSchema<Schema extends SchemaMap>(
schema: Schema
): string {
return Object.entries(schema)
.map(([key, type]) => `${key} ${type?.toUpperCase()}`)
.join(", ");
}

schema: Schema
): string[] {
return Object.entries(schema).map(
([key, fieldDefinition]) => `${key} ${fieldDefinition?.type.toUpperCase()}`
);
}
Loading

0 comments on commit f18fb16

Please sign in to comment.