From 008ec0ef2ff0f69b9766c21894cd7c089ee39d08 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sat, 9 Mar 2024 10:30:43 +0100 Subject: [PATCH] feat(query_builder): add orderByRandom --- src/database/query_builder/database.ts | 21 +++++++++++++ src/types/querybuilder.ts | 1 + test/database/query_builder.spec.ts | 43 ++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/database/query_builder/database.ts b/src/database/query_builder/database.ts index 926712b5..3e4a567d 100644 --- a/src/database/query_builder/database.ts +++ b/src/database/query_builder/database.ts @@ -281,6 +281,27 @@ export class DatabaseQueryBuilder extends Chainable implements DatabaseQueryBuil return this } + /** + * Order results by random value. + */ + orderByRandom(seed = '') { + switch (this.client.dialect.name) { + case 'sqlite3': + case 'better-sqlite3': + case 'postgres': + case 'redshift': + return this.orderByRaw('RANDOM()') + case 'mysql': + return this.orderByRaw(`RAND(${seed})`) + case 'mssql': + return this.orderByRaw('NEWID()') + case 'oracledb': + return this.orderByRaw('dbms_random.value') + default: + throw new Error(`Cannot order by random for the given dialect ${this.client.dialect.name}`) + } + } + /** * Executes the query */ diff --git a/src/types/querybuilder.ts b/src/types/querybuilder.ts index dd23c2cb..04cf1d5e 100644 --- a/src/types/querybuilder.ts +++ b/src/types/querybuilder.ts @@ -651,6 +651,7 @@ export interface ChainableContract { orderBy: OrderBy orderByRaw: RawQueryFn + orderByRandom: (seed?: string) => this union: Union unionAll: UnionAll diff --git a/test/database/query_builder.spec.ts b/test/database/query_builder.spec.ts index b81e807e..eca7c1e5 100644 --- a/test/database/query_builder.spec.ts +++ b/test/database/query_builder.spec.ts @@ -5439,6 +5439,49 @@ test.group('Query Builder | orderByRaw', (group) => { }) }) +test.group('Query Builder | orderByRandom', (group) => { + group.setup(async () => { + await setup() + }) + + group.teardown(async () => { + await cleanup() + }) + + group.each.teardown(async () => { + await resetTables() + }) + + test('define order by random value', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), logger) + connection.connect() + + const db = getQueryBuilder(getQueryClient(connection)) + await getInsertBuilder(getQueryClient(connection)) + .table('users') + .multiInsert([ + { + username: 'virk', + email: 'virk@adonisjs.com', + }, + { + username: 'romain', + email: 'romain@adonisjs.com', + }, + { + username: 'nikk', + email: 'nikk@adonisjs.com', + }, + ]) + + const users = await db.from('users').orderByRandom() + const users2 = await db.from('users').orderByRandom() + + assert.notEqual(users[0].id, users2[0].id) + await connection.disconnect() + }).retry(3) +}) + test.group('Query Builder | offset', (group) => { group.setup(async () => { await setup()