Skip to content
Merged

Dev #74

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 37 additions & 37 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@swc/core": "^1.15.18",
"@swc/helpers": "^0.5.19",
"@types/mocha": "^10.0.10",
"@types/node": "^25.4.0",
"@types/node": "^25.5.0",
"@types/sinon": "^21.0.0",
"c8": "^11.0.0",
"globals": "^17.4.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/builder/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@sqb/builder",
"description": "Extensible multi-dialect SQL query builder written with TypeScript",
"version": "4.23.3",
"version": "4.24.0",
"author": "Panates",
"private": false,
"license": "Apache-2.0",
Expand Down
24 changes: 21 additions & 3 deletions packages/builder/src/query/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { GenerateOptions, GenerateResult } from '../types.js';
export declare interface Query extends EventEmitter {}

export abstract class Query extends Serializable {
protected _comment?: string;
protected _commentDialect?: string[];
protected _params?: Record<string, any>;

constructor() {
Expand All @@ -19,14 +21,24 @@ export abstract class Query extends Serializable {
* Generates Sql script
*/
generate(options?: GenerateOptions): GenerateResult {
const ctx = new SerializeContext(options);
const ctx = new SerializeContext(this, options);
if (this._params) ctx.params = { ...ctx.params, ...this._params };
ctx.serializeHooks = this.listeners('serialize');

/* generate output */
const sql = this._serialize(ctx);
let sql = this._serialize(ctx);
sql = flattenText(sql, { noWrap: !ctx.prettyPrint });
if (
this._comment &&
(!ctx.dialect ||
!this._commentDialect ||
this._commentDialect.includes(ctx.dialect))
) {
const lines = '-- ' + this._comment.split('\n').join('\n-- ') + '\n';
sql = lines + sql;
}
return {
sql: flattenText(sql, { noWrap: !ctx.prettyPrint }),
sql,
params: ctx.preparedParams,
paramOptions: ctx.paramOptions,
returningFields: ctx.returningFields,
Expand All @@ -39,6 +51,12 @@ export abstract class Query extends Serializable {
this._params = obj;
return this;
}

comment(text: string, dialect?: string[]): this {
this._comment = text;
this._commentDialect = dialect;
return this;
}
}

merge(Query.prototype, EventEmitter.prototype, { descriptor: true });
6 changes: 5 additions & 1 deletion packages/builder/src/serialize-context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SerializationType } from './enums.js';
import { SerializerRegistry } from './extensions.js';
import type { Query } from './query/query.js';
import { Serializable } from './serializable.js';
import { isLogicalOperator, isQuery, isSerializable } from './typeguards.js';
import {
Expand Down Expand Up @@ -79,7 +80,10 @@ export class SerializeContext implements GenerateOptions {
returningFields?: { field: string; alias?: string }[];
strictParamGenId?: number;

constructor(opts?: GenerateOptions) {
constructor(
readonly rootQuery: Query,
opts?: GenerateOptions,
) {
if (opts) Object.assign(this, opts);
}

Expand Down
14 changes: 14 additions & 0 deletions packages/builder/test/query-objects/select-query.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,18 @@ describe('builder:serialize "SelectQuery"', () => {
query.generate();
}).toThrow('Alias required for sub-select in "from"');
});

it('should serialize comment', () => {
const query = Select().comment('This is a comment');
const result = query.generate(options);
expect(result.sql).toStrictEqual('-- This is a comment\nselect *');
});

it('should serialize multiline comment', () => {
const query = Select().comment('This is a comment\nline 2\nline 3');
const result = query.generate(options);
expect(result.sql).toStrictEqual(
'-- This is a comment\n-- line 2\n-- line 3\nselect *',
);
});
});
4 changes: 2 additions & 2 deletions packages/connect/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@sqb/connect",
"description": "Multi-dialect database connection framework written with TypeScript",
"version": "4.23.3",
"version": "4.24.0",
"author": "Panates",
"license": "Apache-2.0",
"scripts": {
Expand Down Expand Up @@ -44,7 +44,7 @@
"postgrejs": "^2.22.9"
},
"peerDependencies": {
"@sqb/builder": "^4.23.3",
"@sqb/builder": "^4.24.0",
"reflect-metadata": "^0.2.2"
},
"type": "module",
Expand Down
1 change: 1 addition & 0 deletions packages/connect/src/orm/commands/count.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class CountCommand {
await prepareFilter(entity, filter, where, 'T');
}
const query = Select(Count()).from(entity.tableName + ' T');
if (args.comment) query.comment(args.comment, args.commentDialect);
if (where) query.where(where);
// Execute query
const resp = await connection.execute(query, {
Expand Down
4 changes: 3 additions & 1 deletion packages/connect/src/orm/commands/create.command.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Insert, Param } from '@sqb/builder';
import type { SqbConnection } from '../../client/sqb-connection.js';
import { EntityMetadata } from '../model/entity-metadata.js';
import { Repository } from '../repository.class.js';
import {
checkEnumValue,
isColumnField,
Expand All @@ -13,7 +14,7 @@ export type CreateCommandArgs = {
connection: SqbConnection;
values: any;
returning?: boolean;
};
} & Repository.CreateOptions;

type CreateCommandContext = {
entity: EntityMetadata;
Expand Down Expand Up @@ -50,6 +51,7 @@ export class CreateCommand {
throw new Error('No field given to create new entity instance');

const query = Insert(tableName, ctx.queryValues);
if (args.comment) query.comment(args.comment, args.commentDialect);
if (args.returning) {
const primaryIndexColumns = EntityMetadata.getPrimaryIndexColumns(entity);
if (primaryIndexColumns.length)
Expand Down
1 change: 1 addition & 0 deletions packages/connect/src/orm/commands/delete.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class DeleteCommand {
await prepareFilter(entity, filter, where);
}
const query = Delete(entity.tableName + ' T');
if (args.comment) query.comment(args.comment, args.commentDialect);
if (where) query.where(...where._items);
// Execute query
const resp = await connection.execute(query, {
Expand Down
4 changes: 4 additions & 0 deletions packages/connect/src/orm/commands/find.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ export class FindCommand {
| 'params'
| 'onTransformRow'
| 'prettyPrint'
| 'comment'
| 'commentDialect'
>,
): Promise<any[]> {
// Generate select query
Expand All @@ -348,6 +350,8 @@ export class FindCommand {
this.mainEntity.tableName + ' as ' + this.mainAlias,
);

if (args.comment) query.comment(args.comment, args.commentDialect);

if (args.distinct) query.distinct();

query.where(...this._filter._items);
Expand Down
Loading