From 9b6784d914adbb3c174e73ea1fc4467d43cfff9d Mon Sep 17 00:00:00 2001 From: karak Date: Mon, 5 Jun 2017 06:16:58 +0900 Subject: [PATCH] Firebird (#16933) * Added 'firebird' package * Fixed all of the errors from dtslint * Modify tslint.json in dts-gen form * Fixed more tslint errors. * Validate whitespace rules(CI-only) --- types/firebird/firebird-tests.ts | 122 ++++++++ types/firebird/index.d.ts | 501 +++++++++++++++++++++++++++++++ types/firebird/tsconfig.json | 23 ++ types/firebird/tslint.json | 1 + 4 files changed, 647 insertions(+) create mode 100644 types/firebird/firebird-tests.ts create mode 100644 types/firebird/index.d.ts create mode 100644 types/firebird/tsconfig.json create mode 100644 types/firebird/tslint.json diff --git a/types/firebird/firebird-tests.ts b/types/firebird/firebird-tests.ts new file mode 100644 index 0000000000..4a6bd59c05 --- /dev/null +++ b/types/firebird/firebird-tests.ts @@ -0,0 +1,122 @@ +import * as fb from "firebird"; + +/* createConnection */ +let con: fb.Connection = fb.createConnection(); + +/* Connection */ +con = new fb.Connection(); + +con.connectSync('test.fdb', 'sysdba', 'masterkey', ''); +con.connect('test.fdb', 'sysdba', 'masterkey', '', (err: Error | null) => {}); + +if (con.connected === true) { + console.log('connected'); +} + +con.querySync("insert into test (id,name) values (5, 'new one')"); +const res: fb.FBResult = con.querySync("select * from test"); +con.query("select * from test", (err: Error | null, res: fb.FBResult) => {}); + +con.commitSync(); +con.commit((err: Error | null) => {}); + +con.rollbackSync(); +con.rollback((err: Error | null) => {}); + +con.startSync(); +con.start((err: Error | null) => {}); + +let stmt: fb.FBStatement = con.prepareSync("select * from test where name = ?"); + +if (con.inTransaction === true) { + console.log('in transaction'); +} + +let blob: fb.FBBlob = con.newBlobSync(); + +let tx: fb.Transaction = con.startNewTransactionSync(); +con.startNewTransaction((err: Error | null, tx: fb.Transaction) => {}); + +/* DataType */ +let column: fb.DataType = {}; +if (typeof (column) === "number") { + column * 10; +} else if (typeof (column) === "string") { + column.substring(0, 1); +} else if (column instanceof Date) { + column.toISOString(); +} else { + let _: fb.FBBlob = column; +} + +/* FBResult */ +interface MyRow { + id: number; + name: string; +} + +let rowsArray: fb.DataType[][] = res.fetchSync("all", false); +rowsArray = res.fetchSync(1, false); +res.fetch("all", false, (row: fb.DataType[]) => {}, (err: Error | null, eof: boolean) => {}); +res.fetch(1, false, (row: fb.DataType[]) => {}, (err: Error | null, eof: boolean) => {}); +let rowsObject: Array<{[colmn: string]: fb.DataType}> = res.fetchSync("all", true); +rowsObject = res.fetchSync(1, true); +res.fetch("all", true, (row: {[colmn: string]: fb.DataType}) => {}, (err: Error | null, eof: boolean) => {}); +res.fetch(1, true, (row: {[colmn: string]: fb.DataType}) => {}, (err: Error | null, eof: boolean) => {}); +let rowsTyped: MyRow[] = res.fetchSync("all", true); +rowsTyped = res.fetchSync(1, true); +res.fetch("all", true, (row: MyRow) => {}, (err: Error | null, eof: boolean) => {}); +res.fetch(1, true, (row: MyRow) => {}, (err: Error | null, eof: boolean) => {}); + +/* Transaction */ +tx.querySync("insert into test (id,name) values (5, 'new one')"); +tx.query("select * from test", (err: Error | null, res: fb.FBResult) => {}); + +tx.commitSync(); +tx.commit((err: Error | null) => {}); + +tx.rollbackSync(); +tx.rollback((err: Error | null) => {}); + +tx.startSync(); +tx.start((error: Error | null) => {}); +stmt = tx.prepareSync("select * from test where name = ?"); + +if (tx.inTransaction === true) { + console.log('in transaction'); +} + +/* FBStatement */ +let asFBResult: fb.FBResult = stmt; +stmt.execSync("John"); +stmt.execSync(1, "Mary"); +stmt.execInTransSync(tx, "John"); +stmt.execInTransSync(tx, 1, "Mary"); +stmt.exec("John"); +stmt.exec(1, "Mary"); +stmt.execInTrans(tx, "John"); +stmt.execInTrans(tx, 1, "Mary"); + +/* FBBlob */ +blob._openSync(); + +blob._closeSync(); + +let buffer: Buffer = {}; +let readBytes: number = blob._readSync(buffer); +blob._read(buffer, (err: Error | null, buffer: Buffer, len: number) => {}); + +blob._readAll(); +blob._readAll(10); +blob._readAll(10, 20); +blob._readAll(10, (err: Error | null, buffer: Buffer, len: number) => {}); +blob._readAll(10, 20, (err: Error | null, buffer: Buffer, len: number) => {}); + +let writtenBytes = blob._writeSync(buffer); +writtenBytes = blob._writeSync(buffer, 10); +blob._write(buffer); +blob._write(buffer, 10); +blob._write(buffer, 10, (err: Error | null) => {}); + +/* Stream */ +let strm: NodeJS.ReadWriteStream = new fb.Stream(blob); diff --git a/types/firebird/index.d.ts b/types/firebird/index.d.ts new file mode 100644 index 0000000000..6506762408 --- /dev/null +++ b/types/firebird/index.d.ts @@ -0,0 +1,501 @@ +// Type definitions for firebird 0.1 +// Project: https://github.com/xdenser/node-firebird-libfbclient +// Definitions by: Yasushi Kato +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.1 + +/// + +/** + * This is a type declaration file for 'firebird' package. + * + * Original document is [here](https://www.npmjs.com/package/firebird). + */ +declare module 'firebird' { + /** + * @see createConnection() method will create Firebird Connection object for you + */ + function createConnection(): Connection; + + /** + * Handles database connection and queries. Supports Synchronous and Asynchronous operation. + */ + class Connection { + constructor(); + + /** + * Connects you to database, + * + * @param database a database name in Firebird notation, i.e. : + * @param username user name + * @param pasword + * @param role + * + * @throws raises exception on error (try to catch it). + */ + connectSync(db: string, user: string, pass: string, role: string): void; + + /** + * Asynchronously connects you to Database. + * + * @param database a database name in Firebird notation, i.e. : + * @param username user name + * @param pasword + * @param role + * @param callback function(err), where err is error object in case of error. + */ + connect(db: string, user: string, pass: string, role: string, callback: (err: Error | null) => void): void; + + /** + * A boolean readonly property indicating if Connection object is connected to database + */ + connected: boolean; + + /** + * Executes SQL query. + * @param sql an SQL query to execute. + * @return object in case of success. + * @throws Raises error otherwise. + */ + querySync(sql: string): FBResult; + + /** + * Asynchronously executes query. + * + * @param sql an SQL query to execute. + * @param callback function(err,res), err - is error object or null, res - FBResult object. + */ + query(sql: string, callback: (err: Error | null, res: FBResult) => void): void; + + /** + * Registers connection to listen for firebird event name, called from PL\SQL (in stored procedures or triggers) with post_event 'name'. + * + * @desc + * You may set callback for event with + * @code connection.on('fbevent', function(name, count){ ));. + * Where name is event name, and count is number of times event were posted. + * + * @param name Firebird Event Name. + */ + addFBevent(name: string): void; + + /** + * Unsubscribes connection from getting events for name. + * + * @param name Firebird Event Name. + */ + deleteFBevent(name: string): void; + + /** + * @summary + * Synchronously commits current transaction. + * + * @desc + * Notes: + * There is only one transaction associated with connection. + * Transacation is automatically started before any query if connection does not have active transaction (check @see inTransaction property). + * You also should note that DDL statements (altering database structure) are commited automatically. + * To run quieries in context of other transaction use @see Transaction object. + */ + commitSync(): void; + + /** + * Asynchronous commit transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + commit(callback: (err: Error | null) => void): void; + + /** + * Synchronously rollbacks current transaction. + * + * @desc + * Read notes in @see commitSync() . + */ + rollbackSync(): void; + + /** + * Asynchronously rollbacks current transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + rollback(callback: (err: Error | null) => void): void; + + /** + * Synchronously starts new default transaction. + * + * @desc + * The default transaction should be not in started state before call to this method. + * Read notes in @see commitSync() . + */ + startSync(): void; + + /** + * Asynchronously starts new default transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + start(callback: (err: Error | null) => void): void; + + /**Synchronously prepares SQL statement and returns FBStatement object. + * + * @param sql an SQL query to prepare. + */ + prepareSync(sql: string): FBStatement; + + /** + * A boolean readonly property indicating if connection is in started transaction state. + */ + inTransaction: boolean; + + /** + * Creates new FBblob object and opens it for write. + * After finishing write operation and closing blob one may insert it in database passing as parameter to exec, + * execSync methods of @see FBStatement object. + */ + newBlobSync(): FBBlob; + + /** + * Creates new Transaction object and starts new transaction. + * @returns created object. + */ + startNewTransactionSync(): Transaction; + + /** + * Creates new Transaction object and starts new transaction. + * + * @param callback function(err, transaction), where err is error object in case of error, transaction - newly created transaction. + */ + startNewTransaction(callback: (err: Error | null, transaction: Transaction) => void): void; + } + + /** + * @desc + * Here is Firebird to Node data type accordance: + * + * | Firebird | Node | + * | :------- | :-------- | + * | DATE | Date | + * | TIME | Date | + * | TIMESTAMP | Date | + * | CHAR | String | + * | VARCHAR | String | + * | SMALLINT | Integer| + * | INTEGER | Integer| + * | NUMERIC | Number | + * | DECIMAL | Number | + * | FLOAT | Number | + * | DOUBLE | Number | + * | BLOB | FBblob | + */ + type DataType = Date | string /*| Integer*/ | number | FBBlob; + + /** + * Represents results of SQL query if any. + * You should use this object to fetch rows from database. + * Each row may be represented as array of field values or as object with named fields. + * + * @see DataType + */ + class FBResult { + /** + * @summary + * Synchronously fetches result rows. + * + * @desc + * If you pass "all" as rowCount - it will fetch all result rows. + * If you pass less rowCount than are actually in result, it will return specified number of rows. + * You may call fetchSync multiple times until all rows will be fetched. + * If you specify more rowCount than available it will return only actual number of rows. + * + * @param rowCount number of rows to fetch from results; + * @param asObject format of returned rows. When false - methods returns array of array, when true - array of objects. + */ + fetchSync(rowCount: number | "all", asObject: boolean): DataType[][] | Array<{[column: string]: DataType}>; + fetchSync(rowCount: number | "all", asObject: false): DataType[][]; + fetchSync(rowCount: number | "all", asObject: true): Array<{[column: string]: DataType}>; + fetchSync(rowCount: number | "all", asObject: true): T[]; + + /** + * Asynchronously fetches rows one by one. + * + * @param rowCount number of rows to fetch from results + * @param asObject format of returned rows. When false - methods returns array of array, when true - array of objects + * @param rowCallback function(row), row - Array or Object (depends on asObject parameter) representing single row from result; called for each fetched row. + * @param eofCallback function(err,eof), err - Error object in case of error, or null; eof - true | false. called when whole operation is complete. + */ + fetch(rowCount: number | "all", asObject: boolean, rowCallback: (row: DataType[]| {[column: string]: DataType}) => void, eofCallback: (err: Error | null, eof: boolean) => void): void; + fetch(rowCount: number | "all", asObject: false, rowCallback: (row: DataType[]) => void, eofCallback: (err: Error | null, eof: boolean) => void): void; + fetch(rowCount: number | "all", asObject: true, rowCallback: (row: {[column: string]: DataType}) => void, eofCallback: (err: Error | null, eof: boolean) => void): void; + fetch(rowCount: number | "all", asObject: true, rowCallback: (row: T) => void, eofCallback: (err: Error | null, eof: boolean) => void): void; + } + + /** + * Represents SQL transaction. + * + * @desc + * To get instance of this object call @see startNewTransactionSync or @see startNewTransaction methods of @see Connection object. + * Transaction objects may be reused after commit or rollback. + */ + interface Transaction { + /** + * Executes SQL query in context of this transaction. Returns FBResult object in case of success. Raises error otherwise. + * + * @param sql an SQL query to execute. + */ + querySync(sql: string): void; + + /** + * Asynchronously executes query in context of this transaction. + * + * @param sql an SQL query to execute. + * @param callback err - is error object or null, res - FBResult object. + */ + query(sql: string, callback: (err: Error | null, res: FBResult) => void): void; + + /** + * Synchronously commits this transaction. + * + * @desc + * Notes: + * Transacation is automatically started before any query in context of this object + * if this object does not have active transaction (check inTransaction property). + * You also should note that DDL statements (altering database structure) are commited automatically. + */ + commitSync(): void; + + /** + * Asynchronous commit transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + commit(callback: (err: Error | null) => void): void; + + /** + * Synchronously rollbacks transaction. + * + * @desc + * Read notes in @see commitSync() . + */ + rollbackSync(): void; + + /** + * Asynchronously rollbacks transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + rollback(callback: (err: Error | null) => void): void; + + /** + * Synchronously starts transaction. + * + * @desc + * The transaction should be not in started state before call to this method. + * Read notes in @see commitSync() . + * See @see inTransaction property. + */ + startSync(): void; + + /** + * Asynchronously starts new transaction. + * + * @desc + * Read notes in @see commitSync() . + * + * @param callback function(err), where err is error object in case of error. + */ + start(callback: (err: Error | null) => void): void; + + /** + * Synchronously prepares SQL statement + * + * @param sql an SQL query to prepare. + * @returns @see FBStatement object in context of this transaction. + */ + prepareSync(sql: string): FBStatement; + + /* + * A boolean readonly property indicating if this transaction is in started state. + */ + inTransaction: boolean; + } + + /** + * Represents prepared SQL query (returned by @see Connection.prepare() and @see Connection.prepareSync()). + * + * @see FBStatement is derived form @see FBResult class. + * So it can fetch rows just like @see FBresult object after call to @see execSync, exec methods. + */ + class FBStatement extends FBResult { + /** + * Synchronously executes prepared statement with given parameters. + * + * @desc + * You may fetch rows with methods inherited from @see FBResult. + * @see Statement is executed in context of default connection transaction. + * + * @param params parameters of prepared statement in the same order as in SQL and with appropriate types. + */ + execSync(...params: DataType[]): void; + + /** + * Same as @see execSync but executes statement in context of given @see Transaction obejct. + * + * @param transaction + * @param params + */ + execInTransSync(transaction: Transaction, ...params: DataType[]): void; + + /** + * Asynchronously executes prepared statement with given parameters. + * + * @desc + * @see FBStatement emits 'result' or 'error' event. + * You may fetch rows with methods inherited from @see FBResult after 'result' event emitted. + * Statement is executed in context of default connection transaction. + * + * @param params parameters of prepared statement in the same order as in SQL and with appropriate types. + */ + exec(...params: DataType[]): void; + + /** + * Same as @see exec but executes statement in context of given @see Transaction obejct. + * + * @param transaction + * @param params + */ + execInTrans(transaction: Transaction, ...params: DataType[]): void; + } + + /** + * Represents BLOB data type. + */ + interface FBBlob { + /** + * Synchronously opens blob for reading. + */ + _openSync(): void; + + /** + * Synchronously closes previously opened blob. + */ + _closeSync(): void; + + /** + * Synchronously reads BLOB segment (chunk) into buffer. Tries to fill whole buffer with data. + * + * @param buffer Node buffer to fill with data. + * @returns actual number of bytes read. + */ + _readSync(buffer: Buffer): number; + + /** + * Asynchronously reads BLOB segment (chunk) into buffer. Tries to fill whole buffer with data. + * + * @param buffer Node buffer to fill with data. + * @param callback function(err,buffer,len), err - Error object in case of error, or null;buffer - buffer filled with data; len - actual data length. + */ + _read(buffer: Buffer, callback: (err: Error | null, buffer: Buffer, len: number) => void): void; + + /** + * Asynchronously reads all data from BLOB field. + * Object emits events while reading data error, drain',end`. + * + * @param initialSize - optional, initial result buffer to allocate, default = 0 + * @param chunkSize - optional, size of chunk used to read data, default = 1024 + * @param callback - optional, function (err, buffer, len), err - Error object in case of error, or null;buffer - buffer filled with data; len - actual data length. + */ + _readAll(initialSize?: number, chunkSize?: number, callback?: (err: Error | null, buffer: Buffer, len: number) => void): void; + _readAll(initialSize: number, callback: (err: Error | null, buffer: Buffer, len: number) => void): void; + _readAll(callback: (err: Error | null, buffer: Buffer, len: number) => void): void; + + /** + * Synchronously writes BLOB segment (chunk) from buffer. + * + * @param buffer Node buffer to write from to blob; + * @param len optional length parameter, if specified only len bytes from buffer will be writen. + * @returns number of bytes actually writen. + */ + _writeSync(buffer: Buffer, len?: number): number; + + /** + * Asynchronously writes BLOB segment (chunk) from buffer and calls callback function if any. + * + * @param buffer Node buffer to write from to blob; + * @param len optional length parameter, if specified only len bytes from buffer will be writen. + * @param callback function(err), err - Error object in case of error, or null; + */ + _write(buffer: Buffer, len?: number, callback?: (err: Error | null) => void): void; + } + + /** + * Represents BLOB stream. + * + * @desc + * Create BLOB stream using + * @code var strm = new fb.Stream(FBblob);. + * + * You may pipe strm to/from NodeJS Stream objects (fs or socket). + * You may also look at [NodeJS Streams reference](https://nodejs.org/api/stream.html). + */ + class Stream implements NodeJS.ReadWriteStream { + constructor(blob: FBBlob); + + /* Following lines is JUST AS NodeJS.ReadStream, NodeJS.WriteStream, and NodeJS.Emmiter */ + /* tslint:disable */ + + /* NodeJS.ReadStream */ + readable: boolean; + read(size?: number): string | Buffer; + setEncoding(encoding: string | null): this; + pause(): this; + resume(): this; + isPaused(): boolean; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): this; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + + /* NodeJS.WriteStream */ + writable: boolean; + write(buffer: Buffer | string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + + /* EventEmitter */ + addListener(event: string | symbol, listener: Function): this; + on(event: string | symbol, listener: Function): this; + once(event: string | symbol, listener: Function): this; + removeListener(event: string | symbol, listener: Function): this; + removeAllListeners(event?: string | symbol): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string | symbol): Function[]; + emit(event: string | symbol, ...args: any[]): boolean; + listenerCount(type: string | symbol): number; + prependListener(event: string | symbol, listener: Function): this; + prependOnceListener(event: string | symbol, listener: Function): this; + eventNames(): (string | symbol)[]; + + /* tslint:enable */ + } +} diff --git a/types/firebird/tsconfig.json b/types/firebird/tsconfig.json new file mode 100644 index 0000000000..705913437a --- /dev/null +++ b/types/firebird/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "scripthost" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "firebird-tests.ts" + ] +} diff --git a/types/firebird/tslint.json b/types/firebird/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/firebird/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }