EdgeAIG's picture
download
raw
6.9 kB
import * as Effect from "../../Effect.js";
import * as RequestResolver from "../../RequestResolver.js";
import { SqlClient } from "./SqlClient.js";
import * as SqlResolver from "./SqlResolver.js";
import * as SqlSchema from "./SqlSchema.js";
/**
* Creates a CRUD repository for a schema model backed by a SQL table, with
* insert, update, find-by-id, and delete operations. When `softDeleteColumn` is
* supplied, reads ignore soft-deleted rows and delete updates that column
* instead of removing the row.
*
* @category repository
* @since 4.0.0
*/
export const makeRepository = (Model, options) => Effect.gen(function* () {
const sql = yield* SqlClient;
const idSchema = Model.fields[options.idColumn];
const idColumn = options.idColumn;
const softDeleteColumn = options.softDeleteColumn;
const withSoftDeleteFilter = where => softDeleteColumn === undefined ? where : sql.and([where, sql`${sql(softDeleteColumn)} is null`]);
const setSoftDeleted = softDeleteColumn === undefined ? undefined : sql`${sql(softDeleteColumn)} = CURRENT_TIMESTAMP`;
const insertSchema = SqlSchema.findOne({
Request: Model.insert,
Result: Model,
execute: request => sql.onDialectOrElse({
mysql: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request)};
select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = LAST_INSERT_ID()`)};`.unprepared.pipe(Effect.map(([, results]) => results)),
orElse: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request).returning("*")}`
})
});
const insert = insert => insertSchema(insert).pipe(Effect.catchTag("NoSuchElementError", Effect.die), Effect.withSpan(`${options.spanPrefix}.insert`, {}, {
captureStackTrace: false
}));
const insertVoidSchema = SqlSchema.void({
Request: Model.insert,
execute: request => sql`insert into ${sql(options.tableName)} ${sql.insert(request)}`
});
const insertVoid = insert => insertVoidSchema(insert).pipe(Effect.withSpan(`${options.spanPrefix}.insertVoid`, {}, {
captureStackTrace: false
}));
const updateSchema = SqlSchema.findOne({
Request: Model.update,
Result: Model,
execute: request => sql.onDialectOrElse({
mysql: () => sql`update ${sql(options.tableName)} set ${sql.update(request, [idColumn])} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${request[idColumn]}`)};
select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${request[idColumn]}`)};`.unprepared.pipe(Effect.map(([, results]) => results)),
orElse: () => sql`update ${sql(options.tableName)} set ${sql.update(request, [idColumn])} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${request[idColumn]}`)} returning *`
})
});
const update = update => updateSchema(update).pipe(Effect.catchTag("NoSuchElementError", Effect.die), Effect.withSpan(`${options.spanPrefix}.update`, {
attributes: {
id: update[idColumn]
}
}, {
captureStackTrace: false
}));
const updateVoidSchema = SqlSchema.void({
Request: Model.update,
execute: request => sql`update ${sql(options.tableName)} set ${sql.update(request, [idColumn])} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${request[idColumn]}`)}`
});
const updateVoid = update => updateVoidSchema(update).pipe(Effect.withSpan(`${options.spanPrefix}.updateVoid`, {
attributes: {
id: update[idColumn]
}
}, {
captureStackTrace: false
}));
const findByIdSchema = SqlSchema.findOne({
Request: idSchema,
Result: Model,
execute: id => sql`select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${id}`)}`
});
const findById = id => findByIdSchema(id).pipe(Effect.withSpan(`${options.spanPrefix}.findById`, {
attributes: {
id
}
}, {
captureStackTrace: false
}));
const deleteSchema = SqlSchema.void({
Request: idSchema,
execute: id => softDeleteColumn === undefined ? sql`delete from ${sql(options.tableName)} where ${sql(idColumn)} = ${id}` : sql`update ${sql(options.tableName)} set ${setSoftDeleted} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = ${id}`)}`
});
const delete_ = id => deleteSchema(id).pipe(Effect.withSpan(`${options.spanPrefix}.delete`, {
attributes: {
id
}
}, {
captureStackTrace: false
}));
return {
insert,
insertVoid,
update,
updateVoid,
findById,
delete: delete_
};
});
/**
* Creates batched request resolvers for a schema model's insert, insert-void,
* find-by-id, and delete operations, honoring the optional soft-delete column.
*
* @category repository
* @since 4.0.0
*/
export const makeResolvers = (Model, options) => Effect.gen(function* () {
const sql = yield* SqlClient;
const idSchema = Model.fields[options.idColumn];
const idColumn = options.idColumn;
const softDeleteColumn = options.softDeleteColumn;
const withSoftDeleteFilter = where => softDeleteColumn === undefined ? where : sql.and([where, sql`${sql(softDeleteColumn)} is null`]);
const setSoftDeleted = softDeleteColumn === undefined ? undefined : sql`${sql(softDeleteColumn)} = CURRENT_TIMESTAMP`;
const insert = SqlResolver.ordered({
Request: Model.insert,
Result: Model,
execute: request => sql.onDialectOrElse({
mysql: () => Effect.forEach(request, request => sql`insert into ${sql(options.tableName)} ${sql.insert(request)};
select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql`${sql(idColumn)} = LAST_INSERT_ID()`)};`.unprepared.pipe(Effect.map(([, results]) => results[0])), {
concurrency: 10
}),
orElse: () => sql`insert into ${sql(options.tableName)} ${sql.insert(request).returning("*")}`
})
}).pipe(RequestResolver.withSpan(`${options.spanPrefix}.insertResolver`));
const insertVoid = SqlResolver.void({
Request: Model.insert,
execute: request => sql`insert into ${sql(options.tableName)} ${sql.insert(request)}`
}).pipe(RequestResolver.withSpan(`${options.spanPrefix}.insertVoidResolver`));
const findById = SqlResolver.findById({
Id: idSchema,
Result: Model,
ResultId(request) {
return request[idColumn];
},
execute: ids => sql`select * from ${sql(options.tableName)} where ${withSoftDeleteFilter(sql.in(idColumn, ids))}`
}).pipe(RequestResolver.withSpan(`${options.spanPrefix}.findByIdResolver`));
const delete_ = SqlResolver.void({
Request: idSchema,
execute: ids => softDeleteColumn === undefined ? sql`delete from ${sql(options.tableName)} where ${sql.in(idColumn, ids)}` : sql`update ${sql(options.tableName)} set ${setSoftDeleted} where ${withSoftDeleteFilter(sql.in(idColumn, ids))}`
}).pipe(RequestResolver.withSpan(`${options.spanPrefix}.deleteResolver`));
return {
insert,
insertVoid,
findById,
delete: delete_
};
});
//# sourceMappingURL=SqlModel.js.map

Xet Storage Details

Size:
6.9 kB
·
Xet hash:
8442cc6e7ef4a80b0a108594867e0429687d6c2309564dc55ff25bb286e33655

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.