Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
Binary file added bun.lockb
Binary file not shown.
21 changes: 9 additions & 12 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@

import TestModel from './models/test';
import Test from './types/test';
import TestModel from "./models/test";

console.log(TestModel.tableName);


let relation = TestModel.select(["id", "name"]);
relation = relation.select("hi, no");
relation = relation.where({ id: 1, name: ["test"] });
relation = relation.where('name = "bob"');
// relation = relation.where({id: 2}, true);
// let otherRelation = relation.order({id: "DESC"})
// relation.all().then(res => console.log(res));
console.log(relation)
// let relation = TestModel.select(["id", "name"]);
// relation = relation.select("hi, no");
// relation = relation.where({ id: 1, name: ["test"] });
// relation = relation.where('name = "bob"');
// // relation = relation.where({id: 2}, true);
// // let otherRelation = relation.order({id: "DESC"})
// // relation.all().then(res => console.log(res));
// console.log(relation)

// console.log(relation.relationQuery, otherRelation.relationQuery);
File renamed without changes.
File renamed without changes.
File renamed without changes.
109 changes: 109 additions & 0 deletions lib.old/db.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@

import sqlite, { Database, RunResult, Statement } from 'sqlite3';
import path from 'path';

// This is a wrapper around the standard DB object that
// promisifys all the functions with callbacks
class AsyncDatabase {
db: Database;

constructor(dbPath: string) {
this.db = new sqlite.Database(dbPath);
}

close() : Promise<void> {
return new Promise((resolve, reject) => {
this.db.close((err: Error | null) => {
if(err) reject(err);
resolve();
});
});
}

configure(option: "busyTimeout", value: number) : void {
this.db.configure(option, value);
}

run(sql: string, params: any=[]) : Promise<RunResult> {
return new Promise((resolve, reject) => {
this.db.run(sql, params, function(err) {
if(err) reject(err);
else resolve(this);
});
});
}

get(sql: string, params: any=[]) : Promise<any> {
return new Promise((resolve, reject) => {
this.db.get(sql, params, function(err, row) {
if(err) reject(err);
else resolve(row);
});
});
}

all(sql: string, params: any=[]) : Promise<any[]> {
return new Promise((resolve, reject) => {
this.db.all(sql, params, function(err, rows) {
if(err) reject(err);
else resolve(rows);
});
});
}

each(sql: string, params: any=[], callback = (err: Error | null, row: any): void => {}) : Promise<number> {
return new Promise((resolve, reject) => {
this.db.each(sql, params, callback, function(err: Error | null, numRetrieved: number) {
if(err) reject(err);
else resolve(numRetrieved);
});
});
}

exec(sql: string) : Promise<void> {
return new Promise((resolve, reject) => {
this.db.exec(sql, function(err) {
if(err) reject(err);
else resolve();
});
});
}

prepare(sql: string, params: any=[]) : Promise<Statement> {
return new Promise((resolve, reject) => {
let statement = this.db.prepare(sql, params, (err) => {
if(err) reject(err)
})
if(statement) resolve(statement)
else reject('Something went wrong')
})
}
}

// =========================================================
// This is the initialization and cleanup of the database

// TODO: Fix this
const dbPath = path.resolve(process.cwd(), 'data', 'dev.db');

// const dbPath = __dirname + '/data/project.db'

const db = new AsyncDatabase(dbPath);

process.stdin.resume();

let close = () => {
console.log('closing database')
db.close()
.then(res => console.log("Database closed"))
.catch(err => console.log(err))
.finally(() => process.exit())
}

process.on('SIGINT', close);
process.on('exit', close);
process.on('SIGUSR1', close);
process.on('SIGUSR2', close);
process.on('uncaughtException', close);

export default db;
29 changes: 29 additions & 0 deletions lib.old/sql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// TODO: this
function cleanSQL(sql: string): string {
return sql;
}

function cleanWhiteSpace(str: string): string {
return str.replace(/\s{1,}/g, ' ').replace(/^\s{1,}|\s{1,}$/ig, '')
}

function sql(strings: TemplateStringsArray, ...interopStrings: string[]) : string {
let string: string[] = [];

for(let i:number = 0; i < strings.length - 1; i++) {
let newStr: string = cleanWhiteSpace(strings[i]);
if (newStr.length > 0)
string.push(newStr);
newStr = cleanWhiteSpace(interopStrings[i]);
if (newStr.length > 0)
string.push(cleanSQL(newStr));
}

let newStr: string = strings[strings.length - 1]
if (newStr.length > 0)
string.push(cleanWhiteSpace(newStr));
// Chomp the whitespace from the front and back even further
return string.join(' ');
}

export { sql };
31 changes: 31 additions & 0 deletions lib/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { OptionalOrArray, ConstructorFunctionType } from "types/base_types";
import { Relation } from "./relation";

export abstract class BaseModel<
ModelProperties extends Record<Keys, any>,
Keys extends string
> {
static __tableName?: string;
static get tableName(): string {
if (this.__tableName) {
return this.__tableName;
}

return this.name
.replace(/([A-Z])/g, "_$1")
.toLowerCase()
.slice(1);
}

constructor(params: Partial<ModelProperties>) {
for (const key in params) {
this[key] = params[key];
}
}
}

export function model(tableName: string) {
return <This extends typeof BaseModel>(constructor: This) => {
constructor.__tableName = tableName;
};
}
7 changes: 7 additions & 0 deletions lib/property.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
interface Props {}

export function property(props?: Props) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
return target;
};
}
37 changes: 37 additions & 0 deletions lib/relation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { QueryType } from "types/base_types";

export class Relation<T> implements Iterable<T> {
private query: QueryType<T> = {
select: new Set(),
where: [],
order: []
};

[Symbol.iterator](): Iterator<T> {
throw new Error("Method not implemented.");
}

tableName: string;

constructor(tableName: string) {
this.tableName = tableName;
}

duplicate(): this {
return Object.assign(Object.create(this), { ...this, data: []});
}

select(fields: (keyof T)[] | string): this {
let dup = this.duplicate();

if (typeof fields === "string") {
const newFields = fields.split(/,\s{1,}/);
dup.query.select = new Set([ ...this.query.select, ...newFields ]);
}
else {
dup.query.select = new Set([ ...this.query.select, ...fields ]);
}

return dup
}
}
11 changes: 6 additions & 5 deletions models/test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Test from "types/test";
import Base, { table } from "lib/active_record/model";

@table("tests")
class TestModel extends Base<Test>() {
import { BaseModel, model } from "lib/model";
import { property } from "lib/property";

@model("tests")
class TestModel extends BaseModel {
@property()
id: number;
}

export default TestModel;
2 changes: 1 addition & 1 deletion nodemon.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"watch": ["."],
"ext": "ts",
"exclude": "build",
"exec": "yarn start index.ts || exit 1"
"exec": "bun start || exit 1"
}
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
"private": true,
"type": "module",
"dependencies": {
"sqlite3": "^5.0.2",
"ts-node": "^10.2.1",
"typescript": "^4.4.3"
"sqlite3": "^5.1.7",
"ts-node": "^10.9.2",
"typescript": "next"
},
"scripts": {
"dev": "yarn nodemon",
"setup": "yarn start setup.ts",
"start": "node --loader ts-node/esm --experimental-modules --es-module-specifier-resolution=node"
"setup": "bun setup.ts",
"start": "bun index.ts"
},
"devDependencies": {
"@types/node": "*",
"@types/sqlite3": "^3.1.7",
"nodemon": "^2.0.7"
"@types/node": "^22.5.4",
"@types/sqlite3": "^3.1.11",
"nodemon": "^3.1.7"
}
}
4 changes: 2 additions & 2 deletions setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RunResult } from "sqlite3";
import Database from "./lib/db";
import { sql } from "./lib/sql";
import Database from "./lib.old/db";
import { sql } from "./lib.old/sql";

Database.run(sql`
CREATE TABLE IF NOT EXISTS test(
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "ES2020",
"target": "ESNext",
"lib": [
"dom",
"dom.iterable",
Expand Down
2 changes: 2 additions & 0 deletions types/base_types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ type OptionalOrArray<T> = {
}

type levels = "log" | "warn" | "error" | "critical"

type ConstructorFunctionType<Args=any[], Return=any> = new (...args: Args) => Return;
Loading