diff --git a/d.ts/anydb-sql.d.ts b/d.ts/anydb-sql.d.ts index e6e28dc..76bcb34 100644 --- a/d.ts/anydb-sql.d.ts +++ b/d.ts/anydb-sql.d.ts @@ -10,21 +10,25 @@ declare module "anydb-sql" { module anydbSQL { export interface OrderByValueNode {} - export interface ColumnDefinition { + + interface Named { + name?: Name; + } + export interface ColumnDefinition extends Named { primaryKey?:boolean; dataType?:string; references?: {table:string; column: string} notNull?:boolean unique?:boolean + defaultValue?: Type } - export interface TableDefinition { - name:string - columns:Dictionary - has?:Dictionary<{from:string; many?:boolean}> + export interface TableDefinition { + name: Name + columns:{[CName in keyof Row]: ColumnDefinition} + has?:{[key: string]:{from:string; many?:boolean}} } - export interface QueryLike { query:string; values: any[] @@ -40,25 +44,12 @@ declare module "anydb-sql" { commitAsync():Promise } - export interface SubQuery { - select(node:Column):SubQuery - select(...nodes: any[]):SubQuery - where(...nodes:any[]):SubQuery - from(table:TableNode):SubQuery - from(statement:string):SubQuery - group(...nodes:any[]):SubQuery - order(criteria:OrderByValueNode):SubQuery - exists():BinaryNode - notExists(): BinaryNode; - notExists(subQuery:SubQuery):BinaryNode - } - interface Executable { get():Promise getWithin(tx:DatabaseConnection):Promise exec():Promise all():Promise - execWithin(tx:DatabaseConnection):Promise + execWithin(tx:DatabaseConnection):Promise allWithin(tx:DatabaseConnection):Promise toQuery():QueryLike; } @@ -66,14 +57,31 @@ declare module "anydb-sql" { interface Queryable { where(...nodes:any[]):Query delete():ModifyingQuery - select(...nodes:any[]):Query - selectDeep(...nodesOrTables:any[]):Query + select(n1: Column):Query + select( + n1: Column, + n2: Column):Query<{[N in N1]: T1} & {[N in N2]: T2}> + select( + n1: Column, + n2: Column, + n3: Column):Query<{[N in N1]: T1} & {[N in N2]: T2} & {[N in N3]: T3}> + select(...nodesOrTables:any[]):Query + + selectDeep(n1: Table):Query + selectDeep( + n1: Table, + n2: Table):Query<{[N in N1]: T1} & {[N in N2]: T2}> + selectDeep( + n1: Table, + n2: Table, + n3: Table):Query<{[N in N1]: T1} & {[N in N2]: T2} & {[N in N3]: T3}> + //selectDeep(...nodesOrTables:any[]):Query } export interface Query extends Executable, Queryable { from(table:TableNode):Query from(statement:string):Query - update(o:Dictionary):ModifyingQuery + update(o:{[key: string]:any}):ModifyingQuery update(o:{}):ModifyingQuery group(...nodes:any[]):Query order(...criteria:OrderByValueNode[]):Query @@ -81,6 +89,20 @@ declare module "anydb-sql" { offset(o:number):Query } + export interface SubQuery { + select(node:Column):SubQuery + select(...nodes: any[]):SubQuery + where(...nodes:any[]):SubQuery + from(table:TableNode):SubQuery + from(statement:string):SubQuery + group(...nodes:any[]):SubQuery + order(criteria:OrderByValueNode):SubQuery + exists():BinaryNode + notExists(): BinaryNode; + notExists(subQuery:SubQuery):BinaryNode + } + + export interface ModifyingQuery extends Executable { returning(...nodes:any[]):Query where(...nodes:any[]):ModifyingQuery @@ -102,10 +124,15 @@ declare module "anydb-sql" { interface DropQuery extends Executable { ifExists():Executable } - export interface Table extends TableNode, Queryable { + + type Columns = { + [Name in keyof T]: Column + } + type Table = TableNode & Queryable & Named & Columns & { + create():CreateQuery drop():DropQuery - as(name:string):Table + as(name:OtherName):Table update(o:any):ModifyingQuery insert(row:T):ModifyingQuery insert(rows:T[]):ModifyingQuery @@ -113,21 +140,24 @@ declare module "anydb-sql" { select(...nodes:any[]):Query from(table:TableNode):Query from(statement:string):Query - star():Column + star():Column subQuery():SubQuery eventEmitter:{emit:(type:string, ...args:any[])=>void on:(eventName:string, handler:Function)=>void} - columns:Column[] + columns:Column[] sql: SQL; alter():AlterQuery; indexes(): IndexQuery; } + + type Selectable = Table | Column + export interface AlterQuery extends Executable { - addColumn(column:Column): AlterQuery; + addColumn(column:Column): AlterQuery; addColumn(name: string, options:string): AlterQuery; - dropColumn(column: Column|string): AlterQuery; - renameColumn(column: Column, newColumn: Column):AlterQuery; - renameColumn(column: Column, newName: string):AlterQuery; + dropColumn(column: Column|string): AlterQuery; + renameColumn(column: Column, newColumn: Column):AlterQuery; + renameColumn(column: Column, newName: string):AlterQuery; renameColumn(name: string, newName: string):AlterQuery; rename(newName: string): AlterQuery } @@ -135,20 +165,20 @@ declare module "anydb-sql" { create(): IndexCreationQuery; create(indexName: string): IndexCreationQuery; drop(indexName: string): Executable; - drop(...columns: Column[]): Executable + drop(...columns: Column[]): Executable } export interface IndexCreationQuery extends Executable { unique(): IndexCreationQuery; using(name: string): IndexCreationQuery; - on(...columns: (Column|OrderByValueNode)[]): IndexCreationQuery; + on(...columns: (Column|OrderByValueNode)[]): IndexCreationQuery; withParser(parserName: string): IndexCreationQuery; fulltext(): IndexCreationQuery; spatial(): IndexCreationQuery; - } + } export interface SQL { functions: { - LOWER(c:Column):Column + LOWER(c:Column):Column } } @@ -157,7 +187,8 @@ declare module "anydb-sql" { or(node:BinaryNode):BinaryNode } - export interface Column { + export interface Column { + name: Name in(arr:T[]):BinaryNode in(subQuery:SubQuery):BinaryNode notIn(arr:T[]):BinaryNode @@ -169,30 +200,30 @@ declare module "anydb-sql" { lt(node:any):BinaryNode like(str:string):BinaryNode multiply:{ - (node:Column):Column - (n:number):Column + (node:Column):Column + (n:number):Column //todo check column names } isNull():BinaryNode isNotNull():BinaryNode - sum():Column - count():Column - count(name:string):Column - distinct():Column - as(name:string):Column + //todo check column names + sum():Column + count():Column + count(name:string):Column + distinct():Column + as(name:OtherName):Column ascending:OrderByValueNode descending:OrderByValueNode asc:OrderByValueNode desc:OrderByValueNode - name: string; } export interface AnydbSql extends DatabaseConnection { - define(map:TableDefinition):Table; + define(map:TableDefinition):Table; transaction(fn:(tx:Transaction)=>Promise):Promise - allOf(...tables:Table[]):any - models:Dictionary> - functions:{LOWER:(name:Column)=>Column - RTRIM:(name:Column)=>Column} + allOf(...tables:Table[]):any + models: {[key:string]: Table} + functions:{LOWER:(name:Column)=>Column + RTRIM:(name:Column)=>Column} makeFunction(name:string):Function begin():Transaction open():void; diff --git a/d.ts/test.ts b/d.ts/test.ts new file mode 100644 index 0000000..5b3feb7 --- /dev/null +++ b/d.ts/test.ts @@ -0,0 +1,49 @@ +import * as dbsql from 'anydb-sql' + +let db = dbsql({}); + +interface User { + id: string + name: string + created: Date +} + +let User = db.define<'User', User>({ + name: 'User', + columns: { + id: {name: 'id', dataType: 'string'}, + name: {name: 'name', dataType: 'string'}, + created: {name: 'created', dataType: 'date'} + } +}) + +interface Post { + id: string + name: string; + created: Date; + userId: string; +} + + +let Post = db.define<'Post', Post>({ + name: 'Post', + columns: { + id: {name: 'id', dataType: 'string'}, + name: {name: 'name', dataType: 'string'}, + created: {name: 'created', dataType: 'date'}, + userId: {name: 'userId', dataType: 'string'} + } +}) + + +let q2 = User.select(User.name) + +let q3 = User.where({id: 1}).select(User.name, User.id) + +q3.get().then(u => u.id) + +let q4 = User + .from(User.join(Post).on(User.id.equals(Post.userId))) + .selectDeep(User, Post) + +let all = q4.all().then(x => x[0].Post.created) diff --git a/package.json b/package.json index 278bc46..4efa92e 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "sql": "^0.45.3" }, "devDependencies": { + "@types/bluebird": "^3.0.36", "blue-tape": "^0.1.7", "sqlite3": "3.x" } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2b47831 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "noImplicitAny": true + } +} \ No newline at end of file