static void cg_objc_proc_result_set()

in sources/cg_objc.c [243:484]


static void cg_objc_proc_result_set(ast_node *ast) {
  Contract(is_ast_create_proc_stmt(ast));
  Contract(is_struct(ast->sem->sem_type));
  EXTRACT_NOTNULL(proc_params_stmts, ast->right);
  EXTRACT(params, proc_params_stmts->left);
  EXTRACT_STRING(name, ast->left);
  EXTRACT_MISC_ATTRS(ast, misc_attrs);

  // if getters are suppressed the entire class is moot
  // if result set is suppressed the entire class is moot
  // private implies result set suppressed so also moot
  bool_t suppressed =
    exists_attribute_str(misc_attrs, "suppress_getters") ||
    exists_attribute_str(misc_attrs, "suppress_result_set") ||
    exists_attribute_str(misc_attrs, "private");

  if (suppressed) {
    return;
  }

  Invariant(!use_encode);
  Invariant(!encode_context_column);
  Invariant(!encode_columns);
  encode_columns = symtab_new();
  init_encode_info(misc_attrs, &use_encode, &encode_context_column, encode_columns);

  Invariant(objc_frag_type != FRAG_TYPE_SHARED);
  Invariant(objc_frag_type != FRAG_TYPE_EXTENSION);

  bool_t custom_type_for_encoded_column = !!exists_attribute_str(misc_attrs, "custom_type_for_encoded_column");
  CSTR c_result_set_name = name;
  charbuf *h = cg_header_output;

  CG_CHARBUF_OPEN_SYM(objc_name, name);
  CG_CHARBUF_OPEN_SYM(objc_result_set_name, c_result_set_name);
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(c_name, rt->impl_symbol_prefix, name);

  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(c_result_set, rt->impl_symbol_prefix, c_result_set_name, "_result_set");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(
    c_result_set_ref, rt->impl_symbol_prefix, c_result_set_name, "_result_set_ref");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(c_convert, "", c_name.ptr, "_from_", objc_name.ptr);

  CSTR classname = objc_name.ptr;

  bprintf(h, "\n@class %s;\n", classname);
  bprintf(h, "\n#ifdef CQL_EMIT_OBJC_INTERFACES\n");
  bprintf(h, "@interface %s\n", classname);
  bprintf(h, "@end\n");
  bprintf(h, "#endif\n");

  // Since the parent assembly query has already fetched the aggregated resultSet, we call to use that directly and
  // skip setting up objc and c bridging for extension fragment specific result unless otherwise

  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(objc_convert, "", objc_name.ptr, "_from_", c_name.ptr);

  bprintf(h, "\nstatic inline %s *%s(%s resultSet)\n", objc_name.ptr, objc_convert.ptr, c_result_set_ref.ptr);
  bprintf(h, "{\n");
  bprintf(h, "  return (__bridge %s *)resultSet;\n", objc_name.ptr);
  bprintf(h, "}\n");

  CHARBUF_CLOSE(objc_convert);

  bprintf(
    h,
    "\nstatic inline %s %s(%s *resultSet)\n",
    c_result_set_ref.ptr,
    c_convert.ptr,
    objc_name.ptr);

  bprintf(h, "{\n");
  bprintf(h, "  return (__bridge %s)resultSet;\n", c_result_set_ref.ptr);
  bprintf(h, "}\n");

  bool_t out_stmt_proc = has_out_stmt_result(ast);
  // extension fragments use SELECT and are incompatible with the single row result set form using OUT

  sem_struct *sptr = ast->sem->sptr;
  uint32_t count = sptr->count;
  for (uint32_t i = 0; i < count; i++) {
    sem_t sem_type = sptr->semtypes[i];
    CSTR col = sptr->names[i];
    cg_objc_proc_result_set_getter(
      out_stmt_proc,
      name,
      col,
      objc_name.ptr,
      c_result_set_ref.ptr,
      c_convert.ptr,
      i,
      sem_type,
      h,
      should_encode_col(col, sem_type, use_encode, encode_columns),
      custom_type_for_encoded_column);
  }

  if (use_encode) {
    for (uint32_t i = 0; i < count; i++) {
      CSTR col = sptr->names[i];
      sem_t sem_type = sptr->semtypes[i];
      bool_t encode = should_encode_col(col, sem_type, use_encode, encode_columns);
      if (encode) {
        CG_CHARBUF_OPEN_SYM_WITH_PREFIX(
            objc_getter, objc_name.ptr, "_get_", col, "_is_encoded");
        CG_CHARBUF_OPEN_SYM_WITH_PREFIX(
            c_getter, c_name.ptr, "_get_", col, "_is_encoded");

        bprintf(h,
            "\nstatic inline %s %s(%s *resultSet)\n",
            rt->cql_bool,
            objc_getter.ptr,
            objc_result_set_name.ptr);
        bprintf(h, "{\n");
        bprintf(h, "  return %s(%s(resultSet));\n", c_getter.ptr, c_convert.ptr);
        bprintf(h, "}\n");

        CHARBUF_CLOSE(c_getter);
        CHARBUF_CLOSE(objc_getter);
      }
    }

    // Add a helper function that overrides CQL_DATA_TYPE_ENCODED bit of a resultset.
    // It's a debugging function that allow you to turn ON/OFF encoding/decoding when
    // your app is running.
    bprintf(h,
            "\nstatic inline void %sSetEncoding(%s col, %s encode)\n",
            objc_name.ptr,
            rt->cql_int32,
            rt->cql_bool);
    bprintf(h, "{\n");
    bprintf(h, "  return %sSetEncoding(col, encode);\n", c_name.ptr);
    bprintf(h, "}\n");
  }

  CG_CHARBUF_OPEN_SYM(cgs_result_count, name, "_result_count");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(result_count, rt->impl_symbol_prefix, name, "_result_count");

  bprintf(h,
          "\nstatic inline %s %s(%s *resultSet)\n",
          rt->cql_int32,
          cgs_result_count.ptr,
          objc_result_set_name.ptr);


  bprintf(h, "{\n");
  bprintf(h, "  return %s(%s(resultSet));\n", result_count.ptr, c_convert.ptr);
  bprintf(h, "}\n");

  CHARBUF_CLOSE(result_count);
  CHARBUF_CLOSE(cgs_result_count);

  CG_CHARBUF_OPEN_SYM(cgs_copy_func_name, name, "_copy");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(copy_func_name, rt->impl_symbol_prefix, name, "_copy");

  bool_t generate_copy = misc_attrs && exists_attribute_str(misc_attrs, "generate_copy");
  if (generate_copy) {
    bprintf(h,
            "\nstatic inline %s *%s(%s *resultSet",
            objc_result_set_name.ptr,
            cgs_copy_func_name.ptr,
            objc_result_set_name.ptr);
    if (!out_stmt_proc) {
      bprintf(h,
              ", %s from, %s count",
              rt->cql_int32,
              rt->cql_int32);
    }
    bprintf(h, ")\n");
    bprintf(h, "{\n");
    bprintf(h, "  %s copy;\n", c_result_set_ref.ptr);
    bprintf(h,
            "  %s(%s(resultSet), &copy%s);\n",
            copy_func_name.ptr,
            c_convert.ptr,
            out_stmt_proc ? "" : ", from, count");
    bprintf(h, "  %s(copy);\n", rt->cql_result_set_note_ownership_transferred);
    bprintf(h, "  return (__bridge_transfer %s *)copy;\n", objc_name.ptr);
    bprintf(h, "}\n");
  }

  CHARBUF_CLOSE(copy_func_name);
  CHARBUF_CLOSE(cgs_copy_func_name);

  CSTR opt_row = out_stmt_proc ? "" : "_row";
  CG_CHARBUF_OPEN_SYM(cgs_hash_func_name, name, opt_row, "_hash");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(hash_func_name, rt->impl_symbol_prefix, name, opt_row, "_hash");
  CG_CHARBUF_OPEN_SYM(cgs_eq_func_name, name, opt_row, "_equal");
  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(eq_func_name, rt->impl_symbol_prefix, name, opt_row, "_equal");

  bprintf(h,
          "\nstatic inline NSUInteger %s(%s *resultSet",
          cgs_hash_func_name.ptr,
          objc_name.ptr);
  if (!out_stmt_proc) {
    bprintf(h, ", %s row", rt->cql_int32);
  }
  bprintf(h, ")\n");
  bprintf(h, "{\n");
  bprintf(h,
          "  return %s(%s(resultSet)%s);\n",
          hash_func_name.ptr,
          c_convert.ptr,
          out_stmt_proc ? "" : ", row");
  bprintf(h, "}\n");

  bprintf(h,
          "\nstatic inline BOOL %s(%s *resultSet1",
          cgs_eq_func_name.ptr,
          objc_name.ptr);
  if (!out_stmt_proc) {
    bprintf(h, ", %s row1", rt->cql_int32);
  }
  bprintf(h, ", %s *resultSet2", objc_name.ptr);
  if (!out_stmt_proc) {
    bprintf(h, ", %s row2", rt->cql_int32);
  }
  bprintf(h, ")\n");
  bprintf(h, "{\n");
  bprintf(h,
          "  return %s(%s(resultSet1)%s, %s(resultSet2)%s);\n",
          eq_func_name.ptr,
          c_convert.ptr,
          out_stmt_proc ? "" : ", row1",
          c_convert.ptr,
          out_stmt_proc ? "" : ", row2");
  bprintf(h, "}\n");

  CHARBUF_CLOSE(eq_func_name);
  CHARBUF_CLOSE(cgs_eq_func_name);
  CHARBUF_CLOSE(hash_func_name);
  CHARBUF_CLOSE(cgs_hash_func_name);
  CHARBUF_CLOSE(c_convert);
  CHARBUF_CLOSE(c_result_set_ref);
  CHARBUF_CLOSE(c_result_set);
  CHARBUF_CLOSE(c_name);
  CHARBUF_CLOSE(objc_result_set_name);
  CHARBUF_CLOSE(objc_name);

  use_encode = 0;
  symtab_delete(encode_columns);
  encode_columns = NULL;
  encode_context_column = NULL;
}