Add more features to the query generator
This commit is contained in:
parent
f3f1c42699
commit
9c5d39edfb
5
dist/lib/sqlite/db-schema-manager.js
vendored
5
dist/lib/sqlite/db-schema-manager.js
vendored
@ -406,10 +406,9 @@ class SQLiteSchemaManager {
|
|||||||
if (!existingIndexes.includes(index.indexName)) {
|
if (!existingIndexes.includes(index.indexName)) {
|
||||||
console.log(`Creating index: ${index.indexName}`);
|
console.log(`Creating index: ${index.indexName}`);
|
||||||
const fields = index.indexTableFields
|
const fields = index.indexTableFields
|
||||||
.map((f) => `"${f.value}"`)
|
.map((f) => `"${f}"`)
|
||||||
.join(", ");
|
.join(", ");
|
||||||
const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX
|
this.db.run(`CREATE INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`);
|
||||||
this.db.run(`CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
40
dist/types/index.d.ts
vendored
40
dist/types/index.d.ts
vendored
@ -228,12 +228,12 @@ export interface BUN_SQLITE_ForeignKeyType {
|
|||||||
* Describes a table index and the fields it covers.
|
* Describes a table index and the fields it covers.
|
||||||
*/
|
*/
|
||||||
export interface BUN_SQLITE_IndexSchemaType {
|
export interface BUN_SQLITE_IndexSchemaType {
|
||||||
id?: string | number;
|
/**
|
||||||
|
* Name of the index as it would appear on schema. Eg.
|
||||||
|
* `idx_user_id_index`
|
||||||
|
*/
|
||||||
indexName?: string;
|
indexName?: string;
|
||||||
indexType?: (typeof IndexTypes)[number];
|
indexTableFields?: string[];
|
||||||
indexTableFields?: BUN_SQLITE_IndexTableFieldType[];
|
|
||||||
alias?: string;
|
|
||||||
newTempIndex?: boolean;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Describes a multi-field uniqueness rule for a table.
|
* Describes a multi-field uniqueness rule for a table.
|
||||||
@ -714,11 +714,12 @@ export type TableSelectFieldsObject<T extends {
|
|||||||
count?: {
|
count?: {
|
||||||
alias?: string;
|
alias?: string;
|
||||||
};
|
};
|
||||||
sum?: TableSelectFieldsBasicDirective;
|
sum?: boolean;
|
||||||
max?: TableSelectFieldsBasicDirective;
|
max?: boolean;
|
||||||
min?: TableSelectFieldsBasicDirective;
|
min?: boolean;
|
||||||
average?: TableSelectFieldsBasicDirective;
|
average?: boolean;
|
||||||
group_concat?: Omit<GroupConcatObject, "field">;
|
group_concat?: Omit<GroupConcatObject, "field">;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
export type TableSelectFieldsBasicDirective = {
|
export type TableSelectFieldsBasicDirective = {
|
||||||
alias: string;
|
alias: string;
|
||||||
@ -746,7 +747,7 @@ export type ServerQueryObjectValue = string | number | ServerQueryValuesObject |
|
|||||||
*/
|
*/
|
||||||
export type ServerQueryObject<T extends object = {
|
export type ServerQueryObject<T extends object = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}, K extends string = string> = {
|
}, K extends string = string> = SQLComparisonsParams & {
|
||||||
value?: ServerQueryObjectValue;
|
value?: ServerQueryObjectValue;
|
||||||
nullValue?: boolean;
|
nullValue?: boolean;
|
||||||
notNullValue?: boolean;
|
notNullValue?: boolean;
|
||||||
@ -826,6 +827,7 @@ export type GroupConcatObject = {
|
|||||||
* Separator. Default `,`
|
* Separator. Default `,`
|
||||||
*/
|
*/
|
||||||
separator?: string;
|
separator?: string;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
export type SelectFieldObject<Field extends object = {
|
export type SelectFieldObject<Field extends object = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -833,13 +835,29 @@ export type SelectFieldObject<Field extends object = {
|
|||||||
field: keyof Field;
|
field: keyof Field;
|
||||||
alias?: string;
|
alias?: string;
|
||||||
count?: boolean;
|
count?: boolean;
|
||||||
|
sum?: boolean;
|
||||||
|
max?: boolean;
|
||||||
|
min?: boolean;
|
||||||
|
average?: boolean;
|
||||||
|
group_concat?: Pick<GroupConcatObject, "separator" | "distinct">;
|
||||||
|
distinct?: boolean;
|
||||||
|
};
|
||||||
|
export declare const SQlComparisons: readonly [">", "<>", "<", "=", ">=", "<=", "!=", "IS NOT", "IS", "IS NULL", "IS NOT NULL", "IN", "NOT IN", "LIKE", "NOT LIKE", "GLOB", "NOT GLOB"];
|
||||||
|
export type SQLBetween = {
|
||||||
|
min: SQLInsertGenValueType;
|
||||||
|
max: SQLInsertGenValueType;
|
||||||
|
};
|
||||||
|
export type SQLComparisonsParams = {
|
||||||
|
raw_equality?: (typeof SQlComparisons)[number];
|
||||||
|
between?: SQLBetween;
|
||||||
|
not_between?: SQLBetween;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Defines how a root-table field maps to a join-table field in an `ON` clause.
|
* Defines how a root-table field maps to a join-table field in an `ON` clause.
|
||||||
*/
|
*/
|
||||||
export type ServerQueryParamsJoinMatchObject<Field extends object = {
|
export type ServerQueryParamsJoinMatchObject<Field extends object = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}> = {
|
}> = SQLComparisonsParams & {
|
||||||
/** Field name from the **Root Table** */
|
/** Field name from the **Root Table** */
|
||||||
source?: string | ServerQueryParamsJoinMatchSourceTargetObject;
|
source?: string | ServerQueryParamsJoinMatchSourceTargetObject;
|
||||||
/** Field name from the **Join Table** */
|
/** Field name from the **Join Table** */
|
||||||
|
|||||||
19
dist/types/index.js
vendored
19
dist/types/index.js
vendored
@ -81,6 +81,25 @@ export const ServerQueryEqualities = [
|
|||||||
"MATCH",
|
"MATCH",
|
||||||
"MATCH_BOOLEAN",
|
"MATCH_BOOLEAN",
|
||||||
];
|
];
|
||||||
|
export const SQlComparisons = [
|
||||||
|
">",
|
||||||
|
"<>",
|
||||||
|
"<",
|
||||||
|
"=",
|
||||||
|
">=",
|
||||||
|
"<=",
|
||||||
|
"!=",
|
||||||
|
"IS NOT",
|
||||||
|
"IS",
|
||||||
|
"IS NULL",
|
||||||
|
"IS NOT NULL",
|
||||||
|
"IN",
|
||||||
|
"NOT IN",
|
||||||
|
"LIKE",
|
||||||
|
"NOT LIKE",
|
||||||
|
"GLOB",
|
||||||
|
"NOT GLOB",
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* Uppercase HTTP methods supported by the CRUD helpers.
|
* Uppercase HTTP methods supported by the CRUD helpers.
|
||||||
*/
|
*/
|
||||||
|
|||||||
7
dist/utils/sql-generator-gen-join-str.d.ts
vendored
7
dist/utils/sql-generator-gen-join-str.d.ts
vendored
@ -1,8 +1,11 @@
|
|||||||
import type { ServerQueryParamsJoin, ServerQueryParamsJoinMatchObject } from "../types";
|
import type { ServerQueryParamsJoin, ServerQueryParamsJoinMatchObject, SQLInsertGenValueType } from "../types";
|
||||||
type Param = {
|
type Param = {
|
||||||
mtch: ServerQueryParamsJoinMatchObject;
|
mtch: ServerQueryParamsJoinMatchObject;
|
||||||
join: ServerQueryParamsJoin;
|
join: ServerQueryParamsJoin;
|
||||||
table_name: string;
|
table_name: string;
|
||||||
};
|
};
|
||||||
export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param): string;
|
export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param): {
|
||||||
|
str: string;
|
||||||
|
values: SQLInsertGenValueType[];
|
||||||
|
};
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
46
dist/utils/sql-generator-gen-join-str.js
vendored
46
dist/utils/sql-generator-gen-join-str.js
vendored
@ -1,23 +1,37 @@
|
|||||||
export default function sqlGenGenJoinStr({ join, mtch, table_name }) {
|
export default function sqlGenGenJoinStr({ join, mtch, table_name }) {
|
||||||
|
let values = [];
|
||||||
if (mtch.__batch) {
|
if (mtch.__batch) {
|
||||||
let btch_mtch = ``;
|
let btch_mtch = ``;
|
||||||
btch_mtch += `(`;
|
btch_mtch += `(`;
|
||||||
for (let i = 0; i < mtch.__batch.matches.length; i++) {
|
for (let i = 0; i < mtch.__batch.matches.length; i++) {
|
||||||
const __mtch = mtch.__batch.matches[i];
|
const __mtch = mtch.__batch.matches[i];
|
||||||
btch_mtch += `${sqlGenGenJoinStr({ join, mtch: __mtch, table_name })}`;
|
const { str, values: batch_values } = sqlGenGenJoinStr({
|
||||||
|
join,
|
||||||
|
mtch: __mtch,
|
||||||
|
table_name,
|
||||||
|
});
|
||||||
|
btch_mtch += str;
|
||||||
|
values.push(...batch_values);
|
||||||
if (i < mtch.__batch.matches.length - 1) {
|
if (i < mtch.__batch.matches.length - 1) {
|
||||||
btch_mtch += ` ${mtch.__batch.operator || "OR"} `;
|
btch_mtch += ` ${mtch.__batch.operator || "OR"} `;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
btch_mtch += `)`;
|
btch_mtch += `)`;
|
||||||
return btch_mtch;
|
return {
|
||||||
|
str: btch_mtch,
|
||||||
|
values,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return `${typeof mtch.source == "object" ? mtch.source.tableName : table_name}.${typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source}=${(() => {
|
const equality = mtch.raw_equality || "=";
|
||||||
|
const lhs = `${typeof mtch.source == "object" ? mtch.source.tableName : table_name}.${typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source}`;
|
||||||
|
const rhs = `${(() => {
|
||||||
if (mtch.targetLiteral) {
|
if (mtch.targetLiteral) {
|
||||||
if (typeof mtch.targetLiteral == "number") {
|
values.push(mtch.targetLiteral);
|
||||||
return `${mtch.targetLiteral}`;
|
// if (typeof mtch.targetLiteral == "number") {
|
||||||
}
|
// return `${mtch.targetLiteral}`;
|
||||||
return `'${mtch.targetLiteral}'`;
|
// }
|
||||||
|
// return `'${mtch.targetLiteral}'`;
|
||||||
|
return `?`;
|
||||||
}
|
}
|
||||||
if (join.alias) {
|
if (join.alias) {
|
||||||
return `${typeof mtch.target == "object"
|
return `${typeof mtch.target == "object"
|
||||||
@ -30,4 +44,22 @@ export default function sqlGenGenJoinStr({ join, mtch, table_name }) {
|
|||||||
? mtch.target.tableName
|
? mtch.target.tableName
|
||||||
: join.tableName}.${typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target}`;
|
: join.tableName}.${typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target}`;
|
||||||
})()}`;
|
})()}`;
|
||||||
|
if (mtch.between) {
|
||||||
|
values.push(mtch.between.min, mtch.between.max);
|
||||||
|
return {
|
||||||
|
str: `${lhs} BETWEEN ? AND ?`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (mtch.not_between) {
|
||||||
|
values.push(mtch.not_between.min, mtch.not_between.max);
|
||||||
|
return {
|
||||||
|
str: `${lhs} NOT BETWEEN ? AND ?`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
str: `${lhs} ${equality} ${rhs}`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
45
dist/utils/sql-generator-gen-query-str.js
vendored
45
dist/utils/sql-generator-gen-query-str.js
vendored
@ -94,9 +94,36 @@ export default function sqlGenGenQueryStr(params) {
|
|||||||
return `${joinTableName}.${selectField}`;
|
return `${joinTableName}.${selectField}`;
|
||||||
}
|
}
|
||||||
else if (typeof selectField == "object") {
|
else if (typeof selectField == "object") {
|
||||||
let aliasSelectField = selectField.count
|
let aliasSelectField = `${joinTableName}.${selectField.field}`;
|
||||||
? `COUNT(${joinTableName}.${selectField.field})`
|
if (selectField.count) {
|
||||||
: `${joinTableName}.${selectField.field}`;
|
aliasSelectField = `COUNT(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
if (selectField.sum) {
|
||||||
|
aliasSelectField = `SUM(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
if (selectField.average) {
|
||||||
|
aliasSelectField = `AVERAGE(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
if (selectField.max) {
|
||||||
|
aliasSelectField = `MAX(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
if (selectField.min) {
|
||||||
|
aliasSelectField = `MIN(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
if (selectField.distinct) {
|
||||||
|
aliasSelectField = `DISTINCT ${joinTableName}.${selectField.field}`;
|
||||||
|
}
|
||||||
|
if (selectField.group_concat &&
|
||||||
|
selectField.alias) {
|
||||||
|
return sqlGenGrabConcatStr({
|
||||||
|
field: `${joinTableName}.${selectField.field}`,
|
||||||
|
alias: selectField.alias,
|
||||||
|
separator: selectField.group_concat
|
||||||
|
.separator,
|
||||||
|
distinct: selectField.group_concat
|
||||||
|
.distinct,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (selectField.alias)
|
if (selectField.alias)
|
||||||
aliasSelectField += ` AS ${selectField.alias}`;
|
aliasSelectField += ` AS ${selectField.alias}`;
|
||||||
return aliasSelectField;
|
return aliasSelectField;
|
||||||
@ -135,22 +162,28 @@ export default function sqlGenGenQueryStr(params) {
|
|||||||
if (Array.isArray(join.match)) {
|
if (Array.isArray(join.match)) {
|
||||||
return ("(" +
|
return ("(" +
|
||||||
join.match
|
join.match
|
||||||
.map((mtch) => sqlGenGenJoinStr({
|
.map((mtch) => {
|
||||||
|
const { str, values } = sqlGenGenJoinStr({
|
||||||
mtch,
|
mtch,
|
||||||
join,
|
join,
|
||||||
table_name,
|
table_name,
|
||||||
}))
|
});
|
||||||
|
sqlSearhValues.push(...values);
|
||||||
|
return str;
|
||||||
|
})
|
||||||
.join(join.operator
|
.join(join.operator
|
||||||
? ` ${join.operator} `
|
? ` ${join.operator} `
|
||||||
: " AND ") +
|
: " AND ") +
|
||||||
")");
|
")");
|
||||||
}
|
}
|
||||||
else if (typeof join.match == "object") {
|
else if (typeof join.match == "object") {
|
||||||
return sqlGenGenJoinStr({
|
const { str, values } = sqlGenGenJoinStr({
|
||||||
mtch: join.match,
|
mtch: join.match,
|
||||||
join,
|
join,
|
||||||
table_name,
|
table_name,
|
||||||
});
|
});
|
||||||
|
sqlSearhValues.push(...values);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
})());
|
})());
|
||||||
})
|
})
|
||||||
|
|||||||
4
dist/utils/sql-generator-gen-search-str.d.ts
vendored
4
dist/utils/sql-generator-gen-search-str.d.ts
vendored
@ -1,4 +1,4 @@
|
|||||||
import type { ServerQueryParamsJoin, ServerQueryQueryObject } from "../types";
|
import type { ServerQueryParamsJoin, ServerQueryQueryObject, SQLInsertGenValueType } from "../types";
|
||||||
type Param = {
|
type Param = {
|
||||||
queryObj: ServerQueryQueryObject[string];
|
queryObj: ServerQueryQueryObject[string];
|
||||||
join?: (ServerQueryParamsJoin | ServerQueryParamsJoin[] | undefined)[];
|
join?: (ServerQueryParamsJoin | ServerQueryParamsJoin[] | undefined)[];
|
||||||
@ -7,6 +7,6 @@ type Param = {
|
|||||||
};
|
};
|
||||||
export default function sqlGenGenSearchStr({ queryObj, join, field, table_name, }: Param): {
|
export default function sqlGenGenSearchStr({ queryObj, join, field, table_name, }: Param): {
|
||||||
str: string;
|
str: string;
|
||||||
values: (string | number | Float32Array<ArrayBuffer> | Buffer<ArrayBuffer>)[];
|
values: SQLInsertGenValueType[];
|
||||||
};
|
};
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
8
dist/utils/sql-generator-gen-search-str.js
vendored
8
dist/utils/sql-generator-gen-search-str.js
vendored
@ -61,6 +61,14 @@ export default function sqlGenGenSearchStr({ queryObj, join, field, table_name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (queryObj.raw_equality && queryObj.value) {
|
||||||
|
str = `${finalFieldName} ${queryObj.raw_equality} ?`;
|
||||||
|
sqlSearhValues.push(queryObj.value);
|
||||||
|
}
|
||||||
|
else if (queryObj.between) {
|
||||||
|
str = `${finalFieldName} BETWEEN ? AND ?`;
|
||||||
|
sqlSearhValues.push(queryObj.between.min, queryObj.between.max);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
const valueParsed = queryObj.value ? queryObj.value : undefined;
|
const valueParsed = queryObj.value ? queryObj.value : undefined;
|
||||||
const operatorStrParam = sqlGenOperatorGen({
|
const operatorStrParam = sqlGenOperatorGen({
|
||||||
|
|||||||
@ -2,6 +2,7 @@ type Param = {
|
|||||||
field: string;
|
field: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
separator?: string;
|
separator?: string;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
export default function sqlGenGrabConcatStr({ alias, field, separator, }: Param): string;
|
export default function sqlGenGrabConcatStr({ alias, field, separator, distinct, }: Param): string;
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
10
dist/utils/sql-generator-grab-concat-str.js
vendored
10
dist/utils/sql-generator-grab-concat-str.js
vendored
@ -1,4 +1,10 @@
|
|||||||
export default function sqlGenGrabConcatStr({ alias, field, separator = ",", }) {
|
export default function sqlGenGrabConcatStr({ alias, field, separator = ",", distinct, }) {
|
||||||
let gc = `GROUP_CONCAT(${field}, '${separator}') AS ${alias}`;
|
let gc = `GROUP_CONCAT(`;
|
||||||
|
if (distinct) {
|
||||||
|
gc += `DISTINCT `;
|
||||||
|
}
|
||||||
|
gc += `${field}, '${separator}'`;
|
||||||
|
gc += `)`;
|
||||||
|
gc += ` AS ${alias}`;
|
||||||
return gc;
|
return gc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,24 +13,37 @@ export default function sqlGenGrabSelectFieldSQL({ selectFields, append_table_na
|
|||||||
const fld_name = `${String(fld.fieldName)}`;
|
const fld_name = `${String(fld.fieldName)}`;
|
||||||
if (fld.count) {
|
if (fld.count) {
|
||||||
fld_str += `COUNT(${fld_name})`;
|
fld_str += `COUNT(${fld_name})`;
|
||||||
if (fld.count.alias) {
|
|
||||||
fld_str += ` AS ${fld.count.alias}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (fld.sum) {
|
else if (fld.sum) {
|
||||||
fld_str += `SUM(${fld_name}) AS ${fld.sum.alias}`;
|
fld_str += `SUM(${fld_name})`;
|
||||||
|
}
|
||||||
|
else if (fld.average) {
|
||||||
|
fld_str += `AVERAGE(${fld_name})`;
|
||||||
|
}
|
||||||
|
else if (fld.max) {
|
||||||
|
fld_str += `MAX(${fld_name})`;
|
||||||
|
}
|
||||||
|
else if (fld.min) {
|
||||||
|
fld_str += `MIN(${fld_name})`;
|
||||||
|
}
|
||||||
|
else if (fld.distinct) {
|
||||||
|
fld_str += `DISTINCT ${fld_name}`;
|
||||||
}
|
}
|
||||||
else if (fld.group_concat) {
|
else if (fld.group_concat) {
|
||||||
fld_str += sqlGenGrabConcatStr({
|
fld_str += sqlGenGrabConcatStr({
|
||||||
field: fld_name,
|
field: fld_name,
|
||||||
alias: fld.group_concat.alias,
|
alias: fld.group_concat.alias,
|
||||||
separator: fld.group_concat.separator,
|
separator: fld.group_concat.separator,
|
||||||
|
distinct: fld.group_concat.distinct,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fld_str +=
|
fld_str +=
|
||||||
final_fld_name + (fld.alias ? ` as ${fld.alias}` : ``);
|
final_fld_name + (fld.alias ? ` as ${fld.alias}` : ``);
|
||||||
}
|
}
|
||||||
|
if (fld.alias) {
|
||||||
|
fld_str += ` AS ${fld.alias}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fld_str += final_fld_name;
|
fld_str += final_fld_name;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@moduletrace/bun-sqlite",
|
"name": "@moduletrace/bun-sqlite",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"description": "SQLite manager for Bun",
|
"description": "SQLite manager for Bun",
|
||||||
"author": "Benjamin Toby",
|
"author": "Benjamin Toby",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@ -589,11 +589,10 @@ class SQLiteSchemaManager {
|
|||||||
if (!existingIndexes.includes(index.indexName)) {
|
if (!existingIndexes.includes(index.indexName)) {
|
||||||
console.log(`Creating index: ${index.indexName}`);
|
console.log(`Creating index: ${index.indexName}`);
|
||||||
const fields = index.indexTableFields
|
const fields = index.indexTableFields
|
||||||
.map((f) => `"${f.value}"`)
|
.map((f) => `"${f}"`)
|
||||||
.join(", ");
|
.join(", ");
|
||||||
const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX
|
|
||||||
this.db.run(
|
this.db.run(
|
||||||
`CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`,
|
`CREATE INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -232,12 +232,12 @@ export interface BUN_SQLITE_ForeignKeyType {
|
|||||||
* Describes a table index and the fields it covers.
|
* Describes a table index and the fields it covers.
|
||||||
*/
|
*/
|
||||||
export interface BUN_SQLITE_IndexSchemaType {
|
export interface BUN_SQLITE_IndexSchemaType {
|
||||||
id?: string | number;
|
/**
|
||||||
|
* Name of the index as it would appear on schema. Eg.
|
||||||
|
* `idx_user_id_index`
|
||||||
|
*/
|
||||||
indexName?: string;
|
indexName?: string;
|
||||||
indexType?: (typeof IndexTypes)[number];
|
indexTableFields?: string[];
|
||||||
indexTableFields?: BUN_SQLITE_IndexTableFieldType[];
|
|
||||||
alias?: string;
|
|
||||||
newTempIndex?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -785,11 +785,12 @@ export type TableSelectFieldsObject<
|
|||||||
count?: {
|
count?: {
|
||||||
alias?: string;
|
alias?: string;
|
||||||
};
|
};
|
||||||
sum?: TableSelectFieldsBasicDirective;
|
sum?: boolean;
|
||||||
max?: TableSelectFieldsBasicDirective;
|
max?: boolean;
|
||||||
min?: TableSelectFieldsBasicDirective;
|
min?: boolean;
|
||||||
average?: TableSelectFieldsBasicDirective;
|
average?: boolean;
|
||||||
group_concat?: Omit<GroupConcatObject, "field">;
|
group_concat?: Omit<GroupConcatObject, "field">;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableSelectFieldsBasicDirective = {
|
export type TableSelectFieldsBasicDirective = {
|
||||||
@ -828,7 +829,7 @@ export type ServerQueryObjectValue =
|
|||||||
export type ServerQueryObject<
|
export type ServerQueryObject<
|
||||||
T extends object = { [key: string]: any },
|
T extends object = { [key: string]: any },
|
||||||
K extends string = string,
|
K extends string = string,
|
||||||
> = {
|
> = SQLComparisonsParams & {
|
||||||
value?: ServerQueryObjectValue;
|
value?: ServerQueryObjectValue;
|
||||||
nullValue?: boolean;
|
nullValue?: boolean;
|
||||||
notNullValue?: boolean;
|
notNullValue?: boolean;
|
||||||
@ -921,12 +922,50 @@ export type GroupConcatObject = {
|
|||||||
* Separator. Default `,`
|
* Separator. Default `,`
|
||||||
*/
|
*/
|
||||||
separator?: string;
|
separator?: string;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SelectFieldObject<Field extends object = { [key: string]: any }> = {
|
export type SelectFieldObject<Field extends object = { [key: string]: any }> = {
|
||||||
field: keyof Field;
|
field: keyof Field;
|
||||||
alias?: string;
|
alias?: string;
|
||||||
count?: boolean;
|
count?: boolean;
|
||||||
|
sum?: boolean;
|
||||||
|
max?: boolean;
|
||||||
|
min?: boolean;
|
||||||
|
average?: boolean;
|
||||||
|
group_concat?: Pick<GroupConcatObject, "separator" | "distinct">;
|
||||||
|
distinct?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SQlComparisons = [
|
||||||
|
">",
|
||||||
|
"<>",
|
||||||
|
"<",
|
||||||
|
"=",
|
||||||
|
">=",
|
||||||
|
"<=",
|
||||||
|
"!=",
|
||||||
|
"IS NOT",
|
||||||
|
"IS",
|
||||||
|
"IS NULL",
|
||||||
|
"IS NOT NULL",
|
||||||
|
"IN",
|
||||||
|
"NOT IN",
|
||||||
|
"LIKE",
|
||||||
|
"NOT LIKE",
|
||||||
|
"GLOB",
|
||||||
|
"NOT GLOB",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export type SQLBetween = {
|
||||||
|
min: SQLInsertGenValueType;
|
||||||
|
max: SQLInsertGenValueType;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SQLComparisonsParams = {
|
||||||
|
raw_equality?: (typeof SQlComparisons)[number];
|
||||||
|
between?: SQLBetween;
|
||||||
|
not_between?: SQLBetween;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -934,7 +973,7 @@ export type SelectFieldObject<Field extends object = { [key: string]: any }> = {
|
|||||||
*/
|
*/
|
||||||
export type ServerQueryParamsJoinMatchObject<
|
export type ServerQueryParamsJoinMatchObject<
|
||||||
Field extends object = { [key: string]: any },
|
Field extends object = { [key: string]: any },
|
||||||
> = {
|
> = SQLComparisonsParams & {
|
||||||
/** Field name from the **Root Table** */
|
/** Field name from the **Root Table** */
|
||||||
source?: string | ServerQueryParamsJoinMatchSourceTargetObject;
|
source?: string | ServerQueryParamsJoinMatchSourceTargetObject;
|
||||||
/** Field name from the **Join Table** */
|
/** Field name from the **Join Table** */
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
ServerQueryParamsJoin,
|
ServerQueryParamsJoin,
|
||||||
ServerQueryParamsJoinMatchObject,
|
ServerQueryParamsJoinMatchObject,
|
||||||
|
SQLInsertGenValueType,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
|
|
||||||
type Param = {
|
type Param = {
|
||||||
@ -10,6 +11,8 @@ type Param = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) {
|
export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) {
|
||||||
|
let values: SQLInsertGenValueType[] = [];
|
||||||
|
|
||||||
if (mtch.__batch) {
|
if (mtch.__batch) {
|
||||||
let btch_mtch = ``;
|
let btch_mtch = ``;
|
||||||
btch_mtch += `(`;
|
btch_mtch += `(`;
|
||||||
@ -18,7 +21,17 @@ export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) {
|
|||||||
const __mtch = mtch.__batch.matches[
|
const __mtch = mtch.__batch.matches[
|
||||||
i
|
i
|
||||||
] as ServerQueryParamsJoinMatchObject;
|
] as ServerQueryParamsJoinMatchObject;
|
||||||
btch_mtch += `${sqlGenGenJoinStr({ join, mtch: __mtch, table_name })}`;
|
|
||||||
|
const { str, values: batch_values } = sqlGenGenJoinStr({
|
||||||
|
join,
|
||||||
|
mtch: __mtch,
|
||||||
|
table_name,
|
||||||
|
});
|
||||||
|
|
||||||
|
btch_mtch += str;
|
||||||
|
|
||||||
|
values.push(...batch_values);
|
||||||
|
|
||||||
if (i < mtch.__batch.matches.length - 1) {
|
if (i < mtch.__batch.matches.length - 1) {
|
||||||
btch_mtch += ` ${mtch.__batch.operator || "OR"} `;
|
btch_mtch += ` ${mtch.__batch.operator || "OR"} `;
|
||||||
}
|
}
|
||||||
@ -26,19 +39,28 @@ export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) {
|
|||||||
|
|
||||||
btch_mtch += `)`;
|
btch_mtch += `)`;
|
||||||
|
|
||||||
return btch_mtch;
|
return {
|
||||||
|
str: btch_mtch,
|
||||||
|
values,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${
|
const equality = mtch.raw_equality || "=";
|
||||||
|
|
||||||
|
const lhs = `${
|
||||||
typeof mtch.source == "object" ? mtch.source.tableName : table_name
|
typeof mtch.source == "object" ? mtch.source.tableName : table_name
|
||||||
}.${
|
}.${typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source}`;
|
||||||
typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source
|
|
||||||
}=${(() => {
|
const rhs = `${(() => {
|
||||||
if (mtch.targetLiteral) {
|
if (mtch.targetLiteral) {
|
||||||
if (typeof mtch.targetLiteral == "number") {
|
values.push(mtch.targetLiteral);
|
||||||
return `${mtch.targetLiteral}`;
|
|
||||||
}
|
// if (typeof mtch.targetLiteral == "number") {
|
||||||
return `'${mtch.targetLiteral}'`;
|
// return `${mtch.targetLiteral}`;
|
||||||
|
// }
|
||||||
|
// return `'${mtch.targetLiteral}'`;
|
||||||
|
|
||||||
|
return `?`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (join.alias) {
|
if (join.alias) {
|
||||||
@ -61,4 +83,27 @@ export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param) {
|
|||||||
typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target
|
typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target
|
||||||
}`;
|
}`;
|
||||||
})()}`;
|
})()}`;
|
||||||
|
|
||||||
|
if (mtch.between) {
|
||||||
|
values.push(mtch.between.min, mtch.between.max);
|
||||||
|
|
||||||
|
return {
|
||||||
|
str: `${lhs} BETWEEN ? AND ?`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mtch.not_between) {
|
||||||
|
values.push(mtch.not_between.min, mtch.not_between.max);
|
||||||
|
|
||||||
|
return {
|
||||||
|
str: `${lhs} NOT BETWEEN ? AND ?`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
str: `${lhs} ${equality} ${rhs}`,
|
||||||
|
values,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,9 +121,48 @@ export default function sqlGenGenQueryStr<
|
|||||||
if (typeof selectField == "string") {
|
if (typeof selectField == "string") {
|
||||||
return `${joinTableName}.${selectField}`;
|
return `${joinTableName}.${selectField}`;
|
||||||
} else if (typeof selectField == "object") {
|
} else if (typeof selectField == "object") {
|
||||||
let aliasSelectField = selectField.count
|
let aliasSelectField = `${joinTableName}.${selectField.field}`;
|
||||||
? `COUNT(${joinTableName}.${selectField.field})`
|
|
||||||
: `${joinTableName}.${selectField.field}`;
|
if (selectField.count) {
|
||||||
|
aliasSelectField = `COUNT(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectField.sum) {
|
||||||
|
aliasSelectField = `SUM(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectField.average) {
|
||||||
|
aliasSelectField = `AVERAGE(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectField.max) {
|
||||||
|
aliasSelectField = `MAX(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectField.min) {
|
||||||
|
aliasSelectField = `MIN(${joinTableName}.${selectField.field})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectField.distinct) {
|
||||||
|
aliasSelectField = `DISTINCT ${joinTableName}.${selectField.field}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
selectField.group_concat &&
|
||||||
|
selectField.alias
|
||||||
|
) {
|
||||||
|
return sqlGenGrabConcatStr({
|
||||||
|
field: `${joinTableName}.${selectField.field}`,
|
||||||
|
alias: selectField.alias,
|
||||||
|
separator:
|
||||||
|
selectField.group_concat
|
||||||
|
.separator,
|
||||||
|
distinct:
|
||||||
|
selectField.group_concat
|
||||||
|
.distinct,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (selectField.alias)
|
if (selectField.alias)
|
||||||
aliasSelectField += ` AS ${selectField.alias}`;
|
aliasSelectField += ` AS ${selectField.alias}`;
|
||||||
return aliasSelectField;
|
return aliasSelectField;
|
||||||
@ -168,13 +207,18 @@ export default function sqlGenGenQueryStr<
|
|||||||
return (
|
return (
|
||||||
"(" +
|
"(" +
|
||||||
join.match
|
join.match
|
||||||
.map((mtch) =>
|
.map((mtch) => {
|
||||||
|
const { str, values } =
|
||||||
sqlGenGenJoinStr({
|
sqlGenGenJoinStr({
|
||||||
mtch,
|
mtch,
|
||||||
join,
|
join,
|
||||||
table_name,
|
table_name,
|
||||||
}),
|
});
|
||||||
)
|
|
||||||
|
sqlSearhValues.push(...values);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
})
|
||||||
.join(
|
.join(
|
||||||
join.operator
|
join.operator
|
||||||
? ` ${join.operator} `
|
? ` ${join.operator} `
|
||||||
@ -183,11 +227,15 @@ export default function sqlGenGenQueryStr<
|
|||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
} else if (typeof join.match == "object") {
|
} else if (typeof join.match == "object") {
|
||||||
return sqlGenGenJoinStr({
|
const { str, values } = sqlGenGenJoinStr({
|
||||||
mtch: join.match,
|
mtch: join.match,
|
||||||
join,
|
join,
|
||||||
table_name,
|
table_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sqlSearhValues.push(...values);
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import type {
|
import type {
|
||||||
|
QueryRawValueType,
|
||||||
ServerQueryParamsJoin,
|
ServerQueryParamsJoin,
|
||||||
ServerQueryQueryObject,
|
ServerQueryQueryObject,
|
||||||
ServerQueryValuesObject,
|
ServerQueryValuesObject,
|
||||||
|
SQLInsertGenValueType,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import sqlGenOperatorGen from "./sql-gen-operator-gen";
|
import sqlGenOperatorGen from "./sql-gen-operator-gen";
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ export default function sqlGenGenSearchStr({
|
|||||||
field,
|
field,
|
||||||
table_name,
|
table_name,
|
||||||
}: Param) {
|
}: Param) {
|
||||||
let sqlSearhValues = [];
|
let sqlSearhValues: SQLInsertGenValueType[] = [];
|
||||||
|
|
||||||
const finalFieldName = (() => {
|
const finalFieldName = (() => {
|
||||||
if (queryObj?.tableName) {
|
if (queryObj?.tableName) {
|
||||||
@ -91,6 +93,12 @@ export default function sqlGenGenSearchStr({
|
|||||||
sqlSearhValues.push(operatorStrParam.param);
|
sqlSearhValues.push(operatorStrParam.param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (queryObj.raw_equality && queryObj.value) {
|
||||||
|
str = `${finalFieldName} ${queryObj.raw_equality} ?`;
|
||||||
|
sqlSearhValues.push(queryObj.value);
|
||||||
|
} else if (queryObj.between) {
|
||||||
|
str = `${finalFieldName} BETWEEN ? AND ?`;
|
||||||
|
sqlSearhValues.push(queryObj.between.min, queryObj.between.max);
|
||||||
} else {
|
} else {
|
||||||
const valueParsed = queryObj.value ? queryObj.value : undefined;
|
const valueParsed = queryObj.value ? queryObj.value : undefined;
|
||||||
|
|
||||||
|
|||||||
@ -2,13 +2,24 @@ type Param = {
|
|||||||
field: string;
|
field: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
separator?: string;
|
separator?: string;
|
||||||
|
distinct?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function sqlGenGrabConcatStr({
|
export default function sqlGenGrabConcatStr({
|
||||||
alias,
|
alias,
|
||||||
field,
|
field,
|
||||||
separator = ",",
|
separator = ",",
|
||||||
|
distinct,
|
||||||
}: Param) {
|
}: Param) {
|
||||||
let gc = `GROUP_CONCAT(${field}, '${separator}') AS ${alias}`;
|
let gc = `GROUP_CONCAT(`;
|
||||||
|
|
||||||
|
if (distinct) {
|
||||||
|
gc += `DISTINCT `;
|
||||||
|
}
|
||||||
|
|
||||||
|
gc += `${field}, '${separator}'`;
|
||||||
|
gc += `)`;
|
||||||
|
gc += ` AS ${alias}`;
|
||||||
|
|
||||||
return gc;
|
return gc;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,21 +28,31 @@ export default function sqlGenGrabSelectFieldSQL<
|
|||||||
|
|
||||||
if (fld.count) {
|
if (fld.count) {
|
||||||
fld_str += `COUNT(${fld_name})`;
|
fld_str += `COUNT(${fld_name})`;
|
||||||
if (fld.count.alias) {
|
|
||||||
fld_str += ` AS ${fld.count.alias}`;
|
|
||||||
}
|
|
||||||
} else if (fld.sum) {
|
} else if (fld.sum) {
|
||||||
fld_str += `SUM(${fld_name}) AS ${fld.sum.alias}`;
|
fld_str += `SUM(${fld_name})`;
|
||||||
|
} else if (fld.average) {
|
||||||
|
fld_str += `AVERAGE(${fld_name})`;
|
||||||
|
} else if (fld.max) {
|
||||||
|
fld_str += `MAX(${fld_name})`;
|
||||||
|
} else if (fld.min) {
|
||||||
|
fld_str += `MIN(${fld_name})`;
|
||||||
|
} else if (fld.distinct) {
|
||||||
|
fld_str += `DISTINCT ${fld_name}`;
|
||||||
} else if (fld.group_concat) {
|
} else if (fld.group_concat) {
|
||||||
fld_str += sqlGenGrabConcatStr({
|
fld_str += sqlGenGrabConcatStr({
|
||||||
field: fld_name,
|
field: fld_name,
|
||||||
alias: fld.group_concat.alias,
|
alias: fld.group_concat.alias,
|
||||||
separator: fld.group_concat.separator,
|
separator: fld.group_concat.separator,
|
||||||
|
distinct: fld.group_concat.distinct,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
fld_str +=
|
fld_str +=
|
||||||
final_fld_name + (fld.alias ? ` as ${fld.alias}` : ``);
|
final_fld_name + (fld.alias ? ` as ${fld.alias}` : ``);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fld.alias) {
|
||||||
|
fld_str += ` AS ${fld.alias}`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fld_str += final_fld_name;
|
fld_str += final_fld_name;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user