static void cg_objc_proc_result_set_getter()

in sources/cg_objc.c [60:241]


static void cg_objc_proc_result_set_getter(
  bool_t fetch_proc,
  CSTR name,
  CSTR col_name,
  CSTR objc_name,
  CSTR c_result_set_ref,
  CSTR c_convert,
  uint32_t col,
  sem_t sem_type,
  charbuf *output,
  bool_t encode,
  bool_t custom_type_for_encoded_column)
{
  Contract(is_unitary(sem_type));
  sem_t core_type = core_type_of(sem_type);
  Contract(core_type != SEM_TYPE_NULL);
  Contract(cg_main_output);

  bool_t nullable = is_nullable(sem_type);
  CHARBUF_OPEN(return_type);
  CSTR return_type_separator = "";

  CHARBUF_OPEN(value_convert_begin);
  CSTR value_convert_end = "";
  CSTR c_getter_suffix = "";

  uint32_t col_count_for_base = 0;

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

  bool_t is_asm_frag = objc_frag_type == FRAG_TYPE_ASSEMBLY;

  if (objc_frag_type != FRAG_TYPE_NONE) {
    // we already know the base compiled with no errors
    ast_node *base_proc = find_base_fragment(base_fragment_name);
    Invariant(base_proc);
    Invariant(base_proc->sem);
    Invariant(base_proc->sem->sptr);

    col_count_for_base = base_proc->sem->sptr->count;
  }

  bool_t is_private = col >= col_count_for_base && col_count_for_base > 0
    && is_asm_frag;

  CHARBUF_OPEN(value);

  if (nullable) {
    switch (core_type) {
      case SEM_TYPE_INTEGER:
      case SEM_TYPE_LONG_INTEGER:
      case SEM_TYPE_REAL:
      case SEM_TYPE_BOOL:
        bprintf(&return_type, "%s", "NSNumber *_Nullable");
        return_type_separator = " ";
         bprintf(&value_convert_begin, "%s", "@(");
        value_convert_end = ")";
        c_getter_suffix = "_value";
        cg_objc_proc_result_set_c_getter(fetch_proc, &value, name, col_name, "_is_null", is_private);
        bprintf(&value, " ? nil : ");
        break;
      case SEM_TYPE_BLOB:
        bprintf(&return_type, "%s_Nullable", rt->cql_blob_ref);
        return_type_separator = " ";
        bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_blob_ref);
        break;
      case SEM_TYPE_TEXT:
        if (encode && custom_type_for_encoded_column) {
          is_string_column_encoded = 1;
          bprintf(&return_type, "%s *_Nullable", rt->cql_string_ref_encode);
          bprintf(&value_convert_begin, "(__bridge %s *)", rt->cql_string_ref_encode);
        } else {
          bprintf(&return_type, "%s_Nullable", rt->cql_string_ref);
          bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_string_ref);
        }
        return_type_separator = " ";
        break;
      case SEM_TYPE_OBJECT:
        bprintf(&return_type, "%s_Nullable", rt->cql_object_ref);
        return_type_separator = " ";
        bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_object_ref);
        break;
    }
  } else {
    switch (core_type) {
      case SEM_TYPE_INTEGER:
        return_type_separator = " ";
        bprintf(&return_type, "%s", rt->cql_int32);
        break;
      case SEM_TYPE_LONG_INTEGER:
        return_type_separator = " ";
        bprintf(&return_type, "%s", rt->cql_int64);
        break;
      case SEM_TYPE_REAL:
        return_type_separator = " ";
        bprintf(&return_type, "%s", rt->cql_double);
        break;
      case SEM_TYPE_BOOL:
        return_type_separator = " ";
        bprintf(&return_type, "%s", rt->cql_bool);
        value_convert_end = " ? YES : NO";
        break;
      case SEM_TYPE_TEXT:
        if (encode && custom_type_for_encoded_column) {
          is_string_column_encoded = 1;
          bprintf(&return_type, "%s", rt->cql_string_ref_encode);
          bprintf(&value_convert_begin, "(__bridge %s *)", rt->cql_string_ref_encode);
        } else {
          bprintf(&return_type, "%s", rt->cql_string_ref);
          bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_string_ref);
        }
        break;
      case SEM_TYPE_BLOB:
        bprintf(&return_type, "%s", rt->cql_blob_ref);
        bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_blob_ref);
        break;
      case SEM_TYPE_OBJECT:
        bprintf(&return_type, "%s", rt->cql_object_ref);
        return_type_separator = " ";
        bprintf(&value_convert_begin, "(__bridge %s)", rt->cql_object_ref);
        break;
    }
  }

  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(
    objc_getter,
    rt->symbol_prefix,
    name,
    "_get_",
    col_name);

  CG_CHARBUF_OPEN_SYM_WITH_PREFIX(c_getter,
                                  rt->impl_symbol_prefix,
                                  name,
                                  "_get_",
                                  col_name,
                                  c_getter_suffix);

  if (fetch_proc) {
    bprintf(&value, "%s%s(cResultSet)%s",
            value_convert_begin.ptr,
            c_getter.ptr,
            value_convert_end);
  }
  else {
    bprintf(&value, "%s%s(cResultSet, row)%s",
            value_convert_begin.ptr,
            c_getter.ptr,
            value_convert_end);
  }

  if (fetch_proc) {
    bprintf(output,
            "\nstatic inline %s%s%s(%s *resultSet)\n",
            return_type.ptr,
            return_type_separator,
            objc_getter.ptr,
            objc_name);
  }
  else {
    bprintf(output,
            "\nstatic inline %s%s%s(%s *resultSet, %s row)\n",
            return_type.ptr,
            return_type_separator,
            objc_getter.ptr,
            objc_name,
            rt->cql_int32);
  }

  bprintf(output, "{\n");
  
  bprintf(output, "  %s cResultSet = %s(resultSet);\n", c_result_set_ref, c_convert);
  bprintf(output, "  return %s;\n", value.ptr);
  bprintf(output, "}\n");

  CHARBUF_CLOSE(c_getter);
  CHARBUF_CLOSE(objc_getter);
  CHARBUF_CLOSE(value);
  CHARBUF_CLOSE(value_convert_begin);
  CHARBUF_CLOSE(return_type);
}