mirror of
https://github.com/strapi/strapi.git
synced 2025-09-06 15:22:59 +00:00
Entity manager wip
This commit is contained in:
parent
c46760bcc4
commit
909ca0ee73
@ -1,3 +1,4 @@
|
|||||||
|
import type { Knex } from 'knex';
|
||||||
import {
|
import {
|
||||||
castArray,
|
castArray,
|
||||||
compact,
|
compact,
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
isNil,
|
isNil,
|
||||||
isNull,
|
isNull,
|
||||||
isNumber,
|
isNumber,
|
||||||
|
isObject,
|
||||||
isPlainObject,
|
isPlainObject,
|
||||||
isString,
|
isString,
|
||||||
isUndefined,
|
isUndefined,
|
||||||
@ -36,6 +38,7 @@ import {
|
|||||||
isOneToAny,
|
isOneToAny,
|
||||||
hasOrderColumn,
|
hasOrderColumn,
|
||||||
hasInverseOrderColumn,
|
hasInverseOrderColumn,
|
||||||
|
isRelationAttribute,
|
||||||
} from '../metadata/relations';
|
} from '../metadata/relations';
|
||||||
import {
|
import {
|
||||||
deletePreviousOneToAnyRelations,
|
deletePreviousOneToAnyRelations,
|
||||||
@ -50,12 +53,34 @@ import {
|
|||||||
} from './relations/cloning/regular-relations';
|
} from './relations/cloning/regular-relations';
|
||||||
import { DatabaseError } from '../errors';
|
import { DatabaseError } from '../errors';
|
||||||
import type { Database } from '..';
|
import type { Database } from '..';
|
||||||
|
import type { Meta } from '../metadata/types';
|
||||||
|
import type { ID } from '../typings';
|
||||||
|
|
||||||
const toId = (value) => value.id || value;
|
type Params = {
|
||||||
const toIds = (value) => castArray(value || []).map(toId);
|
where?: any;
|
||||||
|
filters?: any;
|
||||||
|
select?: any;
|
||||||
|
populate?: any;
|
||||||
|
orderBy?: any;
|
||||||
|
_q?: string;
|
||||||
|
data?: any;
|
||||||
|
};
|
||||||
|
|
||||||
const isValidId = (value) => isString(value) || isInteger(value);
|
type Entity = {
|
||||||
const toIdArray = (data) => {
|
id: ID;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isObj = (value: unknown): value is object => isObject(value) && !isNil(value);
|
||||||
|
|
||||||
|
const toId = (value: unknown | { id: unknown }) =>
|
||||||
|
isObject(value) && !isNil(value) && 'id' in value ? value.id : value;
|
||||||
|
const toIds = (value: unknown) => castArray(value || []).map(toId);
|
||||||
|
|
||||||
|
const isValidId = (value: unknown): value is ID => isString(value) || isInteger(value);
|
||||||
|
const isValidObjectId = (value: unknown): value is Record<string, unknown> & { id: ID } =>
|
||||||
|
isObj(value) && 'id' in value && isValidId(value.id);
|
||||||
|
const toIdArray = (data: unknown) => {
|
||||||
const array = castArray(data)
|
const array = castArray(data)
|
||||||
.filter((datum) => !isNil(datum))
|
.filter((datum) => !isNil(datum))
|
||||||
.map((datum) => {
|
.map((datum) => {
|
||||||
@ -65,17 +90,39 @@ const toIdArray = (data) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if it is an object check it has at least a valid id
|
// if it is an object check it has at least a valid id
|
||||||
if (!has('id', datum) || !isValidId(datum.id)) {
|
if (!isValidObjectId(datum)) {
|
||||||
throw new Error(`Invalid id, expected a string or integer, got ${datum}`);
|
throw new Error(`Invalid id, expected a string or integer, got ${datum}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return datum;
|
return datum;
|
||||||
});
|
});
|
||||||
|
|
||||||
return uniqWith(isEqual, array);
|
return uniqWith(isEqual, array);
|
||||||
};
|
};
|
||||||
|
|
||||||
const toAssocs = (data) => {
|
type ScalarAssoc = string | number | null;
|
||||||
if (isArray(data) || isString(data) || isNumber(data) || isNull(data) || data?.id) {
|
type Assocs =
|
||||||
|
| ScalarAssoc
|
||||||
|
| { id: ScalarAssoc | Array<ScalarAssoc> }
|
||||||
|
| Array<ScalarAssoc>
|
||||||
|
| {
|
||||||
|
set?: Array<ScalarAssoc> | null;
|
||||||
|
options?: { strict?: boolean };
|
||||||
|
connect?: Array<{
|
||||||
|
id: ScalarAssoc;
|
||||||
|
position?: { start?: boolean; end?: boolean };
|
||||||
|
}> | null;
|
||||||
|
disconnect?: Array<ScalarAssoc> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const toAssocs = (data: Assocs) => {
|
||||||
|
if (
|
||||||
|
isArray(data) ||
|
||||||
|
isString(data) ||
|
||||||
|
isNumber(data) ||
|
||||||
|
isNull(data) ||
|
||||||
|
(isObj(data) && 'id' in data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
set: isNull(data) ? data : toIdArray(data),
|
set: isNull(data) ? data : toIdArray(data),
|
||||||
};
|
};
|
||||||
@ -99,10 +146,14 @@ const toAssocs = (data) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const processData = (metadata, data = {}, { withDefaults = false } = {}) => {
|
const processData = (
|
||||||
|
metadata: Meta,
|
||||||
|
data: Record<string, unknown> = {},
|
||||||
|
{ withDefaults = false } = {}
|
||||||
|
) => {
|
||||||
const { attributes } = metadata;
|
const { attributes } = metadata;
|
||||||
|
|
||||||
const obj = {};
|
const obj: Record<string, unknown> = {};
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
const attribute = attributes[attributeName];
|
const attribute = attributes[attributeName];
|
||||||
@ -121,7 +172,11 @@ const processData = (metadata, data = {}, { withDefaults = false } = {}) => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof field.validate === 'function' && data[attributeName] !== null) {
|
if (
|
||||||
|
'validate' in field &&
|
||||||
|
typeof field.validate === 'function' &&
|
||||||
|
data[attributeName] !== null
|
||||||
|
) {
|
||||||
field.validate(data[attributeName]);
|
field.validate(data[attributeName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +185,7 @@ const processData = (metadata, data = {}, { withDefaults = false } = {}) => {
|
|||||||
obj[attributeName] = val;
|
obj[attributeName] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.isRelation(attribute.type)) {
|
if (isRelationAttribute(attribute)) {
|
||||||
// oneToOne & manyToOne
|
// oneToOne & manyToOne
|
||||||
if (attribute.joinColumn && attribute.owner) {
|
if (attribute.joinColumn && attribute.owner) {
|
||||||
const joinColumnName = attribute.joinColumn.name;
|
const joinColumnName = attribute.joinColumn.name;
|
||||||
@ -150,7 +205,7 @@ const processData = (metadata, data = {}, { withDefaults = false } = {}) => {
|
|||||||
if (attribute.morphColumn && attribute.owner) {
|
if (attribute.morphColumn && attribute.owner) {
|
||||||
const { idColumn, typeColumn, typeField = '__type' } = attribute.morphColumn;
|
const { idColumn, typeColumn, typeField = '__type' } = attribute.morphColumn;
|
||||||
|
|
||||||
const value = data[attributeName];
|
const value = data[attributeName] as Record<string, unknown>;
|
||||||
|
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
Object.assign(obj, {
|
Object.assign(obj, {
|
||||||
@ -182,10 +237,13 @@ export const createEntityManager = (db: Database) => {
|
|||||||
const repoMap: Record<string, any> = {};
|
const repoMap: Record<string, any> = {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async findOne(uid, params) {
|
async findOne(uid: string, params: Params) {
|
||||||
const states = await db.lifecycles.run('beforeFindOne', uid, { params });
|
const states = await db.lifecycles.run('beforeFindOne', uid, { params });
|
||||||
|
|
||||||
const result = await this.createQueryBuilder(uid).init(params).first().execute();
|
const result = await this.createQueryBuilder(uid)
|
||||||
|
.init(params)
|
||||||
|
.first()
|
||||||
|
.execute<Entity | null>();
|
||||||
|
|
||||||
await db.lifecycles.run('afterFindOne', uid, { params, result }, states);
|
await db.lifecycles.run('afterFindOne', uid, { params, result }, states);
|
||||||
|
|
||||||
@ -193,7 +251,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// should we name it findOne because people are used to it ?
|
// should we name it findOne because people are used to it ?
|
||||||
async findMany(uid, params) {
|
async findMany(uid: string, params: Params) {
|
||||||
const states = await db.lifecycles.run('beforeFindMany', uid, { params });
|
const states = await db.lifecycles.run('beforeFindMany', uid, { params });
|
||||||
|
|
||||||
const result = await this.createQueryBuilder(uid).init(params).execute();
|
const result = await this.createQueryBuilder(uid).init(params).execute();
|
||||||
@ -203,14 +261,14 @@ export const createEntityManager = (db: Database) => {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
async count(uid, params) {
|
async count(uid: string, params: Params) {
|
||||||
const states = await db.lifecycles.run('beforeCount', uid, { params });
|
const states = await db.lifecycles.run('beforeCount', uid, { params });
|
||||||
|
|
||||||
const res = await this.createQueryBuilder(uid)
|
const res = await this.createQueryBuilder(uid)
|
||||||
.init(pick(['_q', 'where', 'filters'], params))
|
.init(pick(['_q', 'where', 'filters'], params))
|
||||||
.count()
|
.count()
|
||||||
.first()
|
.first()
|
||||||
.execute();
|
.execute<{ count: number }>();
|
||||||
|
|
||||||
const result = Number(res.count);
|
const result = Number(res.count);
|
||||||
|
|
||||||
@ -219,7 +277,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
async create(uid, params = {}) {
|
async create(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeCreate', uid, { params });
|
const states = await db.lifecycles.run('beforeCreate', uid, { params });
|
||||||
|
|
||||||
const metadata = db.metadata.get(uid);
|
const metadata = db.metadata.get(uid);
|
||||||
@ -231,9 +289,11 @@ export const createEntityManager = (db: Database) => {
|
|||||||
|
|
||||||
const dataToInsert = processData(metadata, data, { withDefaults: true });
|
const dataToInsert = processData(metadata, data, { withDefaults: true });
|
||||||
|
|
||||||
const res = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
const res = await this.createQueryBuilder(uid)
|
||||||
|
.insert(dataToInsert)
|
||||||
|
.execute<Array<ID | { id: ID }>>();
|
||||||
|
|
||||||
const id = res[0].id || res[0];
|
const id = isObj(res[0]) ? res[0].id : res[0];
|
||||||
|
|
||||||
const trx = await strapi.db.transaction();
|
const trx = await strapi.db.transaction();
|
||||||
try {
|
try {
|
||||||
@ -260,7 +320,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// TODO: where do we handle relation processing for many queries ?
|
// TODO: where do we handle relation processing for many queries ?
|
||||||
async createMany(uid, params = {}) {
|
async createMany(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeCreateMany', uid, { params });
|
const states = await db.lifecycles.run('beforeCreateMany', uid, { params });
|
||||||
|
|
||||||
const metadata = db.metadata.get(uid);
|
const metadata = db.metadata.get(uid);
|
||||||
@ -278,7 +338,9 @@ export const createEntityManager = (db: Database) => {
|
|||||||
throw new Error('Nothing to insert');
|
throw new Error('Nothing to insert');
|
||||||
}
|
}
|
||||||
|
|
||||||
const createdEntries = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
const createdEntries = await this.createQueryBuilder(uid)
|
||||||
|
.insert(dataToInsert)
|
||||||
|
.execute<Array<ID | { id: ID }>>();
|
||||||
|
|
||||||
const result = {
|
const result = {
|
||||||
count: data.length,
|
count: data.length,
|
||||||
@ -290,7 +352,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
async update(uid, params = {}) {
|
async update(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeUpdate', uid, { params });
|
const states = await db.lifecycles.run('beforeUpdate', uid, { params });
|
||||||
|
|
||||||
const metadata = db.metadata.get(uid);
|
const metadata = db.metadata.get(uid);
|
||||||
@ -308,7 +370,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
.select('*')
|
.select('*')
|
||||||
.where(where)
|
.where(where)
|
||||||
.first()
|
.first()
|
||||||
.execute({ mapResults: false });
|
.execute<{ id: ID }>({ mapResults: false });
|
||||||
|
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
return null;
|
return null;
|
||||||
@ -345,7 +407,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// TODO: where do we handle relation processing for many queries ?
|
// TODO: where do we handle relation processing for many queries ?
|
||||||
async updateMany(uid, params = {}) {
|
async updateMany(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeUpdateMany', uid, { params });
|
const states = await db.lifecycles.run('beforeUpdateMany', uid, { params });
|
||||||
|
|
||||||
const metadata = db.metadata.get(uid);
|
const metadata = db.metadata.get(uid);
|
||||||
@ -360,7 +422,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
const updatedRows = await this.createQueryBuilder(uid)
|
const updatedRows = await this.createQueryBuilder(uid)
|
||||||
.where(where)
|
.where(where)
|
||||||
.update(dataToUpdate)
|
.update(dataToUpdate)
|
||||||
.execute();
|
.execute<number>();
|
||||||
|
|
||||||
const result = { count: updatedRows };
|
const result = { count: updatedRows };
|
||||||
|
|
||||||
@ -369,7 +431,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
async clone(uid, cloneId, params = {}) {
|
async clone(uid: string, cloneId: ID, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeCreate', uid, { params });
|
const states = await db.lifecycles.run('beforeCreate', uid, { params });
|
||||||
|
|
||||||
const metadata = db.metadata.get(uid);
|
const metadata = db.metadata.get(uid);
|
||||||
@ -386,24 +448,28 @@ export const createEntityManager = (db: Database) => {
|
|||||||
// Omit unwanted properties
|
// Omit unwanted properties
|
||||||
omit(['id', 'created_at', 'updated_at']),
|
omit(['id', 'created_at', 'updated_at']),
|
||||||
// Merge with provided data, set attribute to null if data attribute is null
|
// Merge with provided data, set attribute to null if data attribute is null
|
||||||
mergeWith(data || {}, (original, override) => (override === null ? override : original)),
|
mergeWith(data || {}, (original: unknown, override: unknown) =>
|
||||||
|
override === null ? override : original
|
||||||
|
),
|
||||||
// Process data with metadata
|
// Process data with metadata
|
||||||
(entity) => processData(metadata, entity, { withDefaults: true })
|
(entity: Record<string, unknown>) => processData(metadata, entity, { withDefaults: true })
|
||||||
)(entity);
|
)(entity);
|
||||||
|
|
||||||
const res = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
const res = await this.createQueryBuilder(uid)
|
||||||
|
.insert(dataToInsert)
|
||||||
|
.execute<Array<ID | { id: ID }>>();
|
||||||
|
|
||||||
const id = res[0].id || res[0];
|
const id = isObj(res[0]) ? res[0].id : res[0];
|
||||||
|
|
||||||
const trx = await strapi.db.transaction();
|
const trx = await strapi.db.transaction();
|
||||||
try {
|
try {
|
||||||
const cloneAttrs = Object.entries(metadata.attributes).reduce((acc, [attrName, attr]) => {
|
const cloneAttrs = Object.entries(metadata.attributes).reduce((acc, [attrName, attr]) => {
|
||||||
// TODO: handle components in the db layer
|
// TODO: handle components in the db layer
|
||||||
if (attr.type === 'relation' && attr.joinTable && !attr.component) {
|
if (isRelationAttribute(attr) && attr.joinTable && !attr.component) {
|
||||||
acc.push(attrName);
|
acc.push(attrName);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, [] as string[]);
|
||||||
|
|
||||||
await this.cloneRelations(uid, id, cloneId, data, { cloneAttrs, transaction: trx.get() });
|
await this.cloneRelations(uid, id, cloneId, data, { cloneAttrs, transaction: trx.get() });
|
||||||
await trx.commit();
|
await trx.commit();
|
||||||
@ -424,7 +490,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
async delete(uid, params = {}) {
|
async delete(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeDelete', uid, { params });
|
const states = await db.lifecycles.run('beforeDelete', uid, { params });
|
||||||
|
|
||||||
const { where, select, populate } = params;
|
const { where, select, populate } = params;
|
||||||
@ -464,7 +530,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// TODO: where do we handle relation processing for many queries ?
|
// TODO: where do we handle relation processing for many queries ?
|
||||||
async deleteMany(uid, params = {}) {
|
async deleteMany(uid: string, params: Params = {}) {
|
||||||
const states = await db.lifecycles.run('beforeDeleteMany', uid, { params });
|
const states = await db.lifecycles.run('beforeDeleteMany', uid, { params });
|
||||||
|
|
||||||
const { where } = params;
|
const { where } = params;
|
||||||
@ -480,13 +546,13 @@ export const createEntityManager = (db: Database) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach relations to a new entity
|
* Attach relations to a new entity
|
||||||
*
|
|
||||||
* @param {EntityManager} em - entity manager instance
|
|
||||||
* @param {Metadata} metadata - model metadta
|
|
||||||
* @param {ID} id - entity ID
|
|
||||||
* @param {object} data - data received for creation
|
|
||||||
*/
|
*/
|
||||||
async attachRelations(uid, id, data, { transaction: trx }) {
|
async attachRelations(
|
||||||
|
uid: string,
|
||||||
|
id: ID,
|
||||||
|
data: Record<string, any>,
|
||||||
|
{ transaction: trx }: { transaction: Knex.Transaction }
|
||||||
|
) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -494,7 +560,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
|
|
||||||
const isValidLink = has(attributeName, data) && !isNil(data[attributeName]);
|
const isValidLink = has(attributeName, data) && !isNil(data[attributeName]);
|
||||||
|
|
||||||
if (attribute.type !== 'relation' || !isValidLink) {
|
if (!isRelationAttribute(attribute) || !isValidLink) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,14 +770,9 @@ export const createEntityManager = (db: Database) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates relations of an existing entity
|
* Updates relations of an existing entity
|
||||||
*
|
|
||||||
* @param {EntityManager} em - entity manager instance
|
|
||||||
* @param {Metadata} metadata - model metadta
|
|
||||||
* @param {ID} id - entity ID
|
|
||||||
* @param {object} data - data received for creation
|
|
||||||
*/
|
*/
|
||||||
// TODO: check relation exists (handled by FKs except for polymorphics)
|
// TODO: check relation exists (handled by FKs except for polymorphics)
|
||||||
async updateRelations(uid, id, data, { transaction: trx }) {
|
async updateRelations(uid: string, id: ID, data, { transaction: trx }) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -1123,7 +1184,15 @@ export const createEntityManager = (db: Database) => {
|
|||||||
* @param {Metadata} metadata - model metadta
|
* @param {Metadata} metadata - model metadta
|
||||||
* @param {ID} id - entity ID
|
* @param {ID} id - entity ID
|
||||||
*/
|
*/
|
||||||
async deleteRelations(uid, id, { transaction: trx }) {
|
async deleteRelations(
|
||||||
|
uid: string,
|
||||||
|
id: ID,
|
||||||
|
{
|
||||||
|
transaction: trx,
|
||||||
|
}: {
|
||||||
|
transaction: Knex.Transaction;
|
||||||
|
}
|
||||||
|
) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
for (const attributeName of Object.keys(attributes)) {
|
for (const attributeName of Object.keys(attributes)) {
|
||||||
@ -1244,7 +1313,19 @@ export const createEntityManager = (db: Database) => {
|
|||||||
* @example cloneRelations('user', 3, 1, { cloneAttrs: ["comments"]})
|
* @example cloneRelations('user', 3, 1, { cloneAttrs: ["comments"]})
|
||||||
* @example cloneRelations('post', 5, 2, { cloneAttrs: ["comments", "likes"] })
|
* @example cloneRelations('post', 5, 2, { cloneAttrs: ["comments", "likes"] })
|
||||||
*/
|
*/
|
||||||
async cloneRelations(uid, targetId, sourceId, data, { cloneAttrs = [], transaction }) {
|
async cloneRelations(
|
||||||
|
uid: string,
|
||||||
|
targetId: ID,
|
||||||
|
sourceId: ID,
|
||||||
|
data: any,
|
||||||
|
{
|
||||||
|
cloneAttrs = [],
|
||||||
|
transaction,
|
||||||
|
}: {
|
||||||
|
cloneAttrs?: string[];
|
||||||
|
transaction: Knex.Transaction;
|
||||||
|
}
|
||||||
|
) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
if (!attributes) {
|
if (!attributes) {
|
||||||
@ -1300,7 +1381,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// TODO: add lifecycle events
|
// TODO: add lifecycle events
|
||||||
async populate(uid, entity, populate) {
|
async populate(uid: string, entity: Entity, populate: Params['populate']) {
|
||||||
const entry = await this.findOne(uid, {
|
const entry = await this.findOne(uid, {
|
||||||
select: ['id'],
|
select: ['id'],
|
||||||
where: { id: entity.id },
|
where: { id: entity.id },
|
||||||
@ -1311,7 +1392,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// TODO: add lifecycle events
|
// TODO: add lifecycle events
|
||||||
async load(uid, entity, fields, params) {
|
async load(uid: string, entity: Entity, fields: string | string[], params: Params) {
|
||||||
const { attributes } = db.metadata.get(uid);
|
const { attributes } = db.metadata.get(uid);
|
||||||
|
|
||||||
const fieldsArr = castArray(fields);
|
const fieldsArr = castArray(fields);
|
||||||
@ -1329,7 +1410,7 @@ export const createEntityManager = (db: Database) => {
|
|||||||
populate: fieldsArr.reduce((acc, field) => {
|
populate: fieldsArr.reduce((acc, field) => {
|
||||||
acc[field] = params || true;
|
acc[field] = params || true;
|
||||||
return acc;
|
return acc;
|
||||||
}, {}),
|
}, {} as Record<string, unknown>),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
|
@ -8,6 +8,7 @@ export interface ColumnInfo {
|
|||||||
export interface Attribute {
|
export interface Attribute {
|
||||||
type: string;
|
type: string;
|
||||||
columnName?: string;
|
columnName?: string;
|
||||||
|
default?: any;
|
||||||
column?: ColumnInfo;
|
column?: ColumnInfo;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
unique?: boolean;
|
unique?: boolean;
|
||||||
@ -46,6 +47,7 @@ export interface BidirectionalAttributeJoinTable extends AttributeJoinTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MorphColumn {
|
export interface MorphColumn {
|
||||||
|
typeField?: string;
|
||||||
typeColumn: {
|
typeColumn: {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
@ -80,7 +80,7 @@ export interface QueryBuilder {
|
|||||||
stream<T>({ mapResults }?: { mapResults?: boolean }): T;
|
stream<T>({ mapResults }?: { mapResults?: boolean }): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
const createQueryBuilder = (
|
const createQueryBuilder = <TResult>(
|
||||||
uid: string,
|
uid: string,
|
||||||
db: Database,
|
db: Database,
|
||||||
initialState: Partial<State> = {}
|
initialState: Partial<State> = {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user