Initial commit
This commit is contained in:
316
node_modules/drizzle-orm/relations.js
generated
vendored
Normal file
316
node_modules/drizzle-orm/relations.js
generated
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
import { getTableUniqueName, Table } from "./table.js";
|
||||
import { Column } from "./column.js";
|
||||
import { entityKind, is } from "./entity.js";
|
||||
import { PrimaryKeyBuilder } from "./pg-core/primary-keys.js";
|
||||
import {
|
||||
and,
|
||||
asc,
|
||||
between,
|
||||
desc,
|
||||
eq,
|
||||
exists,
|
||||
gt,
|
||||
gte,
|
||||
ilike,
|
||||
inArray,
|
||||
isNotNull,
|
||||
isNull,
|
||||
like,
|
||||
lt,
|
||||
lte,
|
||||
ne,
|
||||
not,
|
||||
notBetween,
|
||||
notExists,
|
||||
notIlike,
|
||||
notInArray,
|
||||
notLike,
|
||||
or
|
||||
} from "./sql/expressions/index.js";
|
||||
import { SQL, sql } from "./sql/sql.js";
|
||||
class Relation {
|
||||
constructor(sourceTable, referencedTable, relationName) {
|
||||
this.sourceTable = sourceTable;
|
||||
this.referencedTable = referencedTable;
|
||||
this.relationName = relationName;
|
||||
this.referencedTableName = referencedTable[Table.Symbol.Name];
|
||||
}
|
||||
static [entityKind] = "Relation";
|
||||
referencedTableName;
|
||||
fieldName;
|
||||
}
|
||||
class Relations {
|
||||
constructor(table, config) {
|
||||
this.table = table;
|
||||
this.config = config;
|
||||
}
|
||||
static [entityKind] = "Relations";
|
||||
}
|
||||
class One extends Relation {
|
||||
constructor(sourceTable, referencedTable, config, isNullable) {
|
||||
super(sourceTable, referencedTable, config?.relationName);
|
||||
this.config = config;
|
||||
this.isNullable = isNullable;
|
||||
}
|
||||
static [entityKind] = "One";
|
||||
withFieldName(fieldName) {
|
||||
const relation = new One(
|
||||
this.sourceTable,
|
||||
this.referencedTable,
|
||||
this.config,
|
||||
this.isNullable
|
||||
);
|
||||
relation.fieldName = fieldName;
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
class Many extends Relation {
|
||||
constructor(sourceTable, referencedTable, config) {
|
||||
super(sourceTable, referencedTable, config?.relationName);
|
||||
this.config = config;
|
||||
}
|
||||
static [entityKind] = "Many";
|
||||
withFieldName(fieldName) {
|
||||
const relation = new Many(
|
||||
this.sourceTable,
|
||||
this.referencedTable,
|
||||
this.config
|
||||
);
|
||||
relation.fieldName = fieldName;
|
||||
return relation;
|
||||
}
|
||||
}
|
||||
function getOperators() {
|
||||
return {
|
||||
and,
|
||||
between,
|
||||
eq,
|
||||
exists,
|
||||
gt,
|
||||
gte,
|
||||
ilike,
|
||||
inArray,
|
||||
isNull,
|
||||
isNotNull,
|
||||
like,
|
||||
lt,
|
||||
lte,
|
||||
ne,
|
||||
not,
|
||||
notBetween,
|
||||
notExists,
|
||||
notLike,
|
||||
notIlike,
|
||||
notInArray,
|
||||
or,
|
||||
sql
|
||||
};
|
||||
}
|
||||
function getOrderByOperators() {
|
||||
return {
|
||||
sql,
|
||||
asc,
|
||||
desc
|
||||
};
|
||||
}
|
||||
function extractTablesRelationalConfig(schema, configHelpers) {
|
||||
if (Object.keys(schema).length === 1 && "default" in schema && !is(schema["default"], Table)) {
|
||||
schema = schema["default"];
|
||||
}
|
||||
const tableNamesMap = {};
|
||||
const relationsBuffer = {};
|
||||
const tablesConfig = {};
|
||||
for (const [key, value] of Object.entries(schema)) {
|
||||
if (is(value, Table)) {
|
||||
const dbName = getTableUniqueName(value);
|
||||
const bufferedRelations = relationsBuffer[dbName];
|
||||
tableNamesMap[dbName] = key;
|
||||
tablesConfig[key] = {
|
||||
tsName: key,
|
||||
dbName: value[Table.Symbol.Name],
|
||||
schema: value[Table.Symbol.Schema],
|
||||
columns: value[Table.Symbol.Columns],
|
||||
relations: bufferedRelations?.relations ?? {},
|
||||
primaryKey: bufferedRelations?.primaryKey ?? []
|
||||
};
|
||||
for (const column of Object.values(
|
||||
value[Table.Symbol.Columns]
|
||||
)) {
|
||||
if (column.primary) {
|
||||
tablesConfig[key].primaryKey.push(column);
|
||||
}
|
||||
}
|
||||
const extraConfig = value[Table.Symbol.ExtraConfigBuilder]?.(value[Table.Symbol.ExtraConfigColumns]);
|
||||
if (extraConfig) {
|
||||
for (const configEntry of Object.values(extraConfig)) {
|
||||
if (is(configEntry, PrimaryKeyBuilder)) {
|
||||
tablesConfig[key].primaryKey.push(...configEntry.columns);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (is(value, Relations)) {
|
||||
const dbName = getTableUniqueName(value.table);
|
||||
const tableName = tableNamesMap[dbName];
|
||||
const relations2 = value.config(
|
||||
configHelpers(value.table)
|
||||
);
|
||||
let primaryKey;
|
||||
for (const [relationName, relation] of Object.entries(relations2)) {
|
||||
if (tableName) {
|
||||
const tableConfig = tablesConfig[tableName];
|
||||
tableConfig.relations[relationName] = relation;
|
||||
if (primaryKey) {
|
||||
tableConfig.primaryKey.push(...primaryKey);
|
||||
}
|
||||
} else {
|
||||
if (!(dbName in relationsBuffer)) {
|
||||
relationsBuffer[dbName] = {
|
||||
relations: {},
|
||||
primaryKey
|
||||
};
|
||||
}
|
||||
relationsBuffer[dbName].relations[relationName] = relation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { tables: tablesConfig, tableNamesMap };
|
||||
}
|
||||
function relations(table, relations2) {
|
||||
return new Relations(
|
||||
table,
|
||||
(helpers) => Object.fromEntries(
|
||||
Object.entries(relations2(helpers)).map(([key, value]) => [
|
||||
key,
|
||||
value.withFieldName(key)
|
||||
])
|
||||
)
|
||||
);
|
||||
}
|
||||
function createOne(sourceTable) {
|
||||
return function one(table, config) {
|
||||
return new One(
|
||||
sourceTable,
|
||||
table,
|
||||
config,
|
||||
config?.fields.reduce((res, f) => res && f.notNull, true) ?? false
|
||||
);
|
||||
};
|
||||
}
|
||||
function createMany(sourceTable) {
|
||||
return function many(referencedTable, config) {
|
||||
return new Many(sourceTable, referencedTable, config);
|
||||
};
|
||||
}
|
||||
function normalizeRelation(schema, tableNamesMap, relation) {
|
||||
if (is(relation, One) && relation.config) {
|
||||
return {
|
||||
fields: relation.config.fields,
|
||||
references: relation.config.references
|
||||
};
|
||||
}
|
||||
const referencedTableTsName = tableNamesMap[getTableUniqueName(relation.referencedTable)];
|
||||
if (!referencedTableTsName) {
|
||||
throw new Error(
|
||||
`Table "${relation.referencedTable[Table.Symbol.Name]}" not found in schema`
|
||||
);
|
||||
}
|
||||
const referencedTableConfig = schema[referencedTableTsName];
|
||||
if (!referencedTableConfig) {
|
||||
throw new Error(`Table "${referencedTableTsName}" not found in schema`);
|
||||
}
|
||||
const sourceTable = relation.sourceTable;
|
||||
const sourceTableTsName = tableNamesMap[getTableUniqueName(sourceTable)];
|
||||
if (!sourceTableTsName) {
|
||||
throw new Error(
|
||||
`Table "${sourceTable[Table.Symbol.Name]}" not found in schema`
|
||||
);
|
||||
}
|
||||
const reverseRelations = [];
|
||||
for (const referencedTableRelation of Object.values(
|
||||
referencedTableConfig.relations
|
||||
)) {
|
||||
if (relation.relationName && relation !== referencedTableRelation && referencedTableRelation.relationName === relation.relationName || !relation.relationName && referencedTableRelation.referencedTable === relation.sourceTable) {
|
||||
reverseRelations.push(referencedTableRelation);
|
||||
}
|
||||
}
|
||||
if (reverseRelations.length > 1) {
|
||||
throw relation.relationName ? new Error(
|
||||
`There are multiple relations with name "${relation.relationName}" in table "${referencedTableTsName}"`
|
||||
) : new Error(
|
||||
`There are multiple relations between "${referencedTableTsName}" and "${relation.sourceTable[Table.Symbol.Name]}". Please specify relation name`
|
||||
);
|
||||
}
|
||||
if (reverseRelations[0] && is(reverseRelations[0], One) && reverseRelations[0].config) {
|
||||
return {
|
||||
fields: reverseRelations[0].config.references,
|
||||
references: reverseRelations[0].config.fields
|
||||
};
|
||||
}
|
||||
throw new Error(
|
||||
`There is not enough information to infer relation "${sourceTableTsName}.${relation.fieldName}"`
|
||||
);
|
||||
}
|
||||
function createTableRelationsHelpers(sourceTable) {
|
||||
return {
|
||||
one: createOne(sourceTable),
|
||||
many: createMany(sourceTable)
|
||||
};
|
||||
}
|
||||
function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelection, mapColumnValue = (value) => value) {
|
||||
const result = {};
|
||||
for (const [
|
||||
selectionItemIndex,
|
||||
selectionItem
|
||||
] of buildQueryResultSelection.entries()) {
|
||||
if (selectionItem.isJson) {
|
||||
const relation = tableConfig.relations[selectionItem.tsKey];
|
||||
const rawSubRows = row[selectionItemIndex];
|
||||
const subRows = typeof rawSubRows === "string" ? JSON.parse(rawSubRows) : rawSubRows;
|
||||
result[selectionItem.tsKey] = is(relation, One) ? subRows && mapRelationalRow(
|
||||
tablesConfig,
|
||||
tablesConfig[selectionItem.relationTableTsKey],
|
||||
subRows,
|
||||
selectionItem.selection,
|
||||
mapColumnValue
|
||||
) : subRows.map(
|
||||
(subRow) => mapRelationalRow(
|
||||
tablesConfig,
|
||||
tablesConfig[selectionItem.relationTableTsKey],
|
||||
subRow,
|
||||
selectionItem.selection,
|
||||
mapColumnValue
|
||||
)
|
||||
);
|
||||
} else {
|
||||
const value = mapColumnValue(row[selectionItemIndex]);
|
||||
const field = selectionItem.field;
|
||||
let decoder;
|
||||
if (is(field, Column)) {
|
||||
decoder = field;
|
||||
} else if (is(field, SQL)) {
|
||||
decoder = field.decoder;
|
||||
} else {
|
||||
decoder = field.sql.decoder;
|
||||
}
|
||||
result[selectionItem.tsKey] = value === null ? null : decoder.mapFromDriverValue(value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
export {
|
||||
Many,
|
||||
One,
|
||||
Relation,
|
||||
Relations,
|
||||
createMany,
|
||||
createOne,
|
||||
createTableRelationsHelpers,
|
||||
extractTablesRelationalConfig,
|
||||
getOperators,
|
||||
getOrderByOperators,
|
||||
mapRelationalRow,
|
||||
normalizeRelation,
|
||||
relations
|
||||
};
|
||||
//# sourceMappingURL=relations.js.map
|
||||
Reference in New Issue
Block a user