Comparing version 1.0.57 to 1.0.58
@@ -217,1 +217,35 @@ "use strict"; | ||
exports.array_equals = array_equals; | ||
// from: https://stackoverflow.com/a/69424269 | ||
/** | ||
* Tests whether two values are deeply equal using same-value equality. | ||
* | ||
* Two values are considered deeply equal iff 1) they are the same value, or | ||
* 2) they are both non-callable objects whose own, enumerable, string-keyed | ||
* properties are deeply equal. | ||
* | ||
* Caution: This function does not fully support circular references. Use this | ||
* function only if you are sure that at least one of the arguments has no | ||
* circular references. | ||
*/ | ||
function deep_equal(x, y) { | ||
// check primitive values | ||
if (typeof x !== 'object' || | ||
x === null || | ||
typeof y !== 'object' || | ||
y === null) { | ||
return Object.is(x, y); | ||
} | ||
if (x === y) { | ||
return true; | ||
} | ||
const keys = Object.keys(x); | ||
if (Object.keys(y).length !== keys.length) | ||
return false; | ||
for (const key of keys) { | ||
if (!Object.prototype.propertyIsEnumerable.call(y, key) || | ||
!deep_equal(x[key], y[key])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} |
@@ -23,14 +23,19 @@ "use strict"; | ||
const left_list = (0, extract_subpaths_1.extract_subpaths)((0, helpers_1.drop_last)(1, path), result); | ||
const { left, inner, right } = (0, lir_join_1.lir_join)(left_list, result, list, el => (0, helpers_1.deep_get)([...el, edges[i][0]], result), (l, i, r) => { | ||
r.forEach(right_adjacent => { | ||
l.forEach(left_adjacent => { | ||
const { left, inner, right } = (0, lir_join_1.lir_join)(left_list, result, list, el => (0, helpers_1.deep_get)([...el, edges[i][0]], result), (l, acc, r) => { | ||
r.forEach((right_adjacent, r_index) => { | ||
l.forEach((left_adjacent, l_index) => { | ||
// When the same item appears in multiple spots | ||
// we want to make a copy of it | ||
const item_to_nest = l_index === 0 | ||
? right_adjacent | ||
: (0, helpers_1.clone)(right_adjacent); | ||
if (array_mode) { | ||
(0, push_path_1.push_path)([...left_adjacent, (0, helpers_1.last)(path)], right_adjacent, i); | ||
(0, push_path_1.push_path)([...left_adjacent, (0, helpers_1.last)(path)], item_to_nest, acc); | ||
} | ||
else { | ||
(0, helpers_1.deep_set)([...left_adjacent, (0, helpers_1.last)(path)], right_adjacent, i); | ||
(0, helpers_1.deep_set)([...left_adjacent, (0, helpers_1.last)(path)], item_to_nest, acc); | ||
} | ||
}); | ||
}); | ||
return i; | ||
return acc; | ||
}, el => el[edges[i][1]]); | ||
@@ -37,0 +42,0 @@ } |
@@ -21,2 +21,7 @@ /** | ||
/** | ||
* @returns given an entity, returns true if the entity is in the schema | ||
*/ | ||
export declare const is_entity_name: (entity_name: any, orma_schema: any) => boolean; | ||
export declare const is_field_name: (entity_name: any, field_name: any, orma_schema: any) => boolean; | ||
/** | ||
* Gets a list of edges from given entity -> parent entity | ||
@@ -74,1 +79,6 @@ */ | ||
export declare const field_exists: (entity: string, field: string | number, schema: orma_schema) => string | orma_field_schema | import("../introspector/introspector").orma_index_schema[]; | ||
/** | ||
* Returns true if a field is required to be initially provided by the user. Any field with a default is not required, | ||
* which includes nullable fields which default to null. | ||
*/ | ||
export declare const is_required_field: (entity: string, field: string, schema: orma_schema) => boolean; |
@@ -7,3 +7,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.field_exists = exports.get_unique_field_groups = exports.get_primary_keys = exports.is_parent_entity = exports.get_edge_path = exports.get_direct_edge = exports.get_direct_edges = exports.is_reserved_keyword = exports.get_all_edges = exports.get_child_edges = exports.reverse_edge = exports.get_parent_edges = exports.get_field_names = exports.get_entity_names = void 0; | ||
exports.is_required_field = exports.field_exists = exports.get_unique_field_groups = exports.get_primary_keys = exports.is_parent_entity = exports.get_edge_path = exports.get_direct_edge = exports.get_direct_edges = exports.is_reserved_keyword = exports.get_all_edges = exports.get_child_edges = exports.reverse_edge = exports.get_parent_edges = exports.is_field_name = exports.is_entity_name = exports.get_field_names = exports.get_entity_names = void 0; | ||
/** | ||
@@ -13,3 +13,3 @@ * @returns a list of entities specified in the schema | ||
const get_entity_names = (orma_schema) => { | ||
return Object.keys(orma_schema); | ||
return Object.keys(orma_schema).filter(el => !(0, exports.is_reserved_keyword)(el)); | ||
}; | ||
@@ -22,11 +22,13 @@ exports.get_entity_names = get_entity_names; | ||
var _a; | ||
return Object.keys((_a = orma_schema[entity_name]) !== null && _a !== void 0 ? _a : {}); | ||
return Object.keys((_a = orma_schema[entity_name]) !== null && _a !== void 0 ? _a : {}).filter(el => !(0, exports.is_reserved_keyword)(el)); | ||
}; | ||
exports.get_field_names = get_field_names; | ||
// /** | ||
// * @returns given an entity, returns true if the entity is in the schema | ||
// */ | ||
// export const is_entity_name = (entity_name, orma_schema) => !!orma_schema.entities?.[entity_name] | ||
// export const is_field_name = (entity_name, field_name, orma_schema) => !!orma_schema.entities?.[entity_name]?.fields?.[field_name] | ||
/** | ||
* @returns given an entity, returns true if the entity is in the schema | ||
*/ | ||
const is_entity_name = (entity_name, orma_schema) => !!(orma_schema === null || orma_schema === void 0 ? void 0 : orma_schema[entity_name]); | ||
exports.is_entity_name = is_entity_name; | ||
const is_field_name = (entity_name, field_name, orma_schema) => { var _a; return !!((_a = orma_schema === null || orma_schema === void 0 ? void 0 : orma_schema[entity_name]) === null || _a === void 0 ? void 0 : _a[field_name]); }; | ||
exports.is_field_name = is_field_name; | ||
/** | ||
* Gets a list of edges from given entity -> parent entity | ||
@@ -198,4 +200,4 @@ */ | ||
const get_unique_field_groups = (entity_name, exclude_nullable, orma_schema) => { | ||
var _a; | ||
const indexes = (_a = orma_schema[entity_name].$indexes) !== null && _a !== void 0 ? _a : []; | ||
var _a, _b; | ||
const indexes = (_b = (_a = orma_schema[entity_name]) === null || _a === void 0 ? void 0 : _a.$indexes) !== null && _b !== void 0 ? _b : []; | ||
const unique_field_groups = indexes | ||
@@ -207,3 +209,3 @@ .filter(index => index.is_unique) | ||
const field_schema = orma_schema[entity_name][field]; | ||
return field_schema.required; | ||
return field_schema.not_null; | ||
}); | ||
@@ -225,1 +227,12 @@ return all_fields_non_nullable; | ||
exports.field_exists = field_exists; | ||
/** | ||
* Returns true if a field is required to be initially provided by the user. Any field with a default is not required, | ||
* which includes nullable fields which default to null. | ||
*/ | ||
const is_required_field = (entity, field, schema) => { | ||
var _a; | ||
const field_schema = (_a = schema === null || schema === void 0 ? void 0 : schema[entity]) === null || _a === void 0 ? void 0 : _a[field]; | ||
const is_required = field_schema.not_null && !field_schema.default && !field_schema.auto_increment; | ||
return is_required; | ||
}; | ||
exports.is_required_field = is_required_field; |
@@ -9,26 +9,36 @@ "use strict"; | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }, { id: 2 }]], | ||
[ | ||
['vendors', 0], | ||
[{ id: 1 }, { id: 2 }], | ||
], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 2 }]], | ||
[['vendors', 0, 'products', 0, 'images', 0], [{ product_id: 1 }, { product_id: 1 }]] | ||
[ | ||
['vendors', 0, 'products', 0, 'images', 0], | ||
[{ product_id: 1 }, { product_id: 1 }], | ||
], | ||
]; | ||
const edges = [ | ||
null, | ||
['id', 'vendor_id'], | ||
['id', 'product_id'] | ||
]; | ||
const edges = [null, ['id', 'vendor_id'], ['id', 'product_id']]; | ||
const goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
vendors: [ | ||
{ | ||
id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
products: [{ | ||
products: [ | ||
{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
images: [ | ||
{ | ||
product_id: 1, | ||
}, | ||
{ | ||
product_id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
@@ -42,23 +52,32 @@ let result = (0, nester_1.nester)(data, edges); | ||
[['images', 0], [{ id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
[ | ||
['vendors', 0, 'products', 0], | ||
[ | ||
{ id: 1, vendor_id: 1 }, | ||
{ id: 2, vendor_id: 1 }, | ||
], | ||
], | ||
]; | ||
const edges = [ | ||
null, | ||
null, | ||
['id', 'vendor_id'] | ||
]; | ||
const edges = [null, null, ['id', 'vendor_id']]; | ||
const goal = { | ||
images: [{ | ||
id: 1 | ||
}], | ||
vendors: [{ | ||
images: [ | ||
{ | ||
id: 1, | ||
products: [{ | ||
}, | ||
], | ||
vendors: [ | ||
{ | ||
id: 1, | ||
products: [ | ||
{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
vendor_id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
vendor_id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
@@ -72,32 +91,49 @@ let result = (0, nester_1.nester)(data, edges); | ||
[['images', 0], [{ id: 1 }]], | ||
[['images', 0, 'child_images', 0], [{ id: 1, image_id: 1 }, { id: 2, image_id: 1 }]], | ||
[['vendors', 0, 'products', 0], [{ id: 1, vendor_id: 1 }, { id: 2, vendor_id: 1 }]], | ||
[ | ||
['images', 0, 'child_images', 0], | ||
[ | ||
{ id: 1, image_id: 1 }, | ||
{ id: 2, image_id: 1 }, | ||
], | ||
], | ||
[ | ||
['vendors', 0, 'products', 0], | ||
[ | ||
{ id: 1, vendor_id: 1 }, | ||
{ id: 2, vendor_id: 1 }, | ||
], | ||
], | ||
]; | ||
const edges = [ | ||
null, | ||
null, | ||
['id', 'image_id'], | ||
['id', 'vendor_id'] | ||
]; | ||
const edges = [null, null, ['id', 'image_id'], ['id', 'vendor_id']]; | ||
const goal = { | ||
images: [{ | ||
images: [ | ||
{ | ||
id: 1, | ||
child_images: [{ | ||
child_images: [ | ||
{ | ||
id: 1, | ||
image_id: 1 | ||
}, { | ||
image_id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
image_id: 1 | ||
}] | ||
}], | ||
vendors: [{ | ||
image_id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
vendors: [ | ||
{ | ||
id: 1, | ||
products: [{ | ||
products: [ | ||
{ | ||
id: 1, | ||
vendor_id: 1 | ||
}, { | ||
vendor_id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
vendor_id: 1 | ||
}] | ||
}] | ||
vendor_id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
@@ -109,19 +145,22 @@ let result = (0, nester_1.nester)(data, edges); | ||
const data = [ | ||
[['vendors', 0], [{ id: 1 }, { id: 2 }]], | ||
[ | ||
['vendors', 0], | ||
[{ id: 1 }, { id: 2 }], | ||
], | ||
[['vendors', 0, 'products'], [{ id: 1, vendor_id: 2 }]], | ||
]; | ||
const edges = [ | ||
null, | ||
['id', 'vendor_id'] | ||
]; | ||
const edges = [null, ['id', 'vendor_id']]; | ||
const goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
vendors: [ | ||
{ | ||
id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
products: { | ||
id: 1, | ||
vendor_id: 2 | ||
} | ||
}] | ||
vendor_id: 2, | ||
}, | ||
}, | ||
], | ||
}; | ||
@@ -133,23 +172,33 @@ let result = (0, nester_1.nester)(data, edges); | ||
const data = [ | ||
[['variants', 0], [{ id: 10, product_id: 1 }, { id: 11, product_id: 1 }]], | ||
[ | ||
['variants', 0], | ||
[ | ||
{ id: 10, product_id: 1 }, | ||
{ id: 11, product_id: 1 }, | ||
], | ||
], | ||
[['variants', 0, 'products', 0], [{ id: 1 }]], | ||
]; | ||
const edges = [ | ||
null, | ||
['product_id', 'id'] | ||
]; | ||
const edges = [null, ['product_id', 'id']]; | ||
const goal = { | ||
variants: [{ | ||
variants: [ | ||
{ | ||
id: 10, | ||
product_id: 1, | ||
products: [{ | ||
id: 1 | ||
}] | ||
}, { | ||
products: [ | ||
{ | ||
id: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
id: 11, | ||
product_id: 1, | ||
products: [{ | ||
id: 1 | ||
}] | ||
}] | ||
products: [ | ||
{ | ||
id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
@@ -161,3 +210,3 @@ let result = (0, nester_1.nester)(data, edges); | ||
const vendors = new Array(100).fill(undefined).map((_, i) => ({ | ||
id: Math.random() * 1000000000000000 | ||
id: Math.random() * 1000000000000000, | ||
})); | ||
@@ -167,3 +216,3 @@ const products = vendors.flatMap((vendor, i) => { | ||
id: Math.random() * 1000000000000000, | ||
vendor_id: vendor.id | ||
vendor_id: vendor.id, | ||
})); | ||
@@ -175,3 +224,3 @@ }); | ||
id: Math.random() * 1000000000000000, | ||
product_id: product.id | ||
product_id: product.id, | ||
})); | ||
@@ -182,23 +231,41 @@ }); | ||
[['vendors', 0, 'products'], products], | ||
[['vendors', 0, 'products', 0, 'images'], images] | ||
[['vendors', 0, 'products', 0, 'images'], images], | ||
]; | ||
const edges = [ | ||
{ from_entity: 'vendors', from_field: 'id', to_entity: 'products', to_field: 'vendor_id' }, | ||
{ from_entity: 'products', from_field: 'id', to_entity: 'images', to_field: 'product_id' }, | ||
{ | ||
from_entity: 'vendors', | ||
from_field: 'id', | ||
to_entity: 'products', | ||
to_field: 'vendor_id', | ||
}, | ||
{ | ||
from_entity: 'products', | ||
from_field: 'id', | ||
to_entity: 'images', | ||
to_field: 'product_id', | ||
}, | ||
]; | ||
const goal = { | ||
vendors: [{ | ||
id: 1 | ||
}, { | ||
vendors: [ | ||
{ | ||
id: 1, | ||
}, | ||
{ | ||
id: 2, | ||
products: [{ | ||
products: [ | ||
{ | ||
id: 1, | ||
vendor_id: 2, | ||
images: [{ | ||
product_id: 1 | ||
}, { | ||
product_id: 1 | ||
}] | ||
}] | ||
}] | ||
images: [ | ||
{ | ||
product_id: 1, | ||
}, | ||
{ | ||
product_id: 1, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
@@ -214,2 +281,22 @@ console.time('t'); | ||
}); | ||
(0, mocha_1.test)('Nest same item into multiple spots should make a copy', () => { | ||
// This is a test for a bug that was found in the code. | ||
// The bug was that the same item was being added to multiple places | ||
// and the user expects data to be copied to each spot. | ||
const data = [ | ||
[ | ||
['order_items', 0], | ||
[ | ||
{ id: 1, variant_id: 11 }, | ||
{ id: 2, variant_id: 11 }, | ||
], | ||
], | ||
[['order_items', 0, 'variants', 0], [{ product_id: 111, id: 11 }]], | ||
[['order_items', 0, 'variants', 0, 'products', 0], [{ id: 111 }]], | ||
]; | ||
const edges = [null, ['variant_id', 'id'], ['product_id', 'id']]; | ||
const result = (0, nester_1.nester)(data, edges); | ||
const len = result.order_items[0].variants[0].products.length; | ||
(0, chai_1.expect)(len).to.equal(1); | ||
}); | ||
}); |
export declare const orma_introspect: (db: string, fn: (s: string[]) => Promise<Record<string, unknown>[][]>) => Promise<import("./introspector/introspector").orma_schema>; | ||
export declare const orma_query: <Schema extends import("./types/schema_types").DeepReadonlyObject<import("./introspector/introspector").orma_schema>, Query extends import("./types/query/query_types").OrmaQuery<Schema>>(raw_query: Query, orma_schema_input: Schema, query_function: (sql_string: string[]) => Promise<Record<string, unknown>[][]>, escaping_function: (value: any) => any) => Promise<import("./types/query/query_result_types").StripKeywords<import("./types/query/query_result_types").WrapInArrays<import("./types/query/query_result_types").AddSchemaTypes<Schema, Query, unknown>>>>; | ||
export declare const orma_mutate: (input_mutation: any, mysql_function: import("./mutate/mutate").mysql_fn, escape_fn: import("./mutate/mutate").escape_fn, orma_schema: import("./introspector/introspector").orma_schema) => Promise<any>; | ||
export declare const orma_query: <Schema extends import("./types/schema_types").DeepReadonlyObject<import("./introspector/introspector").orma_schema>, Query extends import("./types/query/query_types").OrmaQuery<Schema>>(raw_query: Query, orma_schema_input: Schema, query_function: (sql_string: string[]) => Promise<Record<string, unknown>[][]>, escaping_function: (value: any) => any, validation_function: (query: any) => any[]) => Promise<(import("./types/query/query_result_types").StripKeywords<import("./types/query/query_result_types").WrapInArrays<import("./types/query/query_result_types").AddSchemaTypes<Schema, Query, unknown>>> & { | ||
$success: true; | ||
}) | { | ||
$success: false; | ||
errors: import("./helpers/error_handling").error_type[]; | ||
}>; | ||
export declare const orma_mutate: (input_mutation: any, mysql_function: import("./mutate/mutate").mysql_fn, orma_schema: import("./introspector/introspector").orma_schema) => Promise<any>; |
@@ -49,18 +49,20 @@ /** | ||
export interface orma_schema { | ||
[entity_name: string]: { | ||
$comment?: string; | ||
$indexes?: orma_index_schema[]; | ||
[field_name: string]: orma_field_schema | orma_index_schema[] | string; | ||
}; | ||
[entity_name: string]: orma_entity_schema; | ||
} | ||
export interface orma_entity_schema { | ||
$comment?: string; | ||
$indexes?: orma_index_schema[]; | ||
[field_name: string]: orma_field_schema | orma_index_schema[] | string; | ||
} | ||
export interface orma_field_schema { | ||
data_type?: typeof mysql_to_simple_types[keyof typeof mysql_to_simple_types]; | ||
data_type?: keyof typeof mysql_to_typescript_types; | ||
character_count?: number; | ||
ordinal_position?: number; | ||
required?: boolean; | ||
decimal_places?: number; | ||
not_null?: boolean; | ||
primary_key?: boolean; | ||
indexed?: boolean; | ||
character_count?: number; | ||
decimal_places?: number; | ||
default?: string | number; | ||
comment?: string; | ||
auto_increment?: boolean; | ||
references?: { | ||
@@ -73,7 +75,7 @@ [referenced_entity: string]: { | ||
export interface orma_index_schema { | ||
index_name: string; | ||
is_unique: boolean; | ||
index_name?: string; | ||
is_unique?: boolean; | ||
fields: string[]; | ||
index_type?: string; | ||
is_visible?: boolean; | ||
invisible?: boolean; | ||
collation?: 'A' | 'D'; | ||
@@ -116,3 +118,3 @@ sub_part?: number | null; | ||
export declare const generate_database_schema: (mysql_tables: mysql_table[], mysql_columns: mysql_column[], mysql_foreign_keys: mysql_foreign_key[], mysql_indexes: mysql_index[]) => orma_schema; | ||
export declare const mysql_to_simple_types: { | ||
export declare const mysql_to_typescript_types: { | ||
readonly bigint: "number"; | ||
@@ -119,0 +121,0 @@ readonly binary: "string"; |
@@ -7,3 +7,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.orma_introspect = exports.generate_index_schemas = exports.generate_field_schema = exports.as_orma_schema = exports.mysql_to_simple_types = exports.generate_database_schema = exports.get_introspect_sqls = void 0; | ||
exports.orma_introspect = exports.generate_index_schemas = exports.generate_field_schema = exports.as_orma_schema = exports.mysql_to_typescript_types = exports.generate_database_schema = exports.get_introspect_sqls = void 0; | ||
const helpers_1 = require("../helpers/helpers"); | ||
@@ -92,3 +92,3 @@ /** | ||
database_schema[mysql_table.table_name] = { | ||
$comment: mysql_table.table_comment | ||
$comment: mysql_table.table_comment, | ||
}; | ||
@@ -98,6 +98,7 @@ } | ||
const field_schema = (0, exports.generate_field_schema)(mysql_column); | ||
database_schema[mysql_column.table_name][mysql_column.column_name] = field_schema; | ||
database_schema[mysql_column.table_name][mysql_column.column_name] = | ||
field_schema; | ||
} | ||
for (const mysql_foreign_key of mysql_foreign_keys) { | ||
const { table_name, column_name, referenced_table_name, referenced_column_name, constraint_name } = mysql_foreign_key; | ||
const { table_name, column_name, referenced_table_name, referenced_column_name, constraint_name, } = mysql_foreign_key; | ||
const reference_path = [ | ||
@@ -108,3 +109,3 @@ table_name, | ||
referenced_table_name, | ||
referenced_column_name | ||
referenced_column_name, | ||
]; | ||
@@ -120,3 +121,3 @@ (0, helpers_1.deep_set)(reference_path, {}, database_schema); | ||
exports.generate_database_schema = generate_database_schema; | ||
exports.mysql_to_simple_types = { | ||
exports.mysql_to_typescript_types = { | ||
bigint: 'number', | ||
@@ -150,3 +151,3 @@ binary: 'string', | ||
varbinary: 'string', | ||
varchar: 'string' | ||
varchar: 'string', | ||
}; | ||
@@ -156,10 +157,10 @@ const as_orma_schema = (schema) => schema; | ||
const generate_field_schema = (mysql_column) => { | ||
const { table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_scale, datetime_precision, column_key, extra, generation_expression, column_comment } = mysql_column; | ||
const { table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_scale, datetime_precision, column_key, extra, generation_expression, column_comment, } = mysql_column; | ||
const field_schema = { | ||
data_type: exports.mysql_to_simple_types[data_type], | ||
ordinal_position | ||
data_type: data_type.toLowerCase(), | ||
ordinal_position, | ||
}; | ||
// indices | ||
if (is_nullable === 'NO') { | ||
field_schema.required = true; | ||
field_schema.not_null = true; | ||
} | ||
@@ -190,3 +191,3 @@ if (column_key === 'PRI' || column_key === 'UNI' || column_key === 'MUL') { | ||
if (extra === 'auto_increment') { | ||
field_schema.default = extra; | ||
field_schema.auto_increment = true; | ||
} | ||
@@ -223,3 +224,3 @@ // comment | ||
const orma_index_schema = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ index_name, is_unique: Number(non_unique) === 0 ? true : false, fields, | ||
index_type, is_visible: is_visible === 'YES' }, collation && { collation }), sub_part && { sub_part }), packed && { packed }), comment && { extra: comment }), expression && { expression }), index_comment && { index_comment }); | ||
index_type, invisible: is_visible === 'NO' }, (collation && { collation })), (sub_part && { sub_part })), (packed && { packed })), (comment && { extra: comment })), (expression && { expression })), (index_comment && { index_comment })); | ||
return orma_index_schema; | ||
@@ -226,0 +227,0 @@ }; |
@@ -18,3 +18,3 @@ "use strict"; | ||
ordinal_position: 1, | ||
is_nullable: 'NO', | ||
is_nullable: 'YES', | ||
data_type: 'int', | ||
@@ -26,8 +26,7 @@ column_key: 'PRI', | ||
(0, chai_1.expect)(field_schema).to.deep.equal({ | ||
data_type: 'number', | ||
default: 'auto_increment', | ||
data_type: 'int', | ||
auto_increment: true, | ||
indexed: true, | ||
ordinal_position: 1, | ||
primary_key: true, | ||
required: true, | ||
}); | ||
@@ -46,6 +45,6 @@ }); | ||
(0, chai_1.expect)(field_schema).to.deep.equal({ | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
not_null: true, | ||
indexed: true, | ||
ordinal_position: 2, | ||
required: true, | ||
}); | ||
@@ -65,3 +64,3 @@ }); | ||
(0, chai_1.expect)(field_schema).to.deep.equal({ | ||
data_type: 'number', | ||
data_type: 'decimal', | ||
ordinal_position: 3, | ||
@@ -131,3 +130,3 @@ character_count: 4, | ||
user_id: { | ||
data_type: 'number', | ||
data_type: 'int', | ||
ordinal_position: 1, | ||
@@ -144,3 +143,3 @@ references: { | ||
id: { | ||
data_type: 'number', | ||
data_type: 'int', | ||
ordinal_position: 1, | ||
@@ -153,3 +152,3 @@ }, | ||
index_type: 'BTREE', | ||
is_visible: true, | ||
invisible: false, | ||
collation: 'A', | ||
@@ -241,3 +240,3 @@ sub_part: 1, | ||
index_type: 'BTREE', | ||
is_visible: true, | ||
invisible: false, | ||
collation: 'A', | ||
@@ -252,3 +251,3 @@ sub_part: 1, | ||
index_type: 'BTREE', | ||
is_visible: true, | ||
invisible: false, | ||
collation: 'A', | ||
@@ -263,3 +262,3 @@ }, | ||
index_type: 'BTREE', | ||
is_visible: false, | ||
invisible: true, | ||
collation: 'A', | ||
@@ -266,0 +265,0 @@ }, |
import { orma_schema } from '../../introspector/introspector'; | ||
export declare const get_update_asts: (entity_name: string, paths: (string | number)[][], mutation: any, orma_schema: orma_schema, escape_fn: any) => { | ||
export declare const get_update_asts: (entity_name: string, paths: (string | number)[][], mutation: any, orma_schema: orma_schema) => { | ||
$update: string; | ||
$set: any[][]; | ||
$set: (string | number)[][]; | ||
$where: { | ||
$eq: any[]; | ||
$eq: (string | number)[]; | ||
} | { | ||
$and: { | ||
$eq: any[]; | ||
$eq: (string | number)[]; | ||
}[]; | ||
}; | ||
}[]; | ||
export declare const get_delete_ast: (entity_name: string, paths: (string | number)[][], mutation: any, orma_schema: orma_schema, escape_fn: any) => any[] | { | ||
export declare const get_delete_ast: (entity_name: string, paths: (string | number)[][], mutation: any, orma_schema: orma_schema) => any[] | { | ||
$delete_from: string; | ||
$where: Record<string, any>; | ||
}; | ||
export declare const get_create_ast: (entity_name: string, paths: (string | number)[][], mutation: any, tier_results: any, orma_schema: orma_schema, escape_fn: any) => any[] | { | ||
export declare const get_create_ast: (entity_name: string, paths: (string | number)[][], mutation: any, tier_results: any, orma_schema: orma_schema) => any[] | { | ||
$insert_into: (string | string[])[]; | ||
$values: any[][]; | ||
$values: (string | number)[][]; | ||
}; | ||
export declare const throw_identifying_key_errors: (operation: string, identifying_keys: string[], path: (string | number)[], mutation: any) => void; | ||
/** | ||
* Gets all the foreign key edges for a specific location in a mutation. Returned edges will be all edges from | ||
* the given location to a connected location in the mutation that are from child -> parent. | ||
*/ | ||
export declare const get_foreign_keys_in_mutation: (mutation: any, record_path: (string | number)[], orma_schema: orma_schema) => { | ||
parent_path: any[]; | ||
edge: import("../../helpers/schema_helpers").Edge; | ||
}[]; | ||
/** | ||
* Gets an object containing all the foreign keys of the record at the given location. | ||
@@ -24,0 +32,0 @@ * Foreign keys are taken from the results_by_path object |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.get_foreign_keys_obj = exports.throw_identifying_key_errors = exports.get_create_ast = exports.get_delete_ast = exports.get_update_asts = void 0; | ||
exports.get_foreign_keys_obj = exports.get_foreign_keys_in_mutation = exports.throw_identifying_key_errors = exports.get_create_ast = exports.get_delete_ast = exports.get_update_asts = void 0; | ||
const escape_1 = require("../../helpers/escape"); | ||
const helpers_1 = require("../../helpers/helpers"); | ||
@@ -9,3 +10,3 @@ const schema_helpers_1 = require("../../helpers/schema_helpers"); | ||
const mutate_1 = require("../mutate"); | ||
const get_update_asts = (entity_name, paths, mutation, orma_schema, escape_fn) => { | ||
const get_update_asts = (entity_name, paths, mutation, orma_schema) => { | ||
if (paths.length === 0) { | ||
@@ -18,3 +19,3 @@ return []; | ||
(0, exports.throw_identifying_key_errors)('update', identifying_keys, path, mutation); | ||
const where = (0, mutate_1.generate_record_where_clause)(identifying_keys, record, escape_fn); | ||
const where = (0, mutate_1.generate_record_where_clause)(identifying_keys, record); | ||
const keys_to_set = Object.keys(record) | ||
@@ -27,3 +28,3 @@ .filter(key => !identifying_keys.includes(key)) | ||
$update: entity_name, | ||
$set: keys_to_set.map(key => [key, escape_fn(record[key])]), | ||
$set: keys_to_set.map(key => [key, (0, escape_1.orma_escape)(record[key])]), | ||
$where: where, | ||
@@ -35,24 +36,6 @@ }; | ||
exports.get_update_asts = get_update_asts; | ||
const get_delete_ast = (entity_name, paths, mutation, orma_schema, escape_fn) => { | ||
const get_delete_ast = (entity_name, paths, mutation, orma_schema) => { | ||
if (paths.length === 0) { | ||
return []; | ||
} | ||
// const jsons = paths.map(path => { | ||
// const record = deep_get(path, mutation) | ||
// const identifying_keys = get_identifying_keys( | ||
// entity_name, | ||
// record, | ||
// orma_schema | ||
// ) | ||
// throw_identifying_key_errors('delete', identifying_keys, path, mutation) | ||
// const where = generate_record_where_clause( | ||
// identifying_keys, | ||
// record, | ||
// escape_fn | ||
// ) | ||
// return { | ||
// $delete_from: entity_name, | ||
// $where: where, | ||
// } | ||
// }) | ||
const wheres = paths.map(path => { | ||
@@ -62,3 +45,3 @@ const record = (0, helpers_1.deep_get)(path, mutation); | ||
(0, exports.throw_identifying_key_errors)('delete', identifying_keys, path, mutation); | ||
const where = (0, mutate_1.generate_record_where_clause)(identifying_keys, record, escape_fn); | ||
const where = (0, mutate_1.generate_record_where_clause)(identifying_keys, record); | ||
return where; | ||
@@ -74,3 +57,3 @@ }); | ||
exports.get_delete_ast = get_delete_ast; | ||
const get_create_ast = (entity_name, paths, mutation, tier_results, orma_schema, escape_fn) => { | ||
const get_create_ast = (entity_name, paths, mutation, tier_results, orma_schema) => { | ||
if (paths.length === 0) { | ||
@@ -98,3 +81,3 @@ return []; | ||
const record_values = [...insert_keys].map(key => { var _a; return (_a = record[key]) !== null && _a !== void 0 ? _a : null; }); | ||
const escaped_record_values = record_values.map(value => escape_fn(value)); | ||
const escaped_record_values = record_values.map(value => (0, escape_1.orma_escape)(value)); | ||
return escaped_record_values; | ||
@@ -115,3 +98,3 @@ }); | ||
original_data: mutation, | ||
stack_trace: new Error().stack, | ||
// stack_trace: new Error().stack, | ||
additional_info: { | ||
@@ -125,6 +108,6 @@ identifying_columns: identifying_keys !== null && identifying_keys !== void 0 ? identifying_keys : 'none', | ||
/** | ||
* Gets an object containing all the foreign keys of the record at the given location. | ||
* Foreign keys are taken from the results_by_path object | ||
* Gets all the foreign key edges for a specific location in a mutation. Returned edges will be all edges from | ||
* the given location to a connected location in the mutation that are from child -> parent. | ||
*/ | ||
const get_foreign_keys_obj = (mutation, record_path, results_by_path, orma_schema) => { | ||
const get_foreign_keys_in_mutation = (mutation, record_path, orma_schema) => { | ||
const entity_name = (0, mutate_1.path_to_entity)(record_path); | ||
@@ -139,10 +122,7 @@ const record = (0, helpers_1.deep_get)(record_path, mutation); | ||
const all_paths = [above_path, ...below_paths]; | ||
// now we will get foreign keys for all the paths that are parent paths (ignoring child paths) and | ||
// put the foreign keys in an object of { [foreign_key_name]: foreign_key_value} | ||
// this object is in the right format to spread into the current record | ||
const foreign_keys = all_paths.reduce((obj, parent_path) => { | ||
const foreign_keys = all_paths.flatMap(parent_path => { | ||
const parent_entity_name = parent_path === null || parent_path === void 0 ? void 0 : parent_path[parent_path.length - 2]; | ||
// dont do anything for the child paths (foreign keys only come from parents by definition) | ||
if (!(0, schema_helpers_1.is_parent_entity)(parent_entity_name, entity_name, orma_schema)) { | ||
return obj; | ||
return []; | ||
} | ||
@@ -153,2 +133,22 @@ // assuming the thing is a parent, we need exactly one edge from the current entity to the parent | ||
const edge = (0, schema_helpers_1.get_direct_edge)(entity_name, parent_entity_name, orma_schema); | ||
return [ | ||
{ | ||
parent_path, | ||
edge, | ||
}, | ||
]; | ||
}); | ||
return foreign_keys; | ||
}; | ||
exports.get_foreign_keys_in_mutation = get_foreign_keys_in_mutation; | ||
/** | ||
* Gets an object containing all the foreign keys of the record at the given location. | ||
* Foreign keys are taken from the results_by_path object | ||
*/ | ||
const get_foreign_keys_obj = (mutation, record_path, results_by_path, orma_schema) => { | ||
const foreing_keys = (0, exports.get_foreign_keys_in_mutation)(mutation, record_path, orma_schema); | ||
// now we will get foreign keys for all the paths that are parent paths (ignoring child paths) and | ||
// put the foreign keys in an object of { [foreign_key_name]: foreign_key_value} | ||
// this object is in the right format to spread into the current record | ||
const foreign_key_obj = foreing_keys.reduce((obj, { parent_path, edge }) => { | ||
// we take the combined parent record as it is in the original mutation (this might have some of the foreign keys) | ||
@@ -159,11 +159,13 @@ // and also the same parent record from the previous results (e.g. autogenerated primiary keys from the database). | ||
const previous_result = results_by_path[(0, string_to_path_1.path_to_string)(parent_path)]; | ||
const parent_record_with_results = Object.assign(Object.assign({}, parent_record), previous_result); | ||
// now we just set the foreign key to whatever is in the combined parent object | ||
obj[edge.from_field] = parent_record_with_results[edge.to_field]; | ||
// set the foreign key from whatever data is present. Note that we dont use ?? since a null value in the | ||
// previous_result object should still be used, only if the prop is not present should we look in the | ||
// parent record of the mutation | ||
obj[edge.from_field] = | ||
previous_result[edge.to_field] === undefined | ||
? parent_record[edge.to_field] | ||
: previous_result[edge.to_field]; | ||
return obj; | ||
}, {}); | ||
// combining the record (from the original mutation) with the foreign keys (for that record) gives the full record | ||
const foreign_key_obj = Object.assign({}, foreign_keys); | ||
return foreign_key_obj; | ||
}; | ||
exports.get_foreign_keys_obj = get_foreign_keys_obj; |
@@ -6,3 +6,2 @@ "use strict"; | ||
const operation_macros_1 = require("./operation_macros"); | ||
const escape_fn = el => (typeof el === 'string' ? `\`${el}\`` : el); | ||
(0, mocha_1.describe)('operation_macros.ts', () => { | ||
@@ -13,2 +12,3 @@ const orma_schema = { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -20,9 +20,9 @@ quantity: {}, | ||
primary_key: true, | ||
required: true, | ||
not_null: true, | ||
}, | ||
unique1: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
unique2: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
@@ -58,5 +58,7 @@ quantity: {}, | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
id2: { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -74,2 +76,3 @@ parent_id: { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -97,3 +100,3 @@ parent_id: { | ||
}; | ||
const result = (0, operation_macros_1.get_update_asts)('grandparents', [['grandparents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('grandparents', [['grandparents', 0]], mutation, orma_schema); | ||
const goal = [ | ||
@@ -117,7 +120,7 @@ { | ||
}; | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema); | ||
const goal = [ | ||
{ | ||
$update: 'parents', | ||
$set: [['unique1', '`john`']], | ||
$set: [['unique1', "'john'"]], | ||
$where: { $eq: ['id', 1] }, | ||
@@ -137,3 +140,3 @@ }, | ||
}; | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema); | ||
const goal = [ | ||
@@ -143,3 +146,3 @@ { | ||
$set: [['quantity', 5]], | ||
$where: { $eq: ['unique1', '`john`'] }, | ||
$where: { $eq: ['unique1', "'john'"] }, | ||
}, | ||
@@ -158,3 +161,3 @@ ]; | ||
try { | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema); | ||
(0, chai_1.expect)('should have thrown an error').to.equal(true); | ||
@@ -177,3 +180,3 @@ } | ||
try { | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('parents', [['parents', 0]], mutation, orma_schema); | ||
(0, chai_1.expect)('should have thrown an error').to.equal(true); | ||
@@ -193,3 +196,3 @@ } | ||
}; | ||
const result = (0, operation_macros_1.get_update_asts)('children', [['children', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_update_asts)('children', [['children', 0]], mutation, orma_schema); | ||
const goal = [ | ||
@@ -225,3 +228,3 @@ { | ||
}; | ||
const result = (0, operation_macros_1.get_delete_ast)('parents', [['parents', 0]], mutation, orma_schema, escape_fn); | ||
const result = (0, operation_macros_1.get_delete_ast)('parents', [['parents', 0]], mutation, orma_schema); | ||
const goal = { | ||
@@ -228,0 +231,0 @@ $delete_from: 'parents', |
@@ -17,10 +17,5 @@ "use strict"; | ||
primary_key: true, | ||
required: true, | ||
}, | ||
unique1: { | ||
required: true, | ||
}, | ||
unique2: { | ||
required: true, | ||
}, | ||
unique1: {}, | ||
unique2: {}, | ||
quantity: {}, | ||
@@ -136,5 +131,17 @@ grandparent_id: { | ||
[ | ||
{ operation: 'delete', paths: [['parents', 0]], route: ['parents'] }, | ||
{ operation: 'update', paths: [['parents', 1]], route: ['parents'] }, | ||
{ operation: 'create', paths: [['parents', 2]], route: ['parents'] }, | ||
{ | ||
operation: 'delete', | ||
paths: [['parents', 0]], | ||
route: ['parents'], | ||
}, | ||
{ | ||
operation: 'update', | ||
paths: [['parents', 1]], | ||
route: ['parents'], | ||
}, | ||
{ | ||
operation: 'create', | ||
paths: [['parents', 2]], | ||
route: ['parents'], | ||
}, | ||
], | ||
@@ -141,0 +148,0 @@ ]; |
import { orma_schema } from '../introspector/introspector'; | ||
export declare type operation = 'create' | 'update' | 'delete' | 'query'; | ||
export declare type mysql_fn = (statements: any) => Promise<Record<string, any>[][]>; | ||
export declare type escape_fn = (string: any) => string; | ||
export declare type statements = { | ||
@@ -12,3 +11,3 @@ sql_ast: Record<any, any>; | ||
}[]; | ||
export declare const orma_mutate: (input_mutation: any, mysql_function: mysql_fn, escape_fn: escape_fn, orma_schema: orma_schema) => Promise<any>; | ||
export declare const orma_mutate: (input_mutation: any, mysql_function: mysql_fn, orma_schema: orma_schema) => Promise<any>; | ||
/** | ||
@@ -18,3 +17,3 @@ * Generates a query that selects the foreign keys and identifying fields, with where clauses per record based on the | ||
*/ | ||
export declare const generate_foreign_key_query: (mutation: any, entity_name: string, paths: (string | number)[][], orma_schema: orma_schema, escape_fn: any) => { | ||
export declare const generate_foreign_key_query: (mutation: any, entity_name: string, paths: (string | number)[][], orma_schema: orma_schema) => { | ||
$select: string[]; | ||
@@ -30,11 +29,11 @@ $from: string; | ||
*/ | ||
export declare const get_mutation_statements: (operation: string, entity_name: string, paths: (string | number)[][], mutation: any, tier_results: any, orma_schema: orma_schema, escape_fn: any) => { | ||
export declare const get_mutation_statements: (operation: string, entity_name: string, paths: (string | number)[][], mutation: any, tier_results: any, orma_schema: orma_schema) => { | ||
sql_ast: Record<any, any>; | ||
paths: (string | number)[][]; | ||
}[]; | ||
export declare const generate_record_where_clause: (identifying_keys: string[], record: Record<string, unknown>, escape_fn: any) => { | ||
$eq: any[]; | ||
export declare const generate_record_where_clause: (identifying_keys: string[], record: Record<string, unknown>) => { | ||
$eq: (string | number)[]; | ||
} | { | ||
$and: { | ||
$eq: any[]; | ||
$eq: (string | number)[]; | ||
}[]; | ||
@@ -41,0 +40,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.add_foreign_key_indexes = exports.get_identifying_keys = exports.path_to_entity = exports.generate_record_where_clause = exports.get_mutation_statements = exports.generate_foreign_key_query = exports.orma_mutate = void 0; | ||
const escape_1 = require("../helpers/escape"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
@@ -13,3 +14,3 @@ const schema_helpers_1 = require("../helpers/schema_helpers"); | ||
const mutate_plan_1 = require("./mutate_plan"); | ||
const orma_mutate = async (input_mutation, mysql_function, escape_fn, orma_schema) => { | ||
const orma_mutate = async (input_mutation, mysql_function, orma_schema) => { | ||
// clone to allow macros to mutation the mutation without changing the user input mutation object | ||
@@ -28,3 +29,3 @@ const mutation = (0, helpers_1.clone)(input_mutation); | ||
const entity_name = (0, helpers_1.last)(route); | ||
const statements = (0, exports.get_mutation_statements)(operation, entity_name, paths, mutation, tier_results, orma_schema, escape_fn); | ||
const statements = (0, exports.get_mutation_statements)(operation, entity_name, paths, mutation, tier_results, orma_schema); | ||
return statements.map(statement => (Object.assign(Object.assign({}, statement), { sql_string: (0, json_sql_1.json_to_sql)(statement.sql_ast), route, | ||
@@ -38,3 +39,3 @@ operation }))); | ||
.map(({ paths, route }) => { | ||
const sql_ast = (0, exports.generate_foreign_key_query)(mutation, (0, helpers_1.last)(route), paths, orma_schema, escape_fn); | ||
const sql_ast = (0, exports.generate_foreign_key_query)(mutation, (0, helpers_1.last)(route), paths, orma_schema); | ||
// sql ast can be undefined if there are no foreign keys to search for on this entity | ||
@@ -100,3 +101,3 @@ if (sql_ast === undefined) { | ||
*/ | ||
const generate_foreign_key_query = (mutation, entity_name, paths, orma_schema, escape_fn) => { | ||
const generate_foreign_key_query = (mutation, entity_name, paths, orma_schema) => { | ||
const foreign_keys = [ | ||
@@ -114,3 +115,3 @@ ...new Set((0, schema_helpers_1.get_child_edges)(entity_name, orma_schema).map(edge => edge.from_field)), | ||
identifying_keys.forEach(field => all_identifying_keys.add(field)); | ||
const where = (0, exports.generate_record_where_clause)(identifying_keys, record, escape_fn); | ||
const where = (0, exports.generate_record_where_clause)(identifying_keys, record); | ||
return where; | ||
@@ -153,6 +154,6 @@ }); | ||
*/ | ||
const get_mutation_statements = (operation, entity_name, paths, mutation, tier_results, orma_schema, escape_fn) => { | ||
const get_mutation_statements = (operation, entity_name, paths, mutation, tier_results, orma_schema) => { | ||
let statements; | ||
if (operation === 'update') { | ||
statements = (0, operation_macros_1.get_update_asts)(entity_name, paths, mutation, orma_schema, escape_fn).map((ast, i) => ({ | ||
statements = (0, operation_macros_1.get_update_asts)(entity_name, paths, mutation, orma_schema).map((ast, i) => ({ | ||
paths: [paths[i]], | ||
@@ -165,3 +166,3 @@ sql_ast: ast, | ||
{ | ||
sql_ast: (0, operation_macros_1.get_delete_ast)(entity_name, paths, mutation, orma_schema, escape_fn), | ||
sql_ast: (0, operation_macros_1.get_delete_ast)(entity_name, paths, mutation, orma_schema), | ||
paths, | ||
@@ -174,3 +175,3 @@ }, | ||
{ | ||
sql_ast: (0, operation_macros_1.get_create_ast)(entity_name, paths, mutation, tier_results, orma_schema, escape_fn), | ||
sql_ast: (0, operation_macros_1.get_create_ast)(entity_name, paths, mutation, tier_results, orma_schema), | ||
paths, | ||
@@ -229,5 +230,5 @@ }, | ||
// } | ||
const generate_record_where_clause = (identifying_keys, record, escape_fn) => { | ||
const generate_record_where_clause = (identifying_keys, record) => { | ||
const where_clauses = identifying_keys.map(key => ({ | ||
$eq: [key, escape_fn(record[key])], | ||
$eq: [key, (0, escape_1.orma_escape)(record[key])], | ||
})); | ||
@@ -234,0 +235,0 @@ const where = where_clauses.length > 1 |
@@ -6,3 +6,2 @@ "use strict"; | ||
const mutate_1 = require("./mutate"); | ||
const escape_fn = el => (typeof el === 'string' ? `\`${el}\`` : el); | ||
(0, mocha_1.describe)('mutate', () => { | ||
@@ -13,2 +12,3 @@ const orma_schema = { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -20,9 +20,9 @@ quantity: {}, | ||
primary_key: true, | ||
required: true, | ||
not_null: true, | ||
}, | ||
unique1: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
unique2: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
@@ -58,5 +58,7 @@ quantity: {}, | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
id2: { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -70,3 +72,3 @@ parent_id: { | ||
}, | ||
batch_id: { required: true }, | ||
batch_id: {}, | ||
$indexes: [ | ||
@@ -83,2 +85,3 @@ { | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
@@ -267,3 +270,3 @@ parent_id: { | ||
}; | ||
const results = await (0, mutate_1.orma_mutate)(mutation, mysql_fn, escape_fn, orma_schema); | ||
const results = await (0, mutate_1.orma_mutate)(mutation, mysql_fn, orma_schema); | ||
const goal = { | ||
@@ -323,4 +326,3 @@ parents: [ | ||
}; | ||
// const escape_fn = val => typeof val === 'string' ? `"${val}"` : val | ||
const results = await (0, mutate_1.orma_mutate)(mutation, mutate_fn, escape_fn, orma_schema); | ||
const results = await (0, mutate_1.orma_mutate)(mutation, mutate_fn, orma_schema); | ||
const goal = { | ||
@@ -327,0 +329,0 @@ $operation: 'create', |
@@ -10,6 +10,5 @@ import { error_type } from '../../helpers/error_handling'; | ||
* @param orma_query a function which takes an orma query and gives the results of running the query | ||
* @param escape_function used to escape values that go in the generated query | ||
* @returns | ||
*/ | ||
export declare const verify_uniqueness: (mutation: any, orma_query: (query: any) => Promise<any>, orma_schema: orma_schema, escape_function: (value: any) => any) => Promise<error_type[]>; | ||
export declare const verify_uniqueness: (mutation: any, orma_query: (query: any) => Promise<any>, orma_schema: orma_schema) => Promise<error_type[]>; | ||
/** | ||
@@ -20,3 +19,3 @@ * Gets a query which gets all relevant records from the database needed to do uniqueness checks. | ||
*/ | ||
export declare const get_verify_uniqueness_query: (pathed_records_by_entity: Record<string, PathedRecord[]>, orma_schema: orma_schema, escape_function: (value: any) => any) => {}; | ||
export declare const get_verify_uniqueness_query: (pathed_records_by_entity: Record<string, PathedRecord[]>, orma_schema: orma_schema) => {}; | ||
/** | ||
@@ -23,0 +22,0 @@ * Given the data from {@link get_verify_uniqueness_query}, generates errors for all records in the mutation |
@@ -15,6 +15,5 @@ "use strict"; | ||
* @param orma_query a function which takes an orma query and gives the results of running the query | ||
* @param escape_function used to escape values that go in the generated query | ||
* @returns | ||
*/ | ||
const verify_uniqueness = async (mutation, orma_query, orma_schema, escape_function) => { | ||
const verify_uniqueness = async (mutation, orma_query, orma_schema) => { | ||
/* | ||
@@ -33,3 +32,3 @@ check that no two rows have the same value for the same unique column, and also make sure that no unique value | ||
const pathed_records_by_entity = (0, mutate_helpers_1.split_mutation_by_entity)(mutation); | ||
const query = (0, exports.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema, escape_function); | ||
const query = (0, exports.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema); | ||
const results = await orma_query(query); | ||
@@ -46,3 +45,3 @@ const database_errors = (0, exports.get_database_uniqueness_errors)(pathed_records_by_entity, results, mutation, orma_schema); | ||
*/ | ||
const get_verify_uniqueness_query = (pathed_records_by_entity, orma_schema, escape_function) => { | ||
const get_verify_uniqueness_query = (pathed_records_by_entity, orma_schema) => { | ||
const mutation_entities = Object.keys(pathed_records_by_entity); | ||
@@ -60,3 +59,3 @@ const query = mutation_entities.reduce((acc, entity) => { | ||
// searches all records for the entity | ||
const $where = (0, query_helpers_1.get_search_records_where)(searchable_pathed_records.map(({ record }) => record), record => (0, mutate_1.get_identifying_keys)(entity, record, orma_schema), escape_function); | ||
const $where = (0, query_helpers_1.get_search_records_where)(searchable_pathed_records.map(({ record }) => record), record => (0, mutate_1.get_identifying_keys)(entity, record, orma_schema)); | ||
if (!$where) { | ||
@@ -63,0 +62,0 @@ throw new Error('There should be a where clause. Something went wrong.'); |
@@ -10,10 +10,10 @@ "use strict"; | ||
id: { | ||
required: true, | ||
primary_key: true, | ||
not_null: true, | ||
}, | ||
first_name: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
last_name: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
@@ -32,6 +32,6 @@ age: {}, | ||
primary_key: true, | ||
required: true, | ||
not_null: true, | ||
}, | ||
title: { | ||
required: true, | ||
not_null: true, | ||
}, | ||
@@ -61,3 +61,3 @@ description: {}, | ||
}; | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema, el => el); | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
@@ -86,3 +86,3 @@ products: { | ||
}; | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema, el => el); | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
@@ -96,6 +96,6 @@ users: { | ||
{ | ||
$eq: ['first_name', 'john'], | ||
$eq: ['first_name', "'john'"], | ||
}, | ||
{ | ||
$eq: ['last_name', 'smith'], | ||
$eq: ['last_name', "'smith'"], | ||
}, | ||
@@ -132,3 +132,3 @@ ], | ||
}; | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema, el => el); | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
@@ -172,3 +172,3 @@ products: { | ||
}; | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema, el => el); | ||
const result = (0, verify_uniqueness_1.get_verify_uniqueness_query)(pathed_records_by_entity, orma_schema); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
@@ -184,3 +184,3 @@ products: { | ||
{ | ||
$in: ['title', ['chair']], | ||
$in: ['title', ["'chair'"]], | ||
}, | ||
@@ -255,3 +255,4 @@ ], | ||
], | ||
products: [{ | ||
products: [ | ||
{ | ||
record: { | ||
@@ -261,3 +262,4 @@ id: 13, | ||
}, | ||
}], | ||
}, | ||
], | ||
}; | ||
@@ -290,5 +292,5 @@ const database_records_by_id = { | ||
first_name: 'john', | ||
last_name: 'smith' | ||
last_name: 'smith', | ||
}, | ||
path: ['users', 0] | ||
path: ['users', 0], | ||
}, | ||
@@ -308,6 +310,7 @@ { | ||
}, | ||
path: ['users', 2] | ||
path: ['users', 2], | ||
}, | ||
], | ||
products: [{ | ||
products: [ | ||
{ | ||
record: { | ||
@@ -317,3 +320,4 @@ id: 13, | ||
}, | ||
}], | ||
}, | ||
], | ||
}; | ||
@@ -320,0 +324,0 @@ const errors = (0, verify_uniqueness_1.get_mutation_uniqueness_errors)(mutation_pathed_records_by_id, {}, orma_schema); |
@@ -74,3 +74,3 @@ "use strict"; | ||
'$insert_into', | ||
'$values' | ||
'$values', | ||
]; | ||
@@ -83,2 +83,3 @@ // turn the array into an object for fast lookups | ||
const sql_command_parsers = { | ||
// DML commands | ||
$select: args => `SELECT ${args.join(', ')}`, | ||
@@ -89,3 +90,3 @@ $as: args => `(${args[0]}) AS ${args[1]}`, | ||
$having: args => `HAVING ${args}`, | ||
$in: (args, path) => `${args[0]}${(0, helpers_1.last)(path) === '$not' ? ' NOT' : ''} IN (${args[1]})`, | ||
$in: (args, path) => `${args[0]}${nested_under_odd_nots(path) ? ' NOT' : ''} IN (${args[1]})`, | ||
$group_by: args => `GROUP BY ${args.join(', ')}`, | ||
@@ -97,7 +98,7 @@ $order_by: args => `ORDER BY ${args.join(', ')}`, | ||
const res = `(${args.join(') AND (')})`; | ||
return (0, helpers_1.last)(path) === '$not' ? `NOT (${res})` : res; | ||
return nested_under_odd_nots(path) ? `NOT (${res})` : res; | ||
}, | ||
$or: (args, path) => { | ||
const res = `(${args.join(') OR (')})`; | ||
return (0, helpers_1.last)(path) === '$not' ? `NOT (${res})` : res; | ||
return nested_under_odd_nots(path) ? `NOT (${res})` : res; | ||
}, | ||
@@ -107,23 +108,121 @@ $any: args => `ANY (${args})`, | ||
$eq: (args, path) => args[1] === null | ||
? `${args[0]}${(0, helpers_1.last)(path) === '$not' ? ' NOT' : ''} IS NULL` | ||
: `${args[0]} ${(0, helpers_1.last)(path) === '$not' ? '!' : ''}= ${args[1]}`, | ||
$gt: (args, path) => `${args[0]} ${(0, helpers_1.last)(path) === '$not' ? '<=' : '>'} ${args[1]}`, | ||
$lt: (args, path) => `${args[0]} ${(0, helpers_1.last)(path) === '$not' ? '>=' : '<'} ${args[1]}`, | ||
$gte: (args, path) => `${args[0]} ${(0, helpers_1.last)(path) === '$not' ? '<' : '>='} ${args[1]}`, | ||
$lte: (args, path) => `${args[0]} ${(0, helpers_1.last)(path) === '$not' ? '>' : '<='} ${args[1]}`, | ||
$exists: (args, path) => `${(0, helpers_1.last)(path) === '$not' ? 'NOT ' : ''}EXISTS (${args})`, | ||
? `${args[0]}${nested_under_odd_nots(path) ? ' NOT' : ''} IS NULL` | ||
: `${args[0]} ${nested_under_odd_nots(path) ? '!' : ''}= ${args[1]}`, | ||
$gt: (args, path) => `${args[0]} ${nested_under_odd_nots(path) ? '<=' : '>'} ${args[1]}`, | ||
$lt: (args, path) => `${args[0]} ${nested_under_odd_nots(path) ? '>=' : '<'} ${args[1]}`, | ||
$gte: (args, path) => `${args[0]} ${nested_under_odd_nots(path) ? '<' : '>='} ${args[1]}`, | ||
$lte: (args, path) => `${args[0]} ${nested_under_odd_nots(path) ? '>' : '<='} ${args[1]}`, | ||
$exists: (args, path) => `${nested_under_odd_nots(path) ? 'NOT ' : ''}EXISTS (${args})`, | ||
$limit: args => `LIMIT ${args}`, | ||
$offset: args => `OFFSET ${args}`, | ||
$like: (args, path) => { | ||
const string_arg = args[1].toString(); | ||
const search_value = string_arg.replace(/^\'/, '').replace(/\'$/, ''); // get rid of quotes if they were put there by escape() | ||
return `${args[0]}${(0, helpers_1.last)(path) === '$not' ? ' NOT' : ''} LIKE '%${search_value}%'`; | ||
// const string_arg = args[1].toString() | ||
// const search_value = string_arg.replace(/^\'/, '').replace(/\'$/, '') // get rid of quotes if they were put there by escape() | ||
// return `${args[0]}${ | ||
// nested_under_odd_nots(path) ? ' NOT' : '' | ||
// } LIKE '%${search_value}%'` | ||
return `${args[0]}${nested_under_odd_nots(path) ? ' NOT' : ''} LIKE ${args[1]}`; | ||
}, | ||
$not: args => args, | ||
// SQL functions | ||
$sum: args => `SUM(${args})`, | ||
// mutations | ||
$insert_into: ([table_name, [...columns]]) => `INSERT INTO ${table_name} (${columns.join(', ')})`, | ||
$values: (values) => `VALUES ${values.map(inner_values => `(${inner_values.join(', ')})`).join(', ')}`, | ||
$values: (values) => `VALUES ${values | ||
.map(inner_values => `(${inner_values.join(', ')})`) | ||
.join(', ')}`, | ||
$update: table_name => `UPDATE ${table_name}`, | ||
$set: (items) => `SET ${items.map(([column, value]) => `${column} = ${value}`).join(', ')}`, | ||
$delete_from: table_name => `DELETE FROM ${table_name}` | ||
$set: items => `SET ${items | ||
.map(([column, value]) => `${column} = ${value}`) | ||
.join(', ')}`, | ||
$delete_from: table_name => `DELETE FROM ${table_name}`, | ||
// DDL commands | ||
}; | ||
/** | ||
* Returns true if the last n elements of a path are $not and n is odd. So ['a', '$not'] returns true | ||
* but ['a', '$not', '$not'] returns false | ||
*/ | ||
const nested_under_odd_nots = (path) => { | ||
let not_count = 0; | ||
for (let i = 0; i < path.length; i++) { | ||
const path_element = path[path.length - 1 - i]; | ||
if (path_element === '$not') { | ||
not_count += 1; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
const is_odd = not_count % 2 === 1; | ||
return is_odd; | ||
}; | ||
/* | ||
{ | ||
$create_table: { | ||
$table_name: 'test', | ||
// table level props | ||
$table_fields: [ | ||
['col1', { | ||
field level props | ||
}] | ||
] | ||
} | ||
} | ||
{ | ||
$create_table: 'my_table', | ||
$temporary: true, | ||
$if_not_exists: true, | ||
$columns: [{ | ||
// column_definition | ||
}] | ||
$like: 'my_other_table', | ||
$as: { | ||
$select: ['col'], | ||
$from:'my_other_table' | ||
}, | ||
$ignore: true, // xor with replace | ||
$replace: true, | ||
// table options | ||
$autoextend_size: 0, | ||
$auto_increment: 1, | ||
$avg_row_length: 100, | ||
$character_set: 'DEFAULT', | ||
$checksum: 1, | ||
$comment: 'My table', | ||
$compression: 'Zlib', | ||
$connection: '', | ||
$data_directory: '...', | ||
$index_directory: '...', | ||
$delay_key_write: 1, | ||
$encryption: 'Y', | ||
$engine_attribute: '', | ||
$secondary_engine_attribute: '', | ||
$insert_method: 'FIRST', | ||
$key_block_size: 64, | ||
$max_rows: 1000, | ||
$min_rows: 500, | ||
$pack_keys: 'DEFAULT', | ||
$row_format: '', | ||
$stats_auto_recalc: 0, | ||
$states_persistent | ||
} | ||
// column definition | ||
{ | ||
$data_type: ['decimal', 6, 2], // check sql docs page to make sure we have everything for data type | ||
$not_null: true, | ||
$default: 123, | ||
$invisible: true, | ||
$auto_increment: true, | ||
$comment: 'my column', | ||
$collate: 'utf8_bin', | ||
$generated_always_as: 'SQRT(col1)', | ||
$stored: true | ||
} | ||
*/ |
@@ -12,3 +12,3 @@ "use strict"; | ||
$select: ['a'], | ||
$from: 'b' | ||
$from: 'b', | ||
}; | ||
@@ -22,4 +22,4 @@ const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json)); | ||
$where: { | ||
$eq: ['a', 'b'] | ||
} | ||
$eq: ['a', 'b'], | ||
}, | ||
}; | ||
@@ -30,7 +30,7 @@ const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json)); | ||
}); | ||
(0, mocha_1.test)("'not' command works", () => { | ||
(0, mocha_1.test)("'$not' command works", () => { | ||
const json = { | ||
$not: { | ||
$in: ['a', [1, 2]] | ||
} | ||
$in: ['a', [1, 2]], | ||
}, | ||
}; | ||
@@ -41,5 +41,21 @@ const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json)); | ||
}); | ||
(0, mocha_1.test)("ignores even number of '$not' commands", () => { | ||
const json = { | ||
$not: { | ||
$not: { | ||
$not: { | ||
$not: { | ||
$in: ['a', [1, 2]], | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json)); | ||
const goal = (0, sql_formatter_1.format)('a IN (1, 2)'); | ||
(0, chai_1.expect)(sql).to.equal(goal); | ||
}); | ||
(0, mocha_1.test)('ignores undefined properties', () => { | ||
const json = { | ||
$having: undefined | ||
$having: undefined, | ||
}; | ||
@@ -46,0 +62,0 @@ const sql = (0, sql_formatter_1.format)((0, json_sql_1.json_to_sql)(json)); |
@@ -18,2 +18,3 @@ import { orma_schema } from '../../introspector/introspector'; | ||
export declare const apply_any_path_macro: (query: any, orma_schema: orma_schema) => void; | ||
export declare const get_any_path_context_entity: (path: any, query: any) => string; | ||
export declare const process_any_clause: (any_clause: any, initial_entity: string, filter_type: '$having' | '$where', orma_schema: orma_schema) => any; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.process_any_clause = exports.apply_any_path_macro = void 0; | ||
exports.process_any_clause = exports.get_any_path_context_entity = exports.apply_any_path_macro = void 0; | ||
const helpers_1 = require("../../helpers/helpers"); | ||
@@ -32,3 +32,3 @@ const schema_helpers_1 = require("../../helpers/schema_helpers"); | ||
paths_to_any.forEach(([clause, clause_path]) => { | ||
const current_entity = get_any_path_context_entity(clause_path, query); | ||
const current_entity = (0, exports.get_any_path_context_entity)(clause_path, query); | ||
const filter_type = get_filter_type(clause_path); | ||
@@ -58,2 +58,3 @@ const processed_clause = (0, exports.process_any_clause)(clause, current_entity, filter_type, orma_schema); | ||
}; | ||
exports.get_any_path_context_entity = get_any_path_context_entity; | ||
const get_filter_type = path => { | ||
@@ -60,0 +61,0 @@ const filter_type = (0, helpers_1.last)(path.filter(path_el => path_el === '$having' || path_el === '$where')); |
@@ -23,2 +23,2 @@ /** | ||
export declare const combine_wheres: (where_clauses: Record<string, any>[], connective: '$and' | '$or') => Record<string, any>; | ||
export declare const get_search_records_where: (records: Record<string, any>[], get_search_fields: (record: Record<string, any>) => string[], escape_function: (value: any) => any) => Record<string, any>; | ||
export declare const get_search_records_where: (records: Record<string, any>[], get_search_fields: (record: Record<string, any>) => string[]) => Record<string, any>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.get_search_records_where = exports.combine_wheres = exports.query_for_each = exports.is_subquery = void 0; | ||
const escape_1 = require("../helpers/escape"); | ||
const helpers_1 = require("../helpers/helpers"); | ||
@@ -75,3 +76,3 @@ const schema_helpers_1 = require("../helpers/schema_helpers"); | ||
exports.combine_wheres = combine_wheres; | ||
const get_search_records_where = (records, get_search_fields, escape_function) => { | ||
const get_search_records_where = (records, get_search_fields) => { | ||
const records_by_search_fields = records.reduce((acc, record) => { | ||
@@ -97,3 +98,3 @@ const identifying_fields = get_search_fields(record); | ||
field, | ||
records.map(record => escape_function(record[field])), | ||
records.map(record => (0, escape_1.orma_escape)(record[field])), | ||
], | ||
@@ -107,3 +108,3 @@ }; | ||
$and: identifying_fields.map(field => ({ | ||
$eq: [field, escape_function(record[field])], | ||
$eq: [field, (0, escape_1.orma_escape)(record[field])], | ||
})), | ||
@@ -110,0 +111,0 @@ })); |
@@ -108,5 +108,5 @@ "use strict"; | ||
]; | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1'], el => el); | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1']); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
$in: ['field1', ['hi']], | ||
$in: ['field1', ["'hi'"]], | ||
}); | ||
@@ -120,5 +120,5 @@ }); | ||
]; | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1'], el => `"${el}"`); | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1']); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
$in: ['field1', ['"hi"']], | ||
$in: ['field1', ["'hi'"]], | ||
}); | ||
@@ -134,10 +134,10 @@ }); | ||
]; | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1', 'field2'], el => el); | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => ['field1', 'field2']); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
$and: [ | ||
{ | ||
$eq: ['field1', 'hi'], | ||
$eq: ['field1', "'hi'"], | ||
}, | ||
{ | ||
$eq: ['field2', 'hi2'], | ||
$eq: ['field2', "'hi2'"], | ||
}, | ||
@@ -168,7 +168,7 @@ ], | ||
]; | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => record.type === 1 ? ['field1'] : ['field1', 'field2'], el => el); | ||
const result = (0, query_helpers_1.get_search_records_where)(records, record => record.type === 1 ? ['field1'] : ['field1', 'field2']); | ||
(0, chai_1.expect)(result).to.deep.equal({ | ||
$or: [ | ||
{ | ||
$in: ['field1', ['a', 'b']], | ||
$in: ['field1', ["'a'", "'b'"]], | ||
}, | ||
@@ -178,6 +178,6 @@ { | ||
{ | ||
$eq: ['field1', 'c1'], | ||
$eq: ['field1', "'c1'"], | ||
}, | ||
{ | ||
$eq: ['field2', 'c2'], | ||
$eq: ['field2', "'c2'"], | ||
}, | ||
@@ -189,6 +189,6 @@ ], | ||
{ | ||
$eq: ['field1', 'd1'], | ||
$eq: ['field1', "'d1'"], | ||
}, | ||
{ | ||
$eq: ['field2', 'd2'], | ||
$eq: ['field2', "'d2'"], | ||
}, | ||
@@ -195,0 +195,0 @@ ], |
@@ -0,5 +1,6 @@ | ||
import { error_type } from '../helpers/error_handling'; | ||
import { orma_schema } from '../introspector/introspector'; | ||
import { QueryResult } from '../types/query/query_result_types'; | ||
import { OrmaQuery } from '../types/query/query_types'; | ||
import { DeepReadonlyObject } from '../types/schema_types'; | ||
import { DeepReadonly } from '../types/schema_types'; | ||
export declare const get_real_parent_name: (path: (string | number)[], query: any) => any; | ||
@@ -9,4 +10,9 @@ export declare const get_real_entity_name: (path: (string | number)[], query: any) => any; | ||
export declare const orma_nester: (results: [string[], Record<string, unknown>[]][], query: any, orma_schema: orma_schema) => {}; | ||
export declare const orma_query: <Schema extends DeepReadonlyObject<orma_schema>, Query extends OrmaQuery<Schema>>(raw_query: Query, orma_schema_input: Schema, query_function: (sql_string: string[]) => Promise<Record<string, unknown>[][]>, escaping_function: (value: any) => any) => Promise<import("../types/query/query_result_types").StripKeywords<import("../types/query/query_result_types").WrapInArrays<import("../types/query/query_result_types").AddSchemaTypes<Schema, Query, unknown>>>>; | ||
export declare const as_orma_schema: <Schema extends DeepReadonlyObject<orma_schema>>(schema: Schema) => Schema; | ||
export declare const as_orma_query: <Schema extends DeepReadonlyObject<orma_schema>, T extends OrmaQuery<Schema>>(schema: Schema, query: T) => T; | ||
export declare const orma_query: <Schema extends import("../types/schema_types").DeepReadonlyObject<orma_schema>, Query extends OrmaQuery<Schema>>(raw_query: Query, orma_schema_input: Schema, query_function: (sql_string: string[]) => Promise<Record<string, unknown>[][]>, escaping_function: (value: any) => any, validation_function: (query: any) => any[]) => Promise<(import("../types/query/query_result_types").StripKeywords<import("../types/query/query_result_types").WrapInArrays<import("../types/query/query_result_types").AddSchemaTypes<Schema, Query, unknown>>> & { | ||
$success: true; | ||
}) | { | ||
$success: false; | ||
errors: error_type[]; | ||
}>; | ||
export declare const as_orma_schema: <Schema extends import("../types/schema_types").DeepReadonlyObject<orma_schema>>(schema: Schema) => Schema; | ||
export declare const as_orma_query: <Schema extends import("../types/schema_types").DeepReadonlyObject<orma_schema>, T extends DeepReadonly<OrmaQuery<Schema>>>(schema: Schema, query: T) => T; |
@@ -13,2 +13,3 @@ "use strict"; | ||
const query_plan_1 = require("./query_plan"); | ||
const query_validation_1 = require("./query_validation"); | ||
// This function will default to the from clause | ||
@@ -18,3 +19,4 @@ const get_real_parent_name = (path, query) => { | ||
return null; | ||
return (0, helpers_1.deep_get)([...(0, helpers_1.drop_last)(1, path), '$from'], query, null) || path[path.length - 2]; | ||
return ((0, helpers_1.deep_get)([...(0, helpers_1.drop_last)(1, path), '$from'], query, null) || | ||
path[path.length - 2]); | ||
}; | ||
@@ -96,5 +98,19 @@ exports.get_real_parent_name = get_real_parent_name; | ||
// export const orma_query = async <schema>(raw_query: validate_query<schema>, orma_schema: validate_orma_schema<schema>, query_function: (sql_string: string) => Promise<Record<string, unknown>[]>) => { | ||
const orma_query = async (raw_query, orma_schema_input, query_function, escaping_function) => { | ||
const orma_query = async (raw_query, orma_schema_input, query_function, escaping_function, validation_function) => { | ||
const query = (0, helpers_1.clone)(raw_query); // clone query so we can apply macros without mutating the actual input query | ||
const orma_schema = orma_schema_input; // this is just because the codebase isnt properly typed | ||
// validation | ||
(0, query_validation_1.preprocess_query_for_validation)(query, orma_schema); | ||
const errors = [ | ||
...validation_function(query), | ||
...(0, query_validation_1.get_any_path_errors)(query, orma_schema), | ||
]; | ||
if (errors.length > 0) { | ||
return { | ||
$success: false, | ||
errors, | ||
}; | ||
} | ||
(0, query_validation_1.postprocess_query_for_validation)(query); | ||
// simple macros | ||
(0, any_path_macro_1.apply_any_path_macro)(query, orma_schema); | ||
@@ -119,2 +135,4 @@ (0, select_macro_1.apply_select_macro)(query, orma_schema); | ||
const output = (0, exports.orma_nester)(results, query, orma_schema); | ||
// @ts-ignore | ||
output.$success = true; | ||
return output; | ||
@@ -127,2 +145,2 @@ }; | ||
exports.as_orma_query = as_orma_query; | ||
// export const as_orma_query_result = <Schema extends OrmaSchema, Query extends OrmaQuery<Schema>>(orma_schema: Schema, query: Query): QueryResult => | ||
// export const as_orma_query_result = <Schema extends OrmaSchema, Query extends OrmaQuery<Schema>>(orma_schema: Schema, query: Query): QueryResult => |
@@ -20,3 +20,3 @@ import { XOR } from '../helper_types'; | ||
} & { | ||
[Field in FilterFieldsBySchemaProp<Schema, Entity, 'required', true>]: FieldType<Schema, Entity, Field>; | ||
[Field in FilterFieldsBySchemaProp<Schema, Entity, 'nullable', false | undefined>]: FieldType<Schema, Entity, Field>; | ||
}; | ||
@@ -23,0 +23,0 @@ declare type ForeignKeyFieldsObj<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, ParentEdges extends GetParentEdges<Schema, Entity>, RequireOperation extends boolean> = ParentEdges extends GetParentEdges<Schema, Entity> ? XOR<{ |
@@ -7,7 +7,6 @@ "use strict"; | ||
id: { | ||
data_type: 'number', | ||
data_type: 'int', | ||
}, | ||
vendor_id: { | ||
required: true, | ||
data_type: 'number', | ||
data_type: 'int', | ||
references: { | ||
@@ -27,7 +26,6 @@ vendors: { | ||
name: { | ||
required: true, | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
}, | ||
nadescriptionme: { | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
}, | ||
@@ -42,3 +40,2 @@ $indexes: [], | ||
product_id: { | ||
required: true, | ||
references: { | ||
@@ -53,3 +50,2 @@ products: { | ||
image_id: { | ||
required: true, | ||
references: { | ||
@@ -111,5 +107,7 @@ images: { | ||
$operation: 'create', | ||
image_urls: [{ | ||
image_id: 12 | ||
}] | ||
image_urls: [ | ||
{ | ||
image_id: 12, | ||
}, | ||
], | ||
}; | ||
@@ -121,6 +119,8 @@ } | ||
const t = { | ||
image_urls: [{ | ||
image_urls: [ | ||
{ | ||
// $operation required here | ||
image_id: 12 | ||
}] | ||
image_id: 12, | ||
}, | ||
], | ||
}; | ||
@@ -127,0 +127,0 @@ } |
@@ -8,3 +8,3 @@ "use strict"; | ||
id: { | ||
data_type: 'number', | ||
data_type: 'int', | ||
}, | ||
@@ -41,3 +41,3 @@ vendor_id: { | ||
url: { | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
}, | ||
@@ -44,0 +44,0 @@ }, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const __1 = require("../.."); | ||
const introspector_1 = require("../../introspector/introspector"); | ||
const query_1 = require("../../query/query"); | ||
{ | ||
const schema = (0, introspector_1.as_orma_schema)({ | ||
const schema = { | ||
products: { | ||
id: { | ||
data_type: 'number', | ||
data_type: 'int', | ||
}, | ||
@@ -22,6 +21,6 @@ }, | ||
url: { | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
}, | ||
}, | ||
}); | ||
}; | ||
const query = (0, query_1.as_orma_query)(schema, { | ||
@@ -37,9 +36,11 @@ my_products: { | ||
// }], | ||
$group_by: ['my_id'] | ||
$group_by: ['id'], | ||
}, | ||
}); | ||
(0, __1.orma_query)(query, schema, async () => ({}), () => { }, () => []).then(result => { | ||
if (result.$success) { | ||
result.my_products[0].id; | ||
result.my_products[0].images[0].my_url; | ||
} | ||
}); | ||
(0, __1.orma_query)(query, schema, async () => ({}), () => { }).then(result => { | ||
result.my_products[0].id; | ||
result.my_products[0].images[0].my_url; | ||
}); | ||
} |
@@ -40,7 +40,7 @@ import { Pluck } from '../helper_types'; | ||
}; | ||
declare type OrderBy<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>> = readonly (FieldOrString<Schema, Entity> | { | ||
$asc: FieldOrString<Schema, Entity>; | ||
declare type OrderBy<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>> = readonly (FieldOrString<Schema, Entity> | Expression<Schema, Entity> | { | ||
$asc: FieldOrString<Schema, Entity> | Expression<Schema, Entity>; | ||
} | { | ||
$desc: FieldOrString<Schema, Entity>; | ||
} | Expression<Schema, Entity>)[]; | ||
$desc: FieldOrString<Schema, Entity> | Expression<Schema, Entity>; | ||
})[]; | ||
export {}; |
import { Edge } from '../helpers/schema_helpers'; | ||
import { mysql_to_simple_types, orma_field_schema, orma_schema } from '../introspector/introspector'; | ||
import { mysql_to_typescript_types, orma_field_schema, orma_schema } from '../introspector/introspector'; | ||
import { IsEqual } from './helper_types'; | ||
@@ -40,6 +40,6 @@ export declare type DeepReadonly<T> = T extends (infer R)[] ? DeepReadonlyArray<R> : T extends Function ? T : T extends object ? DeepReadonlyObject<T> : T; | ||
data_type: any; | ||
} ? FieldTypeStringToType<Schema[Entity][Field]['data_type']> : any; | ||
} ? FieldTypeStringToType<MysqlToTypescriptTypeString<Schema[Entity][Field]['data_type']>> : any; | ||
export declare type GetFieldSchema<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, Field extends GetFields<Schema, Entity>> = Schema[Entity][Field] extends orma_field_schema ? Schema[Entity][Field] : any; | ||
export declare type GetRequiredFields<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>> = GetFieldSchema<Schema, Entity, GetFields<Schema, Entity>>['required'] extends true ? any : never; | ||
declare type FieldTypeStringToType<TypeString extends typeof mysql_to_simple_types[keyof typeof mysql_to_simple_types]> = TypeString extends 'string' ? string : TypeString extends 'number' ? number : TypeString extends 'boolean' ? boolean : TypeString extends 'date' ? Date : any; | ||
declare type MysqlToTypescriptTypeString<TypeString extends keyof typeof mysql_to_typescript_types> = typeof mysql_to_typescript_types[TypeString]; | ||
declare type FieldTypeStringToType<TypeString extends typeof mysql_to_typescript_types[keyof typeof mysql_to_typescript_types]> = TypeString extends 'string' ? string : TypeString extends 'number' ? number : TypeString extends 'boolean' ? boolean : TypeString extends 'date' ? Date : any; | ||
export declare type FilterFieldsBySchemaProp<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, SchemaProp extends string, value> = FilterFieldsBySchemaPropWithFieldsExplicit<Schema, Entity, GetFields<Schema, Entity>, SchemaProp, value>; | ||
@@ -46,0 +46,0 @@ declare type FilterFieldsBySchemaPropWithFieldsExplicit<Schema extends OrmaSchema, Entity extends GetAllEntities<Schema>, Fields extends GetFields<Schema, Entity>, SchemaProp extends string, value> = Fields extends any ? FieldSchemaPropEq<Schema, Entity, Fields, SchemaProp, value> extends true ? Fields : never : never; |
@@ -7,3 +7,3 @@ "use strict"; | ||
id: { | ||
data_type: 'string', | ||
data_type: 'varchar', | ||
}, | ||
@@ -10,0 +10,0 @@ vendor_id: { |
{ | ||
"name": "orma", | ||
"version": "1.0.57", | ||
"version": "1.0.58", | ||
"description": "A declarative relational syncronous orm", | ||
@@ -12,3 +12,4 @@ "main": "build/index.js", | ||
"ntt": "nodemon --exec npm run test", | ||
"coverage-watch": "live-server coverage" | ||
"coverage-watch": "live-server coverage", | ||
"compile-validation": "node -e \"require('./src/scripts/compile_validation').compile_validation()\"" | ||
}, | ||
@@ -48,4 +49,7 @@ "files": [ | ||
"@jsdevtools/npm-publish": "^1.4.3", | ||
"@types/chai": "^4.3.0", | ||
"@types/mocha": "^8.2.3", | ||
"@types/node": "^16.3.2", | ||
"@types/sqlstring": "^2.3.0", | ||
"ajv": "^8.10.0", | ||
"chai": "^4.3.4", | ||
@@ -78,3 +82,7 @@ "live-server": "^1.2.1", | ||
"ext": "ts, js, jsx" | ||
}, | ||
"dependencies": { | ||
"jsonschema": "^1.4.0", | ||
"sqlstring": "^2.3.3" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
396159
150
10032
2
13
+ Addedjsonschema@^1.4.0
+ Addedsqlstring@^2.3.3
+ Addedjsonschema@1.4.1(transitive)
+ Addedsqlstring@2.3.3(transitive)