diff --git a/types/__test__.ts b/types/__test__.ts index 6d0d1bfc..1a22b6e1 100644 --- a/types/__test__.ts +++ b/types/__test__.ts @@ -88,3 +88,30 @@ const db = new DataSource('db', {connector: 'memory'}); await ctx.Model.expire('key', 100); }); }); + +//------- +// DataSource supports different `execute` styles +//------- +(async function () { + // SQL style + const tx = await db.beginTransaction(); + await db.execute('SELECT * FROM Product WHERE count > ?', [10], { + transaction: tx, + }); + await tx.commit(); + + // MongoDB style + await db.execute('MyCollection', 'aggregate', [ + {$lookup: { /* ... */ }}, + {$unwind: '$data'}, + {$out: 'tempData'} + ]); + + // Neo4J style + await db.execute({ + query: 'MATCH (u:User {email: {email}}) RETURN u', + params: { + email: 'alice@example.com', + }, + }); +}); diff --git a/types/datasource.d.ts b/types/datasource.d.ts index bf602976..ca128cc1 100644 --- a/types/datasource.d.ts +++ b/types/datasource.d.ts @@ -300,12 +300,94 @@ export declare class DataSource extends EventEmitter { ping(callback: Callback): void; // Only promise variant, callback is intentionally not supported. + + /** + * Execute a SQL command. + * + * **WARNING:** In general, it is always better to perform database actions + * through repository methods. Directly executing SQL may lead to unexpected + * results, corrupted data, security vulnerabilities and other issues. + * + * @example + * + * ```ts + * // MySQL + * const result = await db.execute( + * 'SELECT * FROM Products WHERE size > ?', + * [42] + * ); + * + * // PostgreSQL + * const result = await db.execute( + * 'SELECT * FROM Products WHERE size > $1', + * [42] + * ); + * ``` + * + * @param command A parameterized SQL command or query. + * Check your database documentation for information on which characters to + * use as parameter placeholders. + * @param parameters List of parameter values to use. + * @param options Additional options, for example `transaction`. + * @returns A promise which resolves to the command output as returned by the + * database driver. The output type (data structure) is database specific and + * often depends on the command executed. + */ execute( command: string | object, - args?: any[] | object, + parameters?: any[] | object, options?: Options, ): Promise; + /** + * Execute a MongoDB command. + * + * **WARNING:** In general, it is always better to perform database actions + * through repository methods. Directly executing MongoDB commands may lead + * to unexpected results and other issues. + * + * @example + * + * ```ts + * const result = await db.execute('MyCollection', 'aggregate', [ + * {$lookup: { + * // ... + * }}, + * {$unwind: '$data'}, + * {$out: 'tempData'} + * ]); + * ``` + * + * @param collectionName The name of the collection to execute the command on. + * @param command The command name. See + * [Collection API docs](http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html) + * for the list of commands supported by the MongoDB client. + * @param parameters Command parameters (arguments), as described in MongoDB API + * docs for individual collection methods. + * @returns A promise which resolves to the command output as returned by the + * database driver. + */ + execute( + collectionName: string, + command: string, + ...parameters: any[], + ): Promise; + + /** + * Execute a raw database command using a connector that's not described + * by LoopBack's `execute` API yet. + * + * **WARNING:** In general, it is always better to perform database actions + * through repository methods. Directly executing database commands may lead + * to unexpected results and other issues. + * + * @param args Command and parameters, please consult your connector's + * documentation to learn about supported commands and their parameters. + * @returns A promise which resolves to the command output as returned by the + * database driver. + */ + execute(...args: any[]): Promise; + /** * Begin a new transaction. *