tree evaluate_impl (tree t) { //cout << "Really evaluate " << t << LF; switch (L(t)) { /* Typesetting primitives with side effects */ case DATOMS: return evaluate_formatting (t, ATOM_DECORATIONS); case DLINES: return evaluate_formatting (t, LINE_DECORATIONS); case DPAGES: return evaluate_formatting (t, PAGE_DECORATIONS); case TFORMAT: return evaluate_formatting (t, CELL_FORMAT); case TABLE: return evaluate_table (t); /* Primitives for macro expansion */ case ASSIGN: return evaluate_assign (t); case WITH: return evaluate_with (t); case PROVIDES: return evaluate_provides (t); case VALUE: return evaluate_value (t); case QUOTE_VALUE: return evaluate_quote_value (t); case MACRO: return copy (t); case DRD_PROPS: return evaluate_drd_props (t); #ifdef CLASSICAL_MACRO_EXPANSION case ARG: return evaluate_arg (t); case QUOTE_ARG: return evaluate_quote_arg (t); #endif case COMPOUND: return evaluate_compound (t); case XMACRO: return copy (t); case GET_LABEL: return evaluate_get_label (t); case GET_ARITY: return evaluate_get_arity (t); /* Primitives for quoting and evaluation */ case MAP_ARGS: return evaluate_rewrite (t); case EVAL_ARGS: return evaluate_eval_args (t); case MARK: return tree (MARK, copy (t[0]), evaluate (t[1])); case EXPAND_AS: return evaluate (t[1]); case EVAL: return evaluate (evaluate (t[0])); case QUOTE: return t[0]; case QUASI: return evaluate (evaluate_quasiquote (t[0])); case QUASIQUOTE: return evaluate_quasiquote (t[0]); case UNQUOTE: case VAR_UNQUOTE: return evaluate (t[0]); case COPY: return copy (evaluate (t[0])); /* Control structures */ case IF: case VAR_IF: return evaluate_if (t); case CASE: return evaluate_case (t); case WHILE: return evaluate_while (t); case FOR_EACH: return evaluate_for_each (t); case EXTERN: return evaluate_rewrite (t); case VAR_INCLUDE: return evaluate_include (t); case WITH_PACKAGE: return evaluate_rewrite (t); case USE_PACKAGE: return evaluate_use_package (t); case USE_MODULE: return evaluate_use_module (t); /* Computational markup */ case OR: return evaluate_or (t); case XOR: return evaluate_xor (t); case AND: return evaluate_and (t); case NOT: return evaluate_not (t); case PLUS: case MINUS: return evaluate_plus_minus (t); case TIMES: case OVER: return evaluate_times_over (t); case DIV: return evaluate_divide (t); case MOD: return evaluate_modulo (t); case MATH_SQRT: return evaluate_math_sqrt (t); case EXP: return evaluate_exp (t); case LOG: return evaluate_log (t); case POW: return evaluate_pow (t); case COS: return evaluate_cos (t); case SIN: return evaluate_sin (t); case TAN: return evaluate_tan (t); case MERGE: return evaluate_merge (t); case LENGTH: return evaluate_length (t); case RANGE: return evaluate_range (t); case NUMBER: return evaluate_number (t); case _DATE: return evaluate_date (t); case TRANSLATE: return evaluate_translate (t); case CHANGE_CASE: return evaluate_change_case (t); case FIND_FILE: return evaluate_find_file (t); case IS_TUPLE: return evaluate_is_tuple (t); case LOOK_UP: return evaluate_lookup (t); case EQUAL: return evaluate_equal (t); case UNEQUAL: return evaluate_unequal (t); case LESS: return evaluate_less (t); case LESSEQ: return evaluate_lesseq (t); case GREATER: return evaluate_greater (t); case GREATEREQ: return evaluate_greatereq (t); case BLEND: return evaluate_blend (t); /* Length units */ case CM_LENGTH: return evaluate_cm_length (); case MM_LENGTH: return evaluate_mm_length (); case IN_LENGTH: return evaluate_in_length (); case PT_LENGTH: return evaluate_pt_length (); case BP_LENGTH: return evaluate_bp_length (); case DD_LENGTH: return evaluate_dd_length (); case PC_LENGTH: return evaluate_pc_length (); case CC_LENGTH: return evaluate_cc_length (); case FS_LENGTH: return evaluate_fs_length (); case FBS_LENGTH: return evaluate_fbs_length (); case EM_LENGTH: return evaluate_em_length (); case LN_LENGTH: return evaluate_ln_length (); case SEP_LENGTH: return evaluate_sep_length (); case YFRAC_LENGTH: return evaluate_yfrac_length (); case EX_LENGTH: return evaluate_ex_length (); case FN_LENGTH: return evaluate_fn_length (); case FNS_LENGTH: return evaluate_fns_length (); case BLS_LENGTH: return evaluate_bls_length (); case FNBOT_LENGTH: return evaluate_fnbot_length (); case FNTOP_LENGTH: return evaluate_fntop_length (); case SPC_LENGTH: return evaluate_spc_length (); case XSPC_LENGTH: return evaluate_xspc_length (); case PAR_LENGTH: return evaluate_par_length (); case PAG_LENGTH: return evaluate_pag_length (); case GW_LENGTH: return evaluate_gw_length (); case GH_LENGTH: return evaluate_gh_length (); case GU_LENGTH: return evaluate_gu_length (); case TMPT_LENGTH: return evaluate_tmpt_length (); case PX_LENGTH: return evaluate_px_length (); case MSEC_LENGTH: return evaluate_msec_length (); case SEC_LENGTH: return evaluate_sec_length (); case MIN_LENGTH: return evaluate_min_length (); case HR_LENGTH: return evaluate_hr_length (); /* Primitives for stylesheet editing */ case STYLE_WITH: case VAR_STYLE_WITH: return evaluate (t[N(t)-1]); case STYLE_ONLY: case VAR_STYLE_ONLY: case ACTIVE: case VAR_ACTIVE: case INACTIVE: case VAR_INACTIVE: return evaluate_compound (t); case REWRITE_INACTIVE: return evaluate_rewrite (t); /* Linking primitives */ case HARD_ID: return evaluate_hard_id (t[0]); case SCRIPT: return evaluate_script (t); case HLINK: case ACTION: return evaluate_compound (t); case SET_BINDING: return evaluate_set_binding (t); case GET_BINDING: return evaluate_get_binding (t); /* Graphical primitives */ case PATTERN: return evaluate_pattern (t); case _POINT: return evaluate_point (t); /* case BOX_INFO: return evaluate_box_info (t); case FRAME_DIRECT: return evaluate_frame_direct (t); case FRAME_INVERSE: return evaluate_frame_inverse (t); */ /* User extensions */ default: if (L(t) < START_EXTENSIONS) { int i, n= N(t); tree r (t, n); for (i=0; i<n; i++) r[i]= evaluate (t[i]); transfer_ip (t, r); return r; } else { tree r= evaluate_compound (t); return r; } } }
nlohmann::json collection::query(nlohmann::json::object_t const& selector, nlohmann::json::object_t const& modifier, int flags) throw(ejdb_exception) { nlohmann::json q1 = selector; nlohmann::json q2 = modifier; bool with_modifier = !q2.empty(); if(with_modifier) { std::swap(q1, q2); } auto* ejdb_query = ejdbcreatequery(_db.get(), convert_to_bson(q1).get(), with_modifier ? convert_to_bson(q2).get() : nullptr, (int)with_modifier, nullptr); if(!ejdb_query) { throw_last_ejdb_exception(); } uint32_t count; std::shared_ptr<TCXSTR> log(tcxstrnew(), tcxstrdel); auto cursor = ejdbqryexecute(_coll.get(), ejdb_query, &count, flags, log.get()); ejdbquerydel(ejdb_query); nlohmann::json updates; nlohmann::json upserts; nlohmann::json dropall; nlohmann::json const json_log = evaluate_log(std::string(log->ptr, log->size)); if(json_log.find("updating_mode") != json_log.end() && json_log["updating_mode"]) { if(json_log.find("$update") != json_log.end()) { updates = json_log["$update"]; if(updates.type() != nlohmann::json::value_t::array) { updates = nlohmann::json::array_t({ updates }); } } if(json_log.find("$upsert") != json_log.end()) { upserts = json_log["$upsert"]; if(upserts.type() != nlohmann::json::value_t::array) { upserts = nlohmann::json::array_t({ upserts }); } for(nlohmann::json::object_t doc: upserts) { std::string const id = doc["_id"]; doc.erase("_id"); document_added(id, doc); } } if(json_log.find("$dropall") != json_log.end()) { for(std::string const& id: json_log["$dropall"]) { dropall.push_back(id); } } } nlohmann::json return_val; if(flags & JBQRYCOUNT) { return_val = count; } else { std::vector<nlohmann::json::object_t> results; results.reserve(count); for(int i = 0; i < count; ++i) { int data_size = 0; auto const& result = convert_to_json(std::shared_ptr<bson>(bson_create_from_buffer(static_cast<char const*>(ejdbqresultbsondata(cursor, i, &data_size)), data_size), bson_destroy)); if(i < updates.size()) { auto const& update = updates[i]; if(result != update) { auto const diff = modified_fields(result, update); document_pre_changed(result["_id"], result, update); document_changed(result["_id"], diff["fields"], diff["cleared"]); } } if(i < dropall.size()) { std::string const& id = dropall[i]; if(result["_id"] == id) { document_pre_removed(id, result); document_removed(id); } } results.push_back(result); } ejdbqresultdispose(cursor); return_val = results; } if(flags & JBQRYFINDONE) { return_val = return_val.empty() ? nlohmann::json::object() : return_val[0]; } return return_val; }