Skip to content

Commit

Permalink
Added attach
Browse files Browse the repository at this point in the history
  • Loading branch information
drodrigues4 committed Jul 24, 2024
1 parent f662fb4 commit 4a15249
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drizzle-orm/src/singlestore-core/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
import type { WithSubqueryWithSelection } from './subquery.ts';
import type { SingleStoreTable } from './table.ts';
import { SingleStoreDetachBase } from './query-builders/detach.ts';
import { SingleStoreAttachBase } from './query-builders/attach.ts';

export class SingleStoreDatabase<
TQueryResult extends SingleStoreQueryResultHKT,
Expand Down Expand Up @@ -480,6 +481,12 @@ export class SingleStoreDatabase<
): SingleStoreDetachBase<TDatabase, TQueryResult, TPreparedQueryHKT> {
return new SingleStoreDetachBase(database, this.session, this.dialect);
}

attach<TDatabase extends string>(
database: TDatabase,
): SingleStoreAttachBase<TDatabase, TQueryResult, TPreparedQueryHKT> {
return new SingleStoreAttachBase(database, this.session, this.dialect);
}
}

export type SingleStoreWithReplicas<Q> = Q & { $primary: Q };
Expand Down
7 changes: 7 additions & 0 deletions drizzle-orm/src/singlestore-core/dialect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type { SingleStoreSession } from './session.ts';
import { SingleStoreTable } from './table.ts';
import { SingleStoreViewBase } from './view-base.ts';
import type { SingleStoreDetachConfig } from './query-builders/detach.ts';
import type { SingleStoreAttachConfig } from './query-builders/attach.ts';

export class SingleStoreDialect {
static readonly [entityKind]: string = 'SingleStoreDialect';
Expand Down Expand Up @@ -125,6 +126,12 @@ export class SingleStoreDialect {
return sql`detach database ${database}${milestoneSql}${workspaceSql}`;
}

buildAttachQuery({ database, milestone }: SingleStoreAttachConfig): SQL {
const milestoneSql = milestone ? sql` at milestone ${milestone}` : undefined;

return sql`attach database ${database}${milestoneSql}`;
}

buildUpdateSet(table: SingleStoreTable, set: UpdateSet): SQL {
const tableColumns = table[Table.Symbol.Columns];

Expand Down
164 changes: 164 additions & 0 deletions drizzle-orm/src/singlestore-core/query-builders/attach.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { entityKind } from '~/entity.ts';
import { QueryPromise } from '~/query-promise.ts';
import type { SingleStoreDialect } from '~/singlestore-core/dialect.ts';
import type {
AnySingleStoreQueryResultHKT,
PreparedQueryHKTBase,
PreparedQueryKind,
SingleStorePreparedQueryConfig,
SingleStoreQueryResultHKT,
SingleStoreQueryResultKind,
SingleStoreSession,
} from '~/singlestore-core/session.ts';
import type { Query, SQL, SQLWrapper } from '~/sql/sql.ts';

export type SingleStoreAttachWithout<
T extends AnySingleStoreAttachBase,
TDynamic extends boolean,
K extends keyof T & string,
> = TDynamic extends true ? T
: Omit<
SingleStoreAttachBase<
T['_']['database'],
T['_']['queryResult'],
T['_']['preparedQueryHKT'],
TDynamic,
T['_']['excludedMethods'] | K
>,
T['_']['excludedMethods'] | K
>;

export type SingleStoreAttach<
TDatabase extends string = string,
TQueryResult extends SingleStoreQueryResultHKT = AnySingleStoreQueryResultHKT,
TPreparedQueryHKT extends PreparedQueryHKTBase = PreparedQueryHKTBase,
> = SingleStoreAttachBase<TDatabase, TQueryResult, TPreparedQueryHKT, true, never>;

export interface SingleStoreAttachConfig {
milestone?: string | undefined;
database: string;
}

export type SingleStoreAttachPrepare<T extends AnySingleStoreAttachBase> = PreparedQueryKind<
T['_']['preparedQueryHKT'],
SingleStorePreparedQueryConfig & {
execute: SingleStoreQueryResultKind<T['_']['queryResult'], never>;
iterator: never;
},
true
>;

type SingleStoreAttachDynamic<T extends AnySingleStoreAttachBase> = SingleStoreAttach<
T['_']['database'],
T['_']['queryResult'],
T['_']['preparedQueryHKT']
>;

type AnySingleStoreAttachBase = SingleStoreAttachBase<any, any, any, any, any>;

export interface SingleStoreAttachBase<
TDatabase extends string,
TQueryResult extends SingleStoreQueryResultHKT,
TPreparedQueryHKT extends PreparedQueryHKTBase,
TDynamic extends boolean = false,
TExcludedMethods extends string = never,
> extends QueryPromise<SingleStoreQueryResultKind<TQueryResult, never>> {
readonly _: {
readonly database: TDatabase;
readonly queryResult: TQueryResult;
readonly preparedQueryHKT: TPreparedQueryHKT;
readonly dynamic: TDynamic;
readonly excludedMethods: TExcludedMethods;
};
}

export class SingleStoreAttachBase<
TDatabase extends string,
TQueryResult extends SingleStoreQueryResultHKT,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TPreparedQueryHKT extends PreparedQueryHKTBase,
TDynamic extends boolean = false,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
TExcludedMethods extends string = never,
> extends QueryPromise<SingleStoreQueryResultKind<TQueryResult, never>> implements SQLWrapper {
static readonly [entityKind]: string = 'SingleStoreAttach';

private config: SingleStoreAttachConfig;

constructor(
private database: TDatabase,
private session: SingleStoreSession,
private dialect: SingleStoreDialect,
) {
super();
this.config = { database };
}

/**
* Adds a `where` clause to the query.
*
* Calling this method will delete only those rows that fulfill a specified condition.
*
* See docs: {@link https://orm.drizzle.team/docs/delete}
*
* @param where the `where` clause.
*
* @example
* You can use conditional operators and `sql function` to filter the rows to be deleted.
*
* ```ts
* // Attach all cars with green color
* db.delete(cars).where(eq(cars.color, 'green'));
* // or
* db.delete(cars).where(sql`${cars.color} = 'green'`)
* ```
*
* You can logically combine conditional operators with `and()` and `or()` operators:
*
* ```ts
* // Attach all BMW cars with a green color
* db.delete(cars).where(and(eq(cars.color, 'green'), eq(cars.brand, 'BMW')));
*
* // Attach all cars with the green or blue color
* db.delete(cars).where(or(eq(cars.color, 'green'), eq(cars.color, 'blue')));
* ```
*/
atMilestone(milestone: string | undefined): SingleStoreAttachWithout<this, TDynamic, 'atMilestone'> {
this.config.milestone = milestone;
return this as any;
}

/** @internal */
getSQL(): SQL {
return this.dialect.buildAttachQuery(this.config);
}

toSQL(): Query {
const { typings: _typings, ...rest } = this.dialect.sqlToQuery(this.getSQL());
return rest;
}

prepare(): SingleStoreAttachPrepare<this> {
return this.session.prepareQuery(
this.dialect.sqlToQuery(this.getSQL()),
undefined,
) as SingleStoreAttachPrepare<this>;
}

override execute: ReturnType<this['prepare']>['execute'] = (placeholderValues) => {
return this.prepare().execute(placeholderValues);
};

private createIterator = (): ReturnType<this['prepare']>['iterator'] => {
const self = this;
return async function*(placeholderValues) {
yield* self.prepare().iterator(placeholderValues);
};
};

iterator = this.createIterator();

$dynamic(): SingleStoreAttachDynamic<this> {
return this as any;
}
}

0 comments on commit 4a15249

Please sign in to comment.