@dazejs/framework
Version:
Daze.js - A powerful web framework for Node.js
359 lines • 12.9 kB
JavaScript
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Repository = void 0;
const builder_1 = require("./builder");
const inspect = Symbol.for('nodejs.util.inspect.custom');
class Repository {
constructor(model) {
this.exists = false;
this.updateAttributeColumns = new Set();
this.withs = new Map();
this.needWithTrashed = false;
this.needWithSecret = false;
this.needAutoTimestap = true;
this.model = model;
const entity = this.model.createNewEntity();
for (const column of this.model.getColumns().keys()) {
if (entity[column] !== undefined) {
this[column] = entity[column];
}
}
return new Proxy(this, this.proxy());
}
getColumns() {
return this.model.getColumns().keys();
}
proxy() {
return {
set(target, p, value, receiver) {
if (target.isExists()) {
target.addUpdateAttributeColumn(p);
}
return Reflect.set(target, p, value, receiver);
},
get(target, p, receiver) {
const customs = target.model.getCustomColumns();
if (customs.includes(p)) {
return Reflect.get(target.model.getOriginEntity().prototype, p, target);
}
return Reflect.get(target, p, receiver);
}
};
}
isExists() {
return this.exists;
}
setExists(exists = true) {
this.exists = exists;
return this;
}
hasUpdatedAttributes() {
return !!this.updateAttributeColumns.size;
}
addUpdateAttributeColumn(key) {
if (this.model.getColumns().has(key)) {
this.updateAttributeColumns.add(key);
}
return this;
}
getUpdatedAttributes() {
const attributes = {};
for (const column of this.updateAttributeColumns) {
attributes[column] = this[column];
}
return attributes;
}
createQueryBuilder() {
const modelBuilder = (new builder_1.ModelBuilder(this.model, this));
return modelBuilder;
}
getPrimaryValue() {
var _a;
return (_a = this[this.model.getPrimaryKey()]) !== null && _a !== void 0 ? _a : null;
}
fill(data) {
if (!data)
return this;
const keys = this.model.getColumns().keys();
for (const key of keys) {
this.setAttribute(key, data[key]);
}
return this;
}
getAttributes() {
const attributes = {};
const columns = this.model.getColumns();
for (const [column, desc] of columns) {
if (!desc.secret) {
attributes[column] = this[column];
}
else {
if (this.needWithSecret) {
attributes[column] = this[column];
}
}
}
const relationMap = this.model.getRelationMap();
for (const realtion of relationMap.keys()) {
const _realtion = this[realtion];
if (_realtion) {
if (Array.isArray(_realtion)) {
attributes[realtion] = _realtion.map(item => item === null || item === void 0 ? void 0 : item.getAttributes());
}
else {
attributes[realtion] = _realtion === null || _realtion === void 0 ? void 0 : _realtion.getAttributes();
}
}
}
return attributes;
}
setAttribute(key, value) {
if (value === undefined)
return this;
this[key] = value;
if (this.isExists()) {
this.addUpdateAttributeColumn(key);
}
return this;
}
getAttribute(key) {
if (!key)
return;
if (this.model.getColumns().has(key) ||
this.model.getCustomColumns().includes(key) ||
this.model.getRelationMap().has(key))
return this[key];
}
with(relation, callback) {
const relationImp = this.model.getRelationImp(relation);
if (relationImp) {
this.setWith(relation, relationImp, callback);
}
return this;
}
withTrashed() {
this.needWithTrashed = true;
return this;
}
withSecret() {
this.needWithSecret = true;
return this;
}
getWiths() {
return this.withs;
}
setWiths(withs) {
this.withs = withs;
return this;
}
setWith(relation, value, queryCallback) {
this.withs.set(relation, {
relation: value,
queryCallback
});
return this;
}
async eagerly(withs, result) {
for (const [relation, relationOption] of withs) {
const { relation: relationImp, queryCallback } = relationOption;
await relationImp.eagerly(result, relation, queryCallback);
}
}
async eagerlyCollection(withs, results) {
for (const [relation, relationOption] of withs) {
const { relation: relationImp, queryCallback } = relationOption;
await relationImp.eagerlyMap(results, relation, queryCallback);
}
}
async delete() {
if (!this.model.getPrimaryKey()) {
throw new Error('Primary key not defined');
}
if (!this.isExists())
return false;
await this.executeDelete();
return true;
}
async executeDelete() {
const query = this.createQueryBuilder();
if (this.model.isForceDelete()) {
await query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).delete();
this.setExists(false);
return true;
}
const attributes = {};
attributes[this.model.getSoftDeleteKey()] = this.model.getFormatedDate(this.model.getColumnType(this.model.getSoftDeleteKey()));
if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) {
const updateTimestampKey = this.model.getUpdateTimestampKey();
attributes[updateTimestampKey] = this.model.getFormatedDate(this.model.getColumnType(updateTimestampKey));
}
return query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).update(attributes);
}
async get(id) {
const query = this.createQueryBuilder();
if (!this.model.isForceDelete() && !this.needWithTrashed) {
if (this.model.getSoftDeleteDefaultValue() === null) {
query.whereNull(this.model.getSoftDeleteKey());
}
else {
query.where(this.model.getSoftDeleteKey(), this.model.getSoftDeleteDefaultValue());
}
}
return query.where(this.model.getPrimaryKey(), '=', id).first();
}
async save() {
const query = this.createQueryBuilder();
if (this.isExists()) {
if (!this.hasUpdatedAttributes())
return true;
if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) {
const key = this.model.getUpdateTimestampKey();
const val = this.model.getFreshDateWithColumnKey(key);
this[key] = val;
}
const updatedAttributes = this.getUpdatedAttributes();
return this.executeUpdate(query, updatedAttributes);
}
else {
if (this.needAutoTimestap && this.model.hasCreateTimestamp()) {
const key = this.model.getCreateTimestampKey();
const val = this.model.getFreshDateWithColumnKey(key);
this[key] = val;
}
if (this.needAutoTimestap && this.model.hasUpdateTimestamp()) {
const key = this.model.getUpdateTimestampKey();
const val = this.model.getFreshDateWithColumnKey(key);
this[key] = val;
}
if (this.model.isIncrementing()) {
await this.executeInsertAndSetId(query);
}
else {
if (!this.model.getColumns().size)
return true;
await query.insert(this.getIntertAttributes());
}
this.setExists(true);
}
return true;
}
getIntertAttributes() {
const attributes = {};
const columns = this.model.getColumns();
for (const [column] of columns) {
attributes[column] = this[column];
}
return attributes;
}
async executeInsertAndSetId(query) {
const id = await query.insert(this.getIntertAttributes());
this.setAttribute(this.model.getPrimaryKey(), id);
return this;
}
async executeUpdate(query, attributes) {
await query.where(this.model.getPrimaryKey(), '=', this.getPrimaryValue()).update(attributes);
return true;
}
async create(attributes) {
const repos = this.model.createRepository().setExists(false).fill(attributes);
await repos.save();
return repos;
}
async destroy(...ids) {
let count = 0;
if (!ids.length)
return count;
const key = this.model.getPrimaryKey();
const results = await this.createQueryBuilder().whereIn(key, ids).find();
for (const result of results) {
if (await result.delete()) {
count++;
}
}
return count;
}
toJSON() {
return this.getAttributes();
}
[inspect]() {
return this.toJSON();
}
withoutAutoTimestamp() {
this.needAutoTimestap = false;
return this;
}
async attach(relation, ...idsWithDatas) {
var _a;
if (!this.isExists()) {
throw new Error('model does not exists!');
}
const relationMap = this.model.getRelationMap();
if (!relationMap.has(relation) || ((_a = relationMap.get(relation)) === null || _a === void 0 ? void 0 : _a.type) !== 'belongsToMany') {
throw new Error(`model does not have many to many relation: [${relation}]!`);
}
const imp = this.model.getRelationImp(relation);
const insertData = [];
const repos = imp.pivot.createRepository();
for (const item of idsWithDatas) {
let _id;
let _data = {};
if (typeof item === 'object' && item.id) {
const { id } = item, rest = __rest(item, ["id"]);
_id = id;
_data = Object.assign({}, rest);
}
else {
_id = item;
}
const data = Object.assign({ [`${imp.foreignPivotKey}`]: this.getPrimaryValue(), [`${imp.relatedPivotKey}`]: _id }, _data);
if (this.needAutoTimestap && repos.model.hasCreateTimestamp()) {
const key = repos.model.getCreateTimestampKey();
const val = repos.model.getFreshDateWithColumnKey(key);
data[key] = val;
}
if (this.needAutoTimestap && repos.model.hasUpdateTimestamp()) {
const key = repos.model.getUpdateTimestampKey();
const val = repos.model.getFreshDateWithColumnKey(key);
data[key] = val;
}
insertData.push(data);
}
await repos
.createQueryBuilder()
.getBuilder()
.insertAll(insertData);
return repos;
}
async detach(relation, ...ids) {
var _a;
if (!this.isExists()) {
throw new Error('model does not exists!');
}
const relationMap = this.model.getRelationMap();
if (!relationMap.has(relation) || ((_a = relationMap.get(relation)) === null || _a === void 0 ? void 0 : _a.type) !== 'belongsToMany') {
throw new Error(`model does not have many to many relation: [${relation}]!`);
}
const imp = this.model.getRelationImp(relation);
const repos = imp.pivot.createRepository();
await repos
.createQueryBuilder()
.getBuilder()
.where(imp.foreignPivotKey, '=', this.getPrimaryValue())
.whereIn(imp.relatedPivotKey, ids)
.delete();
return repos;
}
}
exports.Repository = Repository;
//# sourceMappingURL=repository.js.map