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), ©%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;
}