Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- async newJoinMonster({
- table,
- whereClause: _WC,
- knexQuery,
- auth,
- permission_list,
- row_id,
- force_id_read = false,
- run_as,
- operator,
- }) {
- const whereClause = JSON.parse(JSON.stringify(_WC));
- const { token, account } = auth;
- if (Array.isArray(whereClause)) {
- if (whereClause.length === 0) {
- return { builder: knexQuery, filters_applied: false };
- }
- if (
- whereClause.length === 1 &&
- (whereClause[0] === "AND" || whereClause[0] === "OR")
- ) {
- return { builder: knexQuery, filters_applied: false };
- }
- operator = whereClause.shift();
- if (operator !== "AND" && operator !== "OR") {
- throw new Error(
- "Please send your operator as the first item of the array",
- );
- }
- for (const item of whereClause) {
- const temp_knex = this.knex;
- const temp2_builder = await this.newJoinMonster({
- table,
- whereClause: item,
- knexQuery: temp_knex.select("*"),
- auth,
- permission_list,
- row_id,
- force_id_read: false,
- run_as,
- operator,
- });
- if (
- operator === "OR" &&
- temp2_builder.filters_applied &&
- temp2_builder.builder
- ) {
- knexQuery = knexQuery.orWhere((builder) => {
- return builder.whereRaw(
- temp2_builder.builder.toSQL().sql.split("select * where")[1],
- temp2_builder.builder.toSQL().bindings,
- );
- });
- } else if (
- operator === "AND" &&
- temp2_builder.filters_applied &&
- temp2_builder.builder
- ) {
- knexQuery = knexQuery.where((builder) => {
- return builder.whereRaw(
- temp2_builder.builder.toSQL().sql.split("select * where")[1],
- temp2_builder.builder.toSQL().bindings,
- );
- });
- }
- }
- return {
- builder: knexQuery,
- filters_applied: true,
- };
- } else {
- console.log("here");
- for (const [key, value] of Object.entries(whereClause)) {
- // CHECK IF KEY IS A TABLE
- const some_type_of_link = ["foreign", "link", "externalLink"];
- console.log("KEY: ", key);
- console.log("TABLE: ", this.schema[table]);
- console.log("LINK TYPE: ", this.schema[table].columns?.[key]?.type);
- // I WILL NEED TO HAVE SCHEMA INCLUDE ID, CREATED_AT, UPDATED_AT. BUT THAT IS A TASK FOR FUTURE ADAM
- if (
- some_type_of_link.includes(this.schema[table].columns?.[key]?.type)
- ) {
- // table schema details
- const querySchema = this.schema[table].columns[key];
- // check if this column is a reverse relation
- const bColumnIsReverse = querySchema.reverse || false;
- let allowed;
- // check permissions and see if the user is actually allowed to query using the where filter
- if (bColumnIsReverse) {
- allowed = await this.aclAndRclPermissionCheck({
- table_name: querySchema[querySchema.type].table,
- key: querySchema[querySchema.type].reference_name,
- account,
- row_id,
- force_id: force_id_read,
- permission_list,
- permissionType: "read",
- });
- } else {
- allowed = await this.aclAndRclPermissionCheck({
- table_name: table,
- key,
- account,
- row_id,
- virtual: querySchema.type === "link",
- force_id: force_id_read,
- permission_list,
- permissionType: "read",
- });
- }
- //debug_logger.log({ bColumnIsReverse });
- /* debug_logger.log('acl+rcl permission check arguments', {
- table_name: table,
- key,
- account,
- row_id,
- virtual: querySchema.type === 'link',
- force_id: force_id_read,
- permission_list,
- permissionType: 'read',
- }); */
- //console.log({ key, allowed });
- if (!allowed) {
- // QUERY TO AUTOMATICALLY REMOVE ALL ROWS / IMPOSSIBLE QUERY
- // return this.throwErrorForJoinMonster(knexQuery, table);
- throw new Error(
- `Foreign field can't be searched in where clause because no ACL, yes RCL; field: ${key}`,
- );
- }
- let tableToJoin = "";
- if (querySchema.type === "foreign") {
- allowed = await this.aclAndRclPermissionCheck({
- table_name: querySchema[querySchema.type].table,
- key: "id",
- row_id,
- force_id: force_id_read,
- permission_list,
- account,
- permissionType: "read",
- });
- tableToJoin = querySchema[querySchema.type].table;
- } else {
- allowed = await this.aclAndRclPermissionCheck({
- table_name: table,
- key,
- row_id,
- account,
- force_id: force_id_read,
- virtual: querySchema.type === "link",
- permission_list,
- permissionType: "read",
- });
- tableToJoin = key;
- }
- if (!allowed) {
- // QUERY TO AUTOMATICALLY REMOVE ALL ROWS / IMPOSSIBLE QUERY
- // return this.throwErrorForJoinMonster(knexQuery, table);
- throw new Error(
- `Foreign field can't be searched in where clause because yes ACL, ? RCL; field: ${key}`,
- );
- }
- /**
- * if field simply specifies null, e.g.
- *
- * where: ["AND", { job: null }]
- *
- * just make it where null
- */
- if (value === null && !bColumnIsReverse) {
- knexQuery.whereNull(key);
- continue;
- }
- let children_results;
- const new_query_table = querySchema[querySchema.type].table;
- // TODO: NEED TO CHECK IF PLUGIN
- const new_query_table_schema =
- this.schema[new_query_table].microservice_name;
- let children_knex_query;
- let children_query_key;
- const child_table_def = this.schema[table].columns?.[key]?.[
- this.schema[table].columns?.[key]?.type
- ];
- const child_primary_key = child_table_def.key;
- const reference_name = child_table_def.reference_name ||
- child_table_def.table || table;
- if (bColumnIsReverse) {
- children_query_key = table;
- children_knex_query = this.knex
- .from(`${new_query_table} AS ${new_query_table}`)
- .withSchema(new_query_table_schema)
- .select(reference_name);
- } else if (querySchema.type === "link") {
- children_query_key = "id";
- children_knex_query = this.knex
- .from(`${new_query_table} AS ${new_query_table}`)
- .withSchema(new_query_table_schema)
- .select(children_knex_query);
- } else {
- children_query_key = querySchema[querySchema.type].key;
- children_knex_query = this.knex
- .from(`${new_query_table} AS ${new_query_table}`)
- .withSchema(new_query_table_schema)
- .select(children_knex_query);
- }
- if (value === null) {
- /**
- * inverse search
- * in order to get where reverse foreign is null we have to do:
- *
- * get current records that do have that value, and "reverse" the result
- *
- * i.e. to get a list of jobs that do not have daily reports,
- * get a list of daily reports that have jobs,
- * get jobs which ids has not been in that array
- */
- const children_results_temp = await this.knex
- .from(table)
- .withSchema(new_query_table_schema)
- .select(child_primary_key)
- .whereNotIn(
- child_primary_key,
- children_knex_query.whereNotNull(reference_name),
- );
- children_results = children_results_temp.map((el) => {
- return el[child_primary_key];
- });
- } else {
- const children_results_query = await this.newJoinMonster({
- table: new_query_table,
- whereClause: value,
- knexQuery: children_knex_query,
- permission_list,
- row_id,
- auth,
- });
- const children_results_temp = await children_results_query.builder;
- children_results = children_results_temp.map((el) => {
- return el[children_query_key];
- });
- }
- const column_type = querySchema[querySchema.type].type;
- let where_key;
- if (bColumnIsReverse) {
- where_key = querySchema[querySchema.type].key;
- } else {
- where_key = key;
- }
- // over here, we just got the results back from the foreign key search and if column type isn't an array, we are doing a where in search.
- if (querySchema.type === "foreign") {
- if (!column_type?.includes("Array")) {
- knexQuery.whereIn(where_key, children_results);
- } else {
- const raw_query = `array[${children_results.join(
- ", ",
- )
- }] @> "${where_key}"`;
- if (children_results.length === 0) {
- knexQuery.whereNull("id");
- } else {
- knexQuery.whereRaw(raw_query);
- }
- }
- } else if (querySchema.type === "link") {
- const link_table_name = linkTableNamePartial({
- table_name: table,
- column_name: key,
- });
- let temp_query = await this.knex(link_table_name)
- .withSchema("link")
- .whereIn(
- getReverseColumnName({
- table_name: table,
- column_name: key,
- }),
- children_results,
- );
- knexQuery.whereIn(
- "id",
- temp_query.map((el) => el[`${table}_${key}`]),
- );
- }
- } // must mean that the argument is a column name (id, name etc...)
- // I'll add a check later
- else {
- console.log("CANNOT CREATE JOIN");
- // STANDARD PERMISSION CHECKS
- let temp_table = table;
- if (this.schema[table].is_audit) {
- temp_table = this.schema[table].audits;
- }
- const newPermissions = await this.CL.getAllPermissions({
- table_name: temp_table,
- account,
- force_id: force_id_read,
- info: {
- where: "newJoinMonster STANDARD PERMISSION CHECKS",
- },
- });
- let has_access = false;
- //console.log('check permission for', key);
- // allow access if acl gives
- if (newPermissions?.acl_permissions?.read?.includes(key)) {
- has_access = true;
- } else {
- console.log({ row_id });
- // else if acl blocks
- // check if rcl gives
- if (
- _.find(newPermissions.rcl_permissions, {
- row_id,
- })?.read?.includes(key)
- ) {
- has_access = true;
- }
- }
- if (has_access) {
- // ============================ SPC =================
- for (
- const [
- search_operator,
- search_operator_value,
- ] of Object.entries(value)
- ) {
- //NEED TO DO A NULL CHECK (ONLY WAY TO QUERY FOR NULL VALUES)
- if (search_operator_value === null && search_operator === "eq") {
- knexQuery.whereNull(`${table}.${key}`);
- } else if (
- search_operator_value === null &&
- search_operator === "neq"
- ) {
- knexQuery.whereNotNull(`${table}.${key}`);
- } else {
- if (
- this.schema?.[table]?.columns?.[key]?.type === "integer" &&
- GQLizerToKnexMappings[search_operator] === "ilike"
- ) {
- /**
- * if field type is integer but we use a like, cast the value to a string
- */
- knexQuery.whereRaw(
- [
- `"${table}"."${key}"` + "::varchar",
- GQLizerToKnexMappings[search_operator],
- `'${search_operator_value}'`,
- ].join(" "),
- );
- } else {
- knexQuery.where(
- `${table}.${key}`,
- GQLizerToKnexMappings[search_operator],
- search_operator_value,
- );
- }
- }
- }
- } else {
- // QUERY TO AUTOMATICALLY REMOVE ALL ROWS / IMPOSSIBLE QUERY
- throw new Error("You do not have access to this");
- }
- }
- }
- }
- return { builder: knexQuery, filters_applied: true };
- }
Advertisement
Add Comment
Please, Sign In to add comment