various fixes: refactored imports, introduced fromDriver/toDriver to improve compat

This commit is contained in:
dswbx
2025-06-13 21:15:29 +02:00
parent cc038a0a9a
commit 2ada4e9f20
15 changed files with 100 additions and 35 deletions

View File

@@ -20,6 +20,7 @@ import {
import type { BaseIntrospector, BaseIntrospectorConfig } from "./BaseIntrospector";
import type { Constructor, DB } from "core";
import { KyselyPluginRunner } from "data/plugins/KyselyPluginRunner";
import type { Field } from "data/fields/Field";
export type QB = SelectQueryBuilder<any, any, any>;
@@ -200,6 +201,14 @@ export abstract class Connection<Client = unknown> {
abstract getFieldSchema(spec: FieldSpec, strict?: boolean): SchemaResponse;
toDriver(value: unknown, field: Field): unknown {
return value;
}
fromDriver(value: any, field: Field): unknown {
return value;
}
async close(): Promise<void> {
// no-op by default
}

View File

@@ -1,6 +1,8 @@
import type { TestRunner } from "core/test";
import { Connection, type FieldSpec } from "./Connection";
// @todo: add various datatypes: string, number, boolean, object, array, null, undefined, date, etc.
export function connectionTestSuite(
testRunner: TestRunner,
{

View File

@@ -57,6 +57,6 @@ export class LibsqlConnection extends SqliteConnection<Client> {
}
}
export function libsql(credentials: LibSqlCredentials): LibsqlConnection {
export function libsql(credentials: Client | LibSqlCredentials): LibsqlConnection {
return new LibsqlConnection(credentials);
}

View File

@@ -11,7 +11,9 @@ import { Connection, type DbFunctions, type FieldSpec, type SchemaResponse } fro
import type { Constructor } from "core";
import { customIntrospector } from "../Connection";
import { SqliteIntrospector } from "./SqliteIntrospector";
import type { Field } from "data/fields/Field";
// @todo: add pragmas
export type SqliteConnectionConfig<
CustomDialect extends Constructor<Dialect> = Constructor<Dialect>,
> = {
@@ -80,4 +82,24 @@ export abstract class SqliteConnection<Client = unknown> extends Connection<Clie
},
] as const;
}
override toDriver(value: unknown, field: Field): unknown {
if (field.type === "boolean") {
return value ? 1 : 0;
}
if (typeof value === "undefined") {
return null;
}
return value;
}
override fromDriver(value: any, field: Field): unknown {
if (field.type === "boolean" && typeof value === "number") {
return value === 1;
}
if (value === null) {
return undefined;
}
return value;
}
}

View File

@@ -1,13 +1,9 @@
import { type Static, StringEnum, StringRecord, objectTransform } from "core/utils";
import * as tb from "@sinclair/typebox";
import {
FieldClassMap,
RelationClassMap,
RelationFieldClassMap,
entityConfigSchema,
entityTypes,
} from "data";
import { MediaField, mediaFieldConfigSchema } from "../media/MediaField";
import { FieldClassMap } from "data/fields";
import { RelationClassMap, RelationFieldClassMap } from "data/relations";
import { entityConfigSchema, entityTypes } from "data/entities";
import { primaryFieldTypes } from "./fields";
export const FIELDS = {

View File

@@ -278,6 +278,10 @@ export class EntityManager<TBD extends object = DefaultDB> {
row[key] = field.getDefault();
}
// transform from driver
value = this.connection.fromDriver(value, field);
// transform from field
row[key] = field.transformRetrieve(value as any);
} catch (e: any) {
throw new TransformRetrieveFailedException(

View File

@@ -1,13 +1,15 @@
import { $console, type DB as DefaultDB, type PrimaryFieldType } from "core";
import type { DB as DefaultDB, PrimaryFieldType } from "core";
import { type EmitsEvents, EventManager } from "core/events";
import type { DeleteQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder } from "kysely";
import { type TActionContext, WhereBuilder } from "../..";
import type { TActionContext } from "../..";
import { WhereBuilder } from "../query/WhereBuilder";
import type { Entity, EntityData, EntityManager } from "../../entities";
import { InvalidSearchParamsException } from "../../errors";
import { MutatorEvents } from "../../events";
import { RelationMutator } from "../../relations";
import type { RepoQuery } from "../../server/query";
import { MutatorResult, type MutatorResultOptions } from "./MutatorResult";
import { transformObject } from "core/utils";
type MutatorQB =
| InsertQueryBuilder<any, any, any>
@@ -86,7 +88,11 @@ export class Mutator<
throw new Error(`Field "${key}" is not fillable on entity "${entity.name}"`);
}
// transform from field
validatedData[key] = await field.transformPersist(data[key], this.em, context);
// transform to driver
validatedData[key] = this.em.connection.toDriver(validatedData[key], field);
}
if (Object.keys(validatedData).length === 0) {
@@ -283,6 +289,10 @@ export class Mutator<
): Promise<MutatorResult<Output[]>> {
const entity = this.entity;
const validatedData = await this.getValidatedData(data, "update");
console.log("updateWhere", {
entity,
validatedData,
});
// @todo: add a way to delete all by adding force?
if (!where || typeof where !== "object" || Object.keys(where).length === 0) {

View File

@@ -5,6 +5,7 @@ import { Result, type ResultJSON, type ResultOptions } from "../Result";
export type MutatorResultOptions = ResultOptions & {
silent?: boolean;
logParams?: boolean;
};
export type MutatorResultJSON<T = EntityData[]> = ResultJSON<T>;
@@ -19,7 +20,10 @@ export class MutatorResult<T = EntityData[]> extends Result<T> {
hydrator: (rows) => em.hydrate(entity.name, rows as any),
beforeExecute: (compiled) => {
if (!options?.silent) {
$console.debug(`[Mutation]\n${compiled.sql}\n`);
$console.debug(
`[Mutation]\n${compiled.sql}\n`,
options?.logParams ? compiled.parameters : undefined,
);
}
},
onError: (error) => {

View File

@@ -246,8 +246,10 @@ export class Repository<TBD extends object = DefaultDB, TB extends keyof TBD = a
qb = WhereBuilder.addClause(qb, options.where);
}
if (!ignore.includes("limit")) qb = qb.limit(options.limit ?? defaults.limit);
if (!ignore.includes("offset")) qb = qb.offset(options.offset ?? defaults.offset);
if (!ignore.includes("limit")) {
qb = qb.limit(options.limit ?? defaults.limit);
if (!ignore.includes("offset")) qb = qb.offset(options.offset ?? defaults.offset);
}
// sorting
if (!ignore.includes("sort")) {

View File

@@ -1,5 +1,5 @@
import { s } from "core/object/schema";
import { WhereBuilder, type WhereQuery } from "data";
import { WhereBuilder, type WhereQuery } from "data/entities/query/WhereBuilder";
import { $console } from "core";
import { isObject } from "core/utils";
import type { CoercionOptions, TAnyOf } from "jsonv-ts";