Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add serialize_where.py #7

Closed
Konard opened this issue May 5, 2023 · 1 comment
Closed

Add serialize_where.py #7

Konard opened this issue May 5, 2023 · 1 comment
Labels

Comments

@Konard
Copy link
Member

Konard commented May 5, 2023

export const serializeWhere = (exp: any, env: string = 'links'): any => {
  if (Object.prototype.toString.call(exp) === '[object Array]') return exp.map((e) => serializeWhere(e, env));
  else if (typeof(exp) === 'object') {
    const keys = Object.keys(exp);
    const result: any = {};
    for (let k = 0; k < keys.length; k++) {
      const key = keys[k];
      const type = typeof(exp[key]);
      let setted: any = false;
      const is_id_field = !!~['type_id', 'from_id', 'to_id'].indexOf(key);
      if (env === 'links') {
        if (type === 'string' || type === 'number') {
          if (key === 'value' || key === type) {
            setted = result[type] = { value: { _eq: exp[key] } };
          } else {
            setted = result[key] = { _eq: exp[key] };
          }
        } else if (!_boolExpFields[key] && Object.prototype.toString.call(exp[key]) === '[object Array]') {
          setted = result[key] = serializeWhere(pathToWhere(...exp[key]));
        }
      } else if (env === 'value') {
        if (type === 'string' || type === 'number') {
          setted = result[key] = { _eq: exp[key] };
        }
      }
      if (type === 'object' && exp[key].hasOwnProperty('_type_of') && (
        (env === 'links' && (is_id_field || key === 'id')) ||
        (env === 'selector' && key === 'item_id') ||
        (env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
        (env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
        (env === 'value' && key === 'link_id')
      )) {
        const _temp = setted = { _by_item: { path_item_id: { _eq: exp[key]._type_of }, group_id: { _eq: 0 } } };
        if (key === 'id') {
          result._and = result._and ? [...result._and, _temp] : [_temp];
        } else {
          result[key.slice(0, -3)] = _temp;
        }
      } else if (type === 'object' && exp[key].hasOwnProperty('_id') && (
        (env === 'links' && (is_id_field || key === 'id')) ||
        (env === 'selector' && key === 'item_id') ||
        (env === 'can' && !!~['rule_id', 'action_id', 'subject_id', 'object_id',].indexOf(key)) ||
        (env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) ||
        (env === 'value' && key === 'link_id')
      ) && Object.prototype.toString.call(exp[key]._id) === '[object Array]' && exp[key]._id.length >= 1) {
        const _temp = setted = serializeWhere(pathToWhere(exp[key]._id[0], ...exp[key]._id.slice(1)), 'links');
        if (key === 'id') {
          result._and = result._and ? [...result._and, _temp] : [_temp];
        } else {
          result[key.slice(0, -3)] = _temp;
        }
      }
      if (!setted) {
        const _temp = (
          _boolExpFields[key]
        ) ? (
          serializeWhere(exp[key], env)
         ) : (
          _serialize?.[env]?.relations?.[key]
        ) ? (
          serializeWhere(exp[key], _serialize?.[env]?.relations?.[key])
        ) : (
          exp[key]
        );
        if (key === '_and') result._and ? result._and.push(..._temp) : result._and = _temp;
        else result[key] = _temp;
      }
    }
    return result;
  } else {
    if (typeof(exp) === 'undefined') throw new Error('undefined in query');
    return exp;
  }
};

Translate this code to python and put it into serialize_where.py file

@Konard
Copy link
Member Author

Konard commented May 5, 2023

Doing the same manually in GPT-4 chat:

from typing import Any, Union
from collections.abc import Iterable

_boolExpFields = {}  # Assuming this is a global variable in your JavaScript code
_serialize = {}  # Assuming this is a global variable in your JavaScript code


def serialize_where(exp: Any, env: str = 'links') -> Any:
    if isinstance(exp, list):
        return [serialize_where(e, env) for e in exp]
    elif isinstance(exp, dict):
        keys = exp.keys()
        result = {}
        for key in keys:
            key_type = type(exp[key])
            setted = False
            is_id_field = key in ['type_id', 'from_id', 'to_id']
            if env == 'links':
                if key_type in (str, int):
                    if key == 'value' or key == key_type.__name__:
                        setted = result[key_type.__name__] = {'value': {'_eq': exp[key]}}
                    else:
                        setted = result[key] = {'_eq': exp[key]}
                elif key not in _boolExpFields and isinstance(exp[key], list):
                    setted = result[key] = serialize_where(path_to_where(*exp[key]))
            elif env == 'value':
                if key_type in (str, int):
                    setted = result[key] = {'_eq': exp[key]}

            ids = [
                'rule_id', 'action_id', 'subject_id', 'object_id',
                'link_id', 'tree_id', 'root_id', 'parent_id'
            ]
            if (
                key_type == dict
                and '_type_of' in exp[key]
                and (
                    (env == 'links' and (is_id_field or key == 'id')) or
                    (env == 'selector' and key == 'item_id') or
                    (env == 'can' and key in ids) or
                    (env == 'tree' and key in ids) or
                    (env == 'value' and key == 'link_id')
                )
            ):
                _temp = setted = {
                    '_by_item': {
                        'path_item_id': {'_eq': exp[key]['_type_of']},
                        'group_id': {'_eq': 0}
                    }
                }
                if key == 'id':
                    result['_and'] = [*result.get('_and', []), _temp]
                else:
                    result[key[:-3]] = _temp
            elif (
                key_type == dict
                and '_id' in exp[key]
                and (
                    (env == 'links' and (is_id_field or key == 'id')) or
                    (env == 'selector' and key == 'item_id') or
                    (env == 'can' and key in ids) or
                    (env == 'tree' and key in ids) or
                    (env == 'value' and key == 'link_id')
                )
                and isinstance(exp[key]['_id'], list)
                and len(exp[key]['_id']) >= 1
            ):
                _temp = setted = serialize_where(
                    path_to_where(exp[key]['_id'][0], *exp[key]['_id'][1:]), 'links'
                )
                if key == 'id':
                    result['_and'] = [*result.get('_and', []), _temp]
                else:
                    result[key[:-3]] = _temp

            if not setted:
                _temp = (
                    serialize_where(exp[key], env) if key in _boolExpFields else (
                        serialize_where(exp[key], _serialize.get(env, {}).get('relations', {}).get(key))
                    if _serialize.get(env, {}).get('relations', {}).get(key) else exp[key]
                )
            )
            if key == '_and':
                if '_and' in result:
                    result['_and'].extend(_temp)
                else:
                    result['_and'] = _temp
            else:
                result[key] = _temp
    return result
else:
    if exp is None:
        raise ValueError('undefined in query')
    return exp

@Konard Konard closed this as completed in fedc34c May 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant