Comparing version 0.1.0 to 0.1.1
@@ -1,3 +0,2 @@ | ||
export { Repository } from './repository'; | ||
export { Transaction } from './transaction'; | ||
export { LilORMModule } from './module'; | ||
export * from "./core"; | ||
export * from "./api"; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LilORMModule = exports.Transaction = exports.Repository = void 0; | ||
var repository_1 = require("./repository"); | ||
Object.defineProperty(exports, "Repository", { enumerable: true, get: function () { return repository_1.Repository; } }); | ||
var transaction_1 = require("./transaction"); | ||
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } }); | ||
var module_1 = require("./module"); | ||
Object.defineProperty(exports, "LilORMModule", { enumerable: true, get: function () { return module_1.LilORMModule; } }); | ||
__exportStar(require("./core"), exports); | ||
__exportStar(require("./api"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "lil-orm", | ||
"version": "0.1.0", | ||
"description": "A sqlite3 ORM for Node.js", | ||
"version": "0.1.1", | ||
"description": "Lil ORM is a super lightweight SQLite ORM for Node.js. With its clear API, you can easily interact with SQLite databases.", | ||
"main": "dist/index.js", | ||
@@ -6,0 +6,0 @@ "types": "dist/index.d.ts", |
138
README.md
@@ -1,2 +0,136 @@ | ||
# lil-orm | ||
A lightweight sqlite3 ORM | ||
# Lil ORM | ||
Lil ORM is a super lightweight SQLite ORM for Node.js. With its clear API, you can easily interact with SQLite databases | ||
# Install | ||
``` | ||
npm i lil-orm | ||
``` | ||
# Define Entity | ||
``` | ||
@Entity('user') | ||
class UserEntity { | ||
@PrimaryKey({ | ||
autoIncrement: true, | ||
}) | ||
@Column({ | ||
type: 'INTEGER', | ||
name: 'id', | ||
}) | ||
id: number; | ||
@Column({ | ||
type: 'TEXT', | ||
name: 'name', | ||
}) | ||
name: string; | ||
@Column({ | ||
type: 'TEXT', | ||
name: 'email', | ||
}) | ||
email: string; | ||
@Column({ | ||
type: 'JSON', | ||
name: 'config', | ||
}) | ||
config: any; | ||
@Column({ | ||
type: 'BOOLEAN', | ||
name: 'is_active', | ||
}) | ||
isActive: boolean; | ||
@Column({ | ||
type: 'DATE', | ||
name: 'created_at', | ||
}) | ||
createdAt: Date; | ||
} | ||
``` | ||
supported types: | ||
- TEXT | ||
- INTEGER | ||
- REAL | ||
- BOOLEAN | ||
- DATE (ISO Format) | ||
- JSON | ||
# Module Setup | ||
``` | ||
import { LilORMModule } from 'lil-orm'; | ||
const databaseConnectionString = ':memory:'; | ||
const module = new LilORM(databaseConnectionString); | ||
``` | ||
# Create Table | ||
(experimental API name) | ||
``` | ||
module.createTable(UserEntity) //to create a table from an entity | ||
``` | ||
# CRUD Operations | ||
``` | ||
//get repository for DAO | ||
const repository = module.getRepository<UserEntity>(UserEntity); | ||
//Create | ||
await repository.create({ | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
config: { | ||
test: true, | ||
}, | ||
isActive: true, | ||
createdAt: new Date(), | ||
}); | ||
//Find one | ||
await repository.findOne({ id: 1 }); | ||
//Find all | ||
await repository.findAll(); | ||
//Update | ||
const updatedUser = { | ||
id: 1, | ||
email: 'updated@gmail.com', | ||
name: 'updated', | ||
}; | ||
await repository.update(updatedUser); | ||
//Delete | ||
await repository.delete({ id: 69 }); | ||
``` | ||
# Transactions | ||
``` | ||
import { Transaction } from 'lil-orm'; | ||
const repository = module.getRepository<UserEntity>(UserEntity); | ||
const transaction = new Transaction(repository.dbInstance); | ||
transaction.transaction(async (transaction) => { | ||
repository.create( | ||
{ | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
config: { | ||
test: true, | ||
}, | ||
isActive: true, | ||
createdAt: new Date(), | ||
}, | ||
transaction, | ||
); | ||
}); | ||
``` | ||
@@ -1,7 +0,7 @@ | ||
import 'reflect-metadata'; | ||
import { Column, Entity, PrimaryKey } from '../core/decorators'; | ||
import { LilORMModule } from '../core/module'; | ||
import { Transaction } from '../core/transaction'; | ||
import "reflect-metadata"; | ||
import { Column, Entity, PrimaryKey } from "../core/decorators"; | ||
import { LilORM } from "../"; | ||
import { Transaction } from "../core/transaction"; | ||
@Entity('user') | ||
@Entity("user") | ||
class UserEntity { | ||
@@ -12,4 +12,4 @@ @PrimaryKey({ | ||
@Column({ | ||
type: 'INTEGER', | ||
name: 'id', | ||
type: "INTEGER", | ||
name: "id", | ||
}) | ||
@@ -19,4 +19,4 @@ id: number; | ||
@Column({ | ||
type: 'TEXT', | ||
name: 'name', | ||
type: "TEXT", | ||
name: "name", | ||
}) | ||
@@ -26,4 +26,4 @@ name: string; | ||
@Column({ | ||
type: 'TEXT', | ||
name: 'email', | ||
type: "TEXT", | ||
name: "email", | ||
}) | ||
@@ -33,4 +33,4 @@ email: string; | ||
@Column({ | ||
type: 'JSON', | ||
name: 'config', | ||
type: "JSON", | ||
name: "config", | ||
}) | ||
@@ -40,4 +40,4 @@ config: any; | ||
@Column({ | ||
type: 'BOOLEAN', | ||
name: 'is_active', | ||
type: "BOOLEAN", | ||
name: "is_active", | ||
}) | ||
@@ -47,4 +47,4 @@ isActive: boolean; | ||
@Column({ | ||
type: 'DATE', | ||
name: 'created_at', | ||
type: "DATE", | ||
name: "created_at", | ||
}) | ||
@@ -54,10 +54,7 @@ createdAt: Date; | ||
describe('LilORMModule', () => { | ||
const databaseConnectionString = ':memory:'; | ||
describe("LilORM", () => { | ||
const databaseConnectionString = ":memory:"; | ||
it('should instantiate LilORMModule', () => { | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [], | ||
}); | ||
it("should instantiate LilORM", () => { | ||
const module = new LilORM(databaseConnectionString); | ||
@@ -67,25 +64,19 @@ expect(module).toBeDefined(); | ||
it('should migrate the database schema', async () => { | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
it("should migrate the database schema", async () => { | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
// Assert that the migration was successful by checking if the table exists in the database | ||
const tableExists = await module.tableExists('user'); | ||
const tableExists = await module.tableExists("user"); | ||
expect(tableExists).toBeTruthy(); | ||
}); | ||
it('should create a new user in the database', async () => { | ||
it("should create a new user in the database", async () => { | ||
// Arrange | ||
// ... (Same code as in the original test) | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
@@ -97,4 +88,4 @@ const repository = module.getRepository<UserEntity>(UserEntity); | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
email: "test@gmail.com", | ||
name: "test", | ||
config: { | ||
@@ -110,4 +101,4 @@ test: true, | ||
expect(user).toBeDefined(); | ||
expect(user?.email).toBe('test@gmail.com'); | ||
expect(user?.name).toBe('test'); | ||
expect(user?.email).toBe("test@gmail.com"); | ||
expect(user?.name).toBe("test"); | ||
expect(user?.createdAt).toBeInstanceOf(Date); | ||
@@ -118,12 +109,9 @@ expect(user?.isActive).toBe(true); | ||
it('should retrieve all users from the database', async () => { | ||
it("should retrieve all users from the database", async () => { | ||
// Arrange | ||
// ... (Same code as in the original test) | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
@@ -134,4 +122,4 @@ const repository = module.getRepository<UserEntity>(UserEntity); | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
email: "test@gmail.com", | ||
name: "test", | ||
config: { | ||
@@ -149,16 +137,13 @@ test: true, | ||
expect(users.length).toBe(1); | ||
expect(users[0].email).toBe('test@gmail.com'); | ||
expect(users[0].name).toBe('test'); | ||
expect(users[0].email).toBe("test@gmail.com"); | ||
expect(users[0].name).toBe("test"); | ||
}); | ||
it('should update a user in the database', async () => { | ||
it("should update a user in the database", async () => { | ||
// Arrange | ||
// ... (Same code as in the original test) | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
@@ -169,4 +154,4 @@ const repository = module.getRepository<UserEntity>(UserEntity); | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
email: "test@gmail.com", | ||
name: "test", | ||
config: { | ||
@@ -182,4 +167,4 @@ test: true, | ||
id: 1, | ||
email: 'updated@gmail.com', | ||
name: 'updated', | ||
email: "updated@gmail.com", | ||
name: "updated", | ||
}; | ||
@@ -190,16 +175,13 @@ await repository.update(updatedUser); | ||
const user = await repository.findOne({ id: 1 }); | ||
expect(user?.email).toBe('updated@gmail.com'); | ||
expect(user?.name).toBe('updated'); | ||
expect(user?.email).toBe("updated@gmail.com"); | ||
expect(user?.name).toBe("updated"); | ||
}); | ||
it('should delete a user from the database', async () => { | ||
it("should delete a user from the database", async () => { | ||
// Arrange | ||
// ... (Same code as in the original test) | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
@@ -210,4 +192,4 @@ const repository = module.getRepository<UserEntity>(UserEntity); | ||
id: 69, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
email: "test@gmail.com", | ||
name: "test", | ||
config: { | ||
@@ -229,9 +211,6 @@ test: true, | ||
it('should begin a transaction', async () => { | ||
const module = new LilORMModule({ | ||
database: databaseConnectionString, | ||
entities: [UserEntity], | ||
}); | ||
it("should begin a transaction", async () => { | ||
const module = new LilORM(databaseConnectionString); | ||
await module.migrate(); | ||
await module.createTable(UserEntity); | ||
@@ -246,4 +225,4 @@ const repository = module.getRepository<UserEntity>(UserEntity); | ||
id: 1, | ||
email: 'test@gmail.com', | ||
name: 'test', | ||
email: "test@gmail.com", | ||
name: "test", | ||
config: { | ||
@@ -255,3 +234,3 @@ test: true, | ||
}, | ||
transaction, | ||
transaction | ||
); | ||
@@ -258,0 +237,0 @@ //throw new Error('test'); |
@@ -1,5 +0,5 @@ | ||
export const ENTITY_METADATA_KEY = 'entity'; | ||
export const COLUMN_METADATA_KEY = 'column'; | ||
export const PRIMARY_KEY_METADATA_KEY = 'primary-key'; | ||
export const ENTITY_METADATA_KEY = "entity"; | ||
export const COLUMN_METADATA_KEY = "column"; | ||
export const PRIMARY_KEY_METADATA_KEY = "primary-key"; | ||
export const RADIX = 10; | ||
export const RADIX = 10; |
@@ -1,3 +0,7 @@ | ||
import { COLUMN_METADATA_KEY, ENTITY_METADATA_KEY, PRIMARY_KEY_METADATA_KEY } from './constants'; | ||
import { LilORMType, SQLiteType } from './types'; | ||
import { | ||
COLUMN_METADATA_KEY, | ||
ENTITY_METADATA_KEY, | ||
PRIMARY_KEY_METADATA_KEY, | ||
} from "./constants"; | ||
import { LilORMType } from "./types"; | ||
@@ -17,3 +21,7 @@ export interface ColumnOtps { | ||
return (target: object) => { | ||
Reflect.defineMetadata(ENTITY_METADATA_KEY, { name: tableName || target.constructor.name }, target); | ||
Reflect.defineMetadata( | ||
ENTITY_METADATA_KEY, | ||
{ name: tableName || target.constructor.name }, | ||
target | ||
); | ||
}; | ||
@@ -24,3 +32,8 @@ } | ||
return (target: object, propertyKey: string | symbol) => { | ||
Reflect.defineMetadata(PRIMARY_KEY_METADATA_KEY, { ...opts }, target, propertyKey); | ||
Reflect.defineMetadata( | ||
PRIMARY_KEY_METADATA_KEY, | ||
{ ...opts }, | ||
target, | ||
propertyKey | ||
); | ||
}; | ||
@@ -31,4 +44,9 @@ } | ||
return (target: object, propertyKey: string | symbol) => { | ||
Reflect.defineMetadata(COLUMN_METADATA_KEY, { name: opts?.name, type: opts.type }, target, propertyKey); | ||
Reflect.defineMetadata( | ||
COLUMN_METADATA_KEY, | ||
{ name: opts?.name, type: opts.type }, | ||
target, | ||
propertyKey | ||
); | ||
}; | ||
} |
@@ -1,8 +0,10 @@ | ||
import { MetadataExtractor } from './metadata'; | ||
import { ColumnMetadata, LilORMType, MapTypes, SQLiteType } from './types'; | ||
import { TypesHelper } from './types-helper'; | ||
import { MetadataExtractor } from "./metadata"; | ||
import { ColumnMetadata, LilORMType, MapTypes, SQLiteType } from "./types"; | ||
import { TypesHelper } from "./types-helper"; | ||
export class EntityTransformer { | ||
static transformSQLEntityToObject<TEntity>(entityInstance: any, values: any): TEntity { | ||
static transformSQLEntityToObject<TEntity>( | ||
entityInstance: any, | ||
values: any | ||
): TEntity { | ||
const properties = Object.keys(entityInstance); | ||
@@ -12,6 +14,13 @@ const entity: any = {}; | ||
for (const propertyKey of properties) { | ||
const columnMetadata = Reflect.getMetadata('column', entityInstance, propertyKey); | ||
const columnMetadata = Reflect.getMetadata( | ||
"column", | ||
entityInstance, | ||
propertyKey | ||
); | ||
if (columnMetadata) { | ||
const columnName = columnMetadata.name || propertyKey.toString(); | ||
entity[propertyKey] = EntityTransformer.formatValue(values[columnName], columnMetadata.type); | ||
entity[propertyKey] = EntityTransformer.formatValue( | ||
values[columnName], | ||
columnMetadata.type | ||
); | ||
} | ||
@@ -23,8 +32,14 @@ } | ||
static transformClassInstanceToEntityColumns(entityInstance: any): ColumnMetadata[] { | ||
const columns = MetadataExtractor.getEnrichedEntityColumnsName(entityInstance); | ||
static transformClassInstanceToEntityColumns( | ||
entityInstance: any | ||
): ColumnMetadata[] { | ||
const columns = | ||
MetadataExtractor.getEnrichedEntityColumnsName(entityInstance); | ||
columns | ||
.filter((col) => col.value !== undefined) | ||
.map((column) => { | ||
column.value = this.formatValueToSQLiteType(column.value, column.type) as SQLiteType; | ||
column.value = this.formatValueToSQLiteType( | ||
column.value, | ||
column.type | ||
) as SQLiteType; | ||
column.type = MapTypes[column.type] as SQLiteType; | ||
@@ -39,10 +54,10 @@ return column; | ||
if (TypesHelper.isDate(value)) return `'${value.toISOString()}'`; | ||
if (TypesHelper.isBoolean(value)) return value ? '1' : '0'; | ||
if (TypesHelper.isBoolean(value)) return value ? "1" : "0"; | ||
if (TypesHelper.isNumber(value)) return value.toString(); | ||
if (TypesHelper.isJSONObject(value)) return `'${JSON.stringify(value)}'`; | ||
throw new Error('Not supported type'); | ||
throw new Error("Not supported type"); | ||
} | ||
static formatValue(value: any, type: LilORMType): any { | ||
if (type === 'TEXT' || type === 'UUID' || type === 'BLOB') { | ||
if (type === "TEXT" || type === "UUID" || type === "BLOB") { | ||
if (TypesHelper.isDate(value)) return value.toISOString(); | ||
@@ -53,3 +68,3 @@ if (TypesHelper.isJSONObject(value)) return JSON.stringify(value); | ||
} | ||
if (type === 'INTEGER') { | ||
if (type === "INTEGER") { | ||
if (TypesHelper.isBoolean(value)) return value ? 1 : 0; | ||
@@ -59,12 +74,12 @@ | ||
} | ||
if (type === 'REAL') { | ||
if (type === "REAL") { | ||
return TypesHelper.parseReal(value); | ||
} | ||
if (type === 'JSON') { | ||
if (type === "JSON") { | ||
return TypesHelper.parseJson(value); | ||
} | ||
if (type === 'BOOLEAN') { | ||
if (type === "BOOLEAN") { | ||
return TypesHelper.parseBoolean(value); | ||
} | ||
if (type === 'DATE') { | ||
if (type === "DATE") { | ||
return TypesHelper.parseDate(value); | ||
@@ -81,3 +96,2 @@ } | ||
} | ||
} |
export function escapeValue(value: any): string { | ||
if (typeof value === 'string') { | ||
if (typeof value === "string") { | ||
return `'${value}'`; | ||
@@ -4,0 +4,0 @@ } |
@@ -1,3 +0,3 @@ | ||
export { Repository } from './repository' | ||
export { Transaction } from './transaction' | ||
export { LilORMModule } from './module' | ||
export { Repository } from "./repository"; | ||
export { Transaction } from "./transaction"; | ||
export * from "./decorators"; |
@@ -1,5 +0,9 @@ | ||
import { COLUMN_METADATA_KEY, ENTITY_METADATA_KEY, PRIMARY_KEY_METADATA_KEY } from './constants'; | ||
import { EntityTransformer } from './entity-transformer'; | ||
import { ColumnMetadata, LilORMType, MapTypes, SQLiteType } from './types'; | ||
import { TypesHelper } from './types-helper'; | ||
import { | ||
COLUMN_METADATA_KEY, | ||
ENTITY_METADATA_KEY, | ||
PRIMARY_KEY_METADATA_KEY, | ||
} from "./constants"; | ||
import { EntityTransformer } from "./entity-transformer"; | ||
import { ColumnMetadata, LilORMType, MapTypes, SQLiteType } from "./types"; | ||
import { TypesHelper } from "./types-helper"; | ||
@@ -14,3 +18,6 @@ export class MetadataExtractor { | ||
static getEntityTableName(entityClass: any): string { | ||
const entityMetadata = Reflect.getMetadata(ENTITY_METADATA_KEY, entityClass); | ||
const entityMetadata = Reflect.getMetadata( | ||
ENTITY_METADATA_KEY, | ||
entityClass | ||
); | ||
const tableName = entityMetadata.name; | ||
@@ -26,7 +33,14 @@ return tableName; | ||
*/ | ||
static getEntityPrimaryKey(entityInstance: any): { propertyKey: string; columnName: string } { | ||
static getEntityPrimaryKey(entityInstance: any): { | ||
propertyKey: string; | ||
columnName: string; | ||
} { | ||
const properties = Object.keys(entityInstance); | ||
for (const propertyKey of properties) { | ||
const primaryKeyMetadata = Reflect.getMetadata(PRIMARY_KEY_METADATA_KEY, entityInstance, propertyKey); | ||
const primaryKeyMetadata = Reflect.getMetadata( | ||
PRIMARY_KEY_METADATA_KEY, | ||
entityInstance, | ||
propertyKey | ||
); | ||
if (primaryKeyMetadata) { | ||
@@ -38,3 +52,3 @@ const columnName = primaryKeyMetadata.name || propertyKey.toString(); | ||
throw new Error('Primary key not found'); | ||
throw new Error("Primary key not found"); | ||
} | ||
@@ -52,3 +66,7 @@ | ||
for (const propertyKey of properties) { | ||
const columnMetadata = Reflect.getMetadata(COLUMN_METADATA_KEY, entityInstance, propertyKey); | ||
const columnMetadata = Reflect.getMetadata( | ||
COLUMN_METADATA_KEY, | ||
entityInstance, | ||
propertyKey | ||
); | ||
if (columnMetadata) { | ||
@@ -68,3 +86,7 @@ const columnName = columnMetadata.name || propertyKey.toString(); | ||
for (const propertyKey of properties) { | ||
const columnMetadata = Reflect.getMetadata(COLUMN_METADATA_KEY, entityInstance, propertyKey); | ||
const columnMetadata = Reflect.getMetadata( | ||
COLUMN_METADATA_KEY, | ||
entityInstance, | ||
propertyKey | ||
); | ||
if (columnMetadata) { | ||
@@ -93,6 +115,13 @@ const columnName = columnMetadata.name || propertyKey.toString(); | ||
for (const propertyKey of properties) { | ||
const columnMetadata = Reflect.getMetadata(COLUMN_METADATA_KEY, entityInstance, propertyKey); | ||
const columnMetadata = Reflect.getMetadata( | ||
COLUMN_METADATA_KEY, | ||
entityInstance, | ||
propertyKey | ||
); | ||
if (columnMetadata) { | ||
const propertyValue = entityInstance[propertyKey]; | ||
const columnValue = EntityTransformer.formatValueToSQLiteType(propertyValue, columnMetadata.type); | ||
const columnValue = EntityTransformer.formatValueToSQLiteType( | ||
propertyValue, | ||
columnMetadata.type | ||
); | ||
values.push(columnValue); | ||
@@ -99,0 +128,0 @@ } |
@@ -1,14 +0,14 @@ | ||
import { COLUMN_METADATA_KEY, PRIMARY_KEY_METADATA_KEY } from './constants'; | ||
import { PrimaryKeyOpts, ColumnOtps } from './decorators'; | ||
import { EntityTransformer } from './entity-transformer'; | ||
import { escapeValue } from './helper'; | ||
import { MetadataExtractor } from './metadata'; | ||
import { EntityType, MapTypes, SQLiteType } from './types'; | ||
import 'reflect-metadata'; | ||
import { COLUMN_METADATA_KEY, PRIMARY_KEY_METADATA_KEY } from "./constants"; | ||
import { PrimaryKeyOpts, ColumnOtps } from "./decorators"; | ||
import { EntityTransformer } from "./entity-transformer"; | ||
import { escapeValue } from "./helper"; | ||
import { MetadataExtractor } from "./metadata"; | ||
import { EntityType, MapTypes, SQLiteType } from "./types"; | ||
import "reflect-metadata"; | ||
export class QueryBuilder { | ||
static createTableSql(entityClass: any): string { | ||
const entityMetadata = Reflect.getMetadata('entity', entityClass); | ||
const entityMetadata = Reflect.getMetadata("entity", entityClass); | ||
if (!entityMetadata) { | ||
throw new Error('Entity metadata not found'); | ||
throw new Error("Entity metadata not found"); | ||
} | ||
@@ -20,7 +20,13 @@ const tableName = entityMetadata.name || entityClass.constructor.name; | ||
const getColumnMetadata = (target: any, propertyKey: string | symbol): ColumnOtps => { | ||
const getColumnMetadata = ( | ||
target: any, | ||
propertyKey: string | symbol | ||
): ColumnOtps => { | ||
return Reflect.getMetadata(COLUMN_METADATA_KEY, target, propertyKey); | ||
}; | ||
const getPrimaryKeyMetadata = (target: any, propertyKey: string | symbol): PrimaryKeyOpts => { | ||
const getPrimaryKeyMetadata = ( | ||
target: any, | ||
propertyKey: string | symbol | ||
): PrimaryKeyOpts => { | ||
return Reflect.getMetadata(PRIMARY_KEY_METADATA_KEY, target, propertyKey); | ||
@@ -33,3 +39,6 @@ }; | ||
const propertyMetadata = getColumnMetadata(entityInstance, propertyKey); | ||
const primaryKeyMetadata = getPrimaryKeyMetadata(entityInstance, propertyKey); | ||
const primaryKeyMetadata = getPrimaryKeyMetadata( | ||
entityInstance, | ||
propertyKey | ||
); | ||
@@ -44,3 +53,3 @@ if (propertyMetadata) { | ||
if (primaryKeyOptions.autoIncrement) { | ||
columnDefinition += ' PRIMARY KEY AUTOINCREMENT'; | ||
columnDefinition += " PRIMARY KEY AUTOINCREMENT"; | ||
} | ||
@@ -52,3 +61,5 @@ | ||
const createTableQuery = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns.join(', ')});`; | ||
const createTableQuery = `CREATE TABLE IF NOT EXISTS ${tableName} (${columns.join( | ||
", " | ||
)});`; | ||
@@ -58,18 +69,30 @@ return createTableQuery; | ||
static insertSql<TEntity>(entityObject: any, entityClass: EntityType<TEntity>): string { | ||
static insertSql<TEntity>( | ||
entityObject: any, | ||
entityClass: EntityType<TEntity> | ||
): string { | ||
const entityInstance = Object.assign(new entityClass(), entityObject); | ||
const tableName = MetadataExtractor.getEntityTableName(entityClass); | ||
const columns = EntityTransformer.transformClassInstanceToEntityColumns(entityInstance); | ||
const columns = | ||
EntityTransformer.transformClassInstanceToEntityColumns(entityInstance); | ||
const columnsNames = columns.map((column) => column.name); | ||
const values = columns.map((column) => EntityTransformer.valueQueryFormatter(column.value)); | ||
const values = columns.map((column) => | ||
EntityTransformer.valueQueryFormatter(column.value) | ||
); | ||
const insertQuery = `INSERT INTO ${tableName} (${columnsNames.join(', ')}) VALUES (${values.join(', ')});`; | ||
const insertQuery = `INSERT INTO ${tableName} (${columnsNames.join( | ||
", " | ||
)}) VALUES (${values.join(", ")});`; | ||
return insertQuery; | ||
} | ||
static updateSql<TEntity>(entityObject: any, entityClass: EntityType<TEntity>): string { | ||
static updateSql<TEntity>( | ||
entityObject: any, | ||
entityClass: EntityType<TEntity> | ||
): string { | ||
const entityInstance = Object.assign(new entityClass(), entityObject); | ||
const tableName = MetadataExtractor.getEntityTableName(entityClass); | ||
const columns = EntityTransformer.transformClassInstanceToEntityColumns(entityInstance); | ||
const columns = | ||
EntityTransformer.transformClassInstanceToEntityColumns(entityInstance); | ||
@@ -83,4 +106,4 @@ const setClause = columns | ||
}) | ||
.join(', '); | ||
.join(", "); | ||
const primaryKey = MetadataExtractor.getEntityPrimaryKey(new entityClass()); | ||
@@ -90,3 +113,3 @@ const id = (entityInstance as any)[primaryKey.propertyKey]; | ||
const updateQuery = `UPDATE ${tableName} SET ${setClause} WHERE ${primaryKey.columnName} = ${id};`; | ||
return updateQuery; | ||
@@ -104,3 +127,2 @@ } | ||
} | ||
} |
@@ -1,7 +0,7 @@ | ||
import { EntityTransformer } from './entity-transformer'; | ||
import { escapeValue } from './helper'; | ||
import { MetadataExtractor } from './metadata'; | ||
import { QueryBuilder } from './query-builder'; | ||
import { SQLiteDatabase } from './sqlite-database'; | ||
import { Transaction } from './transaction'; | ||
import { EntityTransformer } from "./entity-transformer"; | ||
import { escapeValue } from "./helper"; | ||
import { MetadataExtractor } from "./metadata"; | ||
import { QueryBuilder } from "./query-builder"; | ||
import { SQLiteDatabase } from "./sqlite-database"; | ||
import { Transaction } from "./transaction"; | ||
@@ -12,4 +12,6 @@ export class Repository<TEntity> { | ||
constructor( | ||
private readonly entityModel: new () => TEntity extends object ? TEntity : any, | ||
private readonly db: SQLiteDatabase, | ||
private readonly entityModel: new () => TEntity extends object | ||
? TEntity | ||
: any, | ||
private readonly db: SQLiteDatabase | ||
) { | ||
@@ -27,3 +29,3 @@ this.tableName = MetadataExtractor.getEntityTableName(entityModel); | ||
.map(([key, value]) => `${key} = ${escapeValue(value)}`) | ||
.join(' AND '); | ||
.join(" AND "); | ||
const query = `SELECT * FROM ${this.tableName} WHERE ${whereClause}`; | ||
@@ -39,3 +41,3 @@ const res = await this.db.query<TEntity>(query, this.entityModel); | ||
.map(([key, value]) => `${key} = ${escapeValue(value)}`) | ||
.join(' AND '); | ||
.join(" AND "); | ||
const query = `SELECT * FROM ${this.tableName} WHERE ${whereClause}`; | ||
@@ -57,3 +59,6 @@ const res = await this.db.query<TEntity>(query, this.entityModel); | ||
create(entity: TEntity extends {} ? TEntity : any, transaction?: Transaction): Promise<void> { | ||
create( | ||
entity: TEntity extends {} ? TEntity : any, | ||
transaction?: Transaction | ||
): Promise<void> { | ||
return new Promise((resolve, reject) => { | ||
@@ -60,0 +65,0 @@ const query = QueryBuilder.insertSql(entity as TEntity, this.entityModel); |
@@ -1,4 +0,4 @@ | ||
import * as sqlite3 from 'sqlite3'; | ||
import { EntityTransformer } from './entity-transformer'; | ||
import { EntityType } from './types'; | ||
import * as sqlite3 from "sqlite3"; | ||
import { EntityTransformer } from "./entity-transformer"; | ||
import { EntityType } from "./types"; | ||
@@ -42,3 +42,6 @@ export interface Result<T> { | ||
? rows.map((row) => { | ||
return EntityTransformer.transformSQLEntityToObject(new entityClass(), row); | ||
return EntityTransformer.transformSQLEntityToObject( | ||
new entityClass(), | ||
row | ||
); | ||
}) | ||
@@ -45,0 +48,0 @@ : rows.map((row) => { |
@@ -1,2 +0,2 @@ | ||
import { SQLiteDatabase } from './sqlite-database'; | ||
import { SQLiteDatabase } from "./sqlite-database"; | ||
@@ -10,3 +10,3 @@ export class Transaction { | ||
this.statemanets = []; | ||
this.statemanets.push('BEGIN TRANSACTION'); | ||
this.statemanets.push("BEGIN TRANSACTION"); | ||
return this; | ||
@@ -16,4 +16,4 @@ } | ||
commit(): void { | ||
this.statemanets.push('COMMIT'); | ||
this.db.sqliteInstance.exec(this.statemanets.join(';')); | ||
this.statemanets.push("COMMIT"); | ||
this.db.sqliteInstance.exec(this.statemanets.join(";")); | ||
} | ||
@@ -26,7 +26,9 @@ | ||
rollback(): void { | ||
this.statemanets.push('ROLLBACK'); | ||
this.db.sqliteInstance.exec(this.statemanets.join(';')); | ||
this.statemanets.push("ROLLBACK"); | ||
this.db.sqliteInstance.exec(this.statemanets.join(";")); | ||
} | ||
transaction<T>(callback: (transaction: Transaction) => Promise<T>): Promise<T> { | ||
transaction<T>( | ||
callback: (transaction: Transaction) => Promise<T> | ||
): Promise<T> { | ||
return new Promise(async (resolve, reject) => { | ||
@@ -33,0 +35,0 @@ this.begin(); |
@@ -5,3 +5,3 @@ import { RADIX } from "./constants"; | ||
static isJSONObject(value: any): boolean { | ||
return typeof value === 'object'; | ||
return typeof value === "object"; | ||
} | ||
@@ -14,15 +14,17 @@ | ||
static isString(value: any): boolean { | ||
return typeof value === 'string'; | ||
return typeof value === "string"; | ||
} | ||
static isNumber(value: any): boolean { | ||
return typeof value === 'number'; | ||
return typeof value === "number"; | ||
} | ||
static isBoolean(value: any): boolean { | ||
return typeof value === 'boolean'; | ||
return typeof value === "boolean"; | ||
} | ||
static isUUID(value: any): boolean { | ||
const regex = new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'); | ||
const regex = new RegExp( | ||
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" | ||
); | ||
return regex.test(value); | ||
@@ -40,3 +42,3 @@ } | ||
static parseBoolean(value: any): boolean { | ||
return value === 'true' || value === '1' || value === 1; | ||
return value === "true" || value === "1" || value === 1; | ||
} | ||
@@ -58,5 +60,5 @@ | ||
static generateUUIDv4(): string { | ||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { | ||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { | ||
const r = (Math.random() * 16) | 0; | ||
const v = c === 'x' ? r : (r & 0x3) | 0x8; | ||
const v = c === "x" ? r : (r & 0x3) | 0x8; | ||
return v.toString(16); | ||
@@ -63,0 +65,0 @@ }); |
@@ -12,4 +12,4 @@ export interface LilORMModuleOptions { | ||
export type SQLiteType = 'INTEGER' | 'TEXT' | 'REAL' | 'BLOB'; | ||
export type LilOrmTypeExtension = 'JSON' | 'BOOLEAN' | 'DATE' | 'UUID'; | ||
export type SQLiteType = "INTEGER" | "TEXT" | "REAL" | "BLOB"; | ||
export type LilOrmTypeExtension = "JSON" | "BOOLEAN" | "DATE" | "UUID"; | ||
@@ -19,12 +19,12 @@ export type LilORMType = SQLiteType | LilOrmTypeExtension; | ||
export const MapTypes = { | ||
INTEGER: 'INTEGER', | ||
TEXT: 'TEXT', | ||
REAL: 'REAL', | ||
BLOB: 'BLOB', | ||
JSON: 'TEXT', | ||
BOOLEAN: 'INTEGER', | ||
DATE: 'TEXT', | ||
UUID: 'TEXT', | ||
INTEGER: "INTEGER", | ||
TEXT: "TEXT", | ||
REAL: "REAL", | ||
BLOB: "BLOB", | ||
JSON: "TEXT", | ||
BOOLEAN: "INTEGER", | ||
DATE: "TEXT", | ||
UUID: "TEXT", | ||
}; | ||
export type EntityType<T> = new () => T extends object ? T : any; |
@@ -27,4 +27,5 @@ { | ||
"src/**/*.spec.ts", | ||
"src/**/*.test.ts" | ||
"src/**/*.test.ts", | ||
"./dist/**/*" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
162135
101
2607
137