static void command_schema_column_output_sources(grn_ctx *ctx, grn_obj *column) { grn_obj *source_table; grn_obj source_ids; unsigned int i, n_ids; source_table = grn_ctx_at(ctx, grn_obj_get_range(ctx, column)); GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); if (column->header.type == GRN_COLUMN_INDEX) { grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids); } n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id); grn_ctx_output_array_open(ctx, "sources", n_ids); for (i = 0; i < n_ids; i++) { grn_id source_id; grn_obj *source; source_id = GRN_RECORD_VALUE_AT(&source_ids, i); source = grn_ctx_at(ctx, source_id); grn_ctx_output_map_open(ctx, "source", 3); grn_ctx_output_cstr(ctx, "name"); if (grn_obj_is_table(ctx, source)) { grn_ctx_output_cstr(ctx, "_key"); } else { command_schema_output_column_name(ctx, source); } grn_ctx_output_cstr(ctx, "table"); command_schema_output_name(ctx, source_table); grn_ctx_output_cstr(ctx, "full_name"); if (grn_obj_is_table(ctx, source)) { char name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int name_size; name_size = grn_obj_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE); name[name_size] = '\0'; grn_strcat(name, GRN_TABLE_MAX_KEY_SIZE, "._key"); grn_ctx_output_cstr(ctx, name); } else { command_schema_output_name(ctx, source); } grn_ctx_output_map_close(ctx); } grn_ctx_output_array_close(ctx); GRN_OBJ_FIN(ctx, &source_ids); }
// <cmd> {<len> <column id>} <type> <#keys> [{<len> <key>}]... void hog_del(server_t *s, grn_ctx *ctx) { uint32_t len; receive(s->socket, &len, sizeof(len)); len = ntohl(len); char *buf = malloc(len); receive(s->socket, buf, len); grn_obj *col, *table; col = grn_ctx_get(ctx, buf, len); if(grn_obj_is_table(ctx, col)) table = col; else table = grn_column_table(ctx, col); // get key type char type; receive(s->socket, &type, 1); // submit values for each keys uint32_t nkeys; receive(s->socket, &nkeys, sizeof(nkeys)); nkeys = ntohl(nkeys); for(uint32_t i = 0; i < nkeys; ++i){ receive(s->socket, &len, sizeof(len)); len = ntohl(len); buf = realloc(buf, len); receive(s->socket, buf, len); ntoh_buf(buf, len, type); grn_table_delete(ctx, table, buf, len); } cleanup: free(buf); }
void test_is_table(gconstpointer data) { const gchar *name; grn_obj *object; assert_send_command("table_create Users TABLE_HASH_KEY ShortText"); assert_send_command("column_create Users name COLUMN_SCALAR ShortText"); name = gcut_data_get_string(data, "name"); object = grn_ctx_get(context, name, strlen(name)); if (gcut_data_get_string(data, "expected")) { cut_assert_true(grn_obj_is_table(context, object)); } else { cut_assert_false(grn_obj_is_table(context, object)); } }
// <cmd> {<len> <column id>} <types> <#kvs> [{<len> <key>} {<len> <value>}]... void put_or_set(server_t *s, grn_ctx *ctx, int set) { uint32_t len; HOG_RECV(s, &len, sizeof(len), return); len = ntohl(len); char *buf = hog_alloc(NULL, len); HOG_RECV(s, buf, len, goto cleanup); grn_obj *col, *table; col = grn_ctx_get(ctx, buf, len); if(grn_obj_is_table(ctx, col)) table = col; else table = grn_column_table(ctx, col); // get key and value types char types[2]; HOG_RECV(s, types, 2, goto cleanup); // receive keys and values uint32_t nkeys; HOG_RECV(s, &nkeys, sizeof(nkeys), goto cleanup); nkeys = ntohl(nkeys); grn_obj value; GRN_OBJ_INIT(&value, GRN_BULK, 0, types[1]); for(uint32_t i = 0; i < nkeys; ++i){ HOG_RECV(s, &len, sizeof(len), goto value_fin); len = ntohl(len); buf = hog_alloc(buf, len); HOG_RECV(s, buf, len, goto value_fin); ntoh_buf(buf, len, types[0]); grn_id id; if(set){ id = grn_table_get(ctx, table, buf, len); }else{ id = grn_table_add(ctx, table, buf, len, NULL); } HOG_RECV(s, &len, sizeof(len), goto value_fin); len = ntohl(len); buf = hog_alloc(buf, len); HOG_RECV(s, buf, len, goto value_fin); if(id == GRN_ID_NIL) continue; ntoh_buf(buf, len, types[1]); GRN_BULK_REWIND(&value); grn_bulk_write(ctx, &value, buf, len); grn_obj_set_value(ctx, col, id, &value, GRN_OBJ_SET); } submit_one(s->socket); value_fin: GRN_OBJ_FIN(ctx, &value); cleanup: free(buf); }
static mrb_value indexable_index_ids(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *object; grn_hook_entry entry; int i; int n_indexes; mrb_value mrb_index_ids; grn_obj hook_data; object = DATA_PTR(self); if (grn_obj_is_key_accessor(ctx, object)) { object = grn_ctx_at(ctx, object->header.domain); } if (grn_obj_is_table(ctx, object)) { entry = GRN_HOOK_INSERT; } else if (grn_obj_is_column(ctx, object)) { entry = GRN_HOOK_SET; } else { return mrb_ary_new(mrb); } n_indexes = grn_obj_get_nhooks(ctx, object, entry); mrb_index_ids = mrb_ary_new_capa(mrb, n_indexes); GRN_TEXT_INIT(&hook_data, 0); for (i = 0; i < n_indexes; i++) { GRN_BULK_REWIND(&hook_data); grn_obj_get_hook(ctx, object, entry, i, &hook_data); if (GRN_BULK_VSIZE(&hook_data) == sizeof(grn_obj_default_set_value_hook_data)) { grn_obj_default_set_value_hook_data *data; data = (grn_obj_default_set_value_hook_data *)GRN_TEXT_VALUE(&hook_data); mrb_ary_push(mrb, mrb_index_ids, mrb_fixnum_value(data->target)); } } return mrb_index_ids; }
static void command_schema_output_type(grn_ctx *ctx, const char *type_label, grn_obj *type) { if (!type) { grn_ctx_output_null(ctx); return; } grn_ctx_output_map_open(ctx, type_label, 2); grn_ctx_output_cstr(ctx, "name"); command_schema_output_name(ctx, type); grn_ctx_output_cstr(ctx, "type"); if (grn_obj_is_table(ctx, type)) { grn_ctx_output_cstr(ctx, "reference"); } else { grn_ctx_output_cstr(ctx, "type"); } grn_ctx_output_map_close(ctx); }
static grn_rc sequential_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *query, uint32_t max_distance, uint32_t prefix_match_size, uint32_t max_expansion, int flags, grn_obj *res, grn_operator op) { grn_table_cursor *tc; char *sx = GRN_TEXT_VALUE(query); char *ex = GRN_BULK_CURR(query); if (op == GRN_OP_AND) { tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } else { tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } if (tc) { grn_id id; grn_obj value; score_heap *heap; int i, n; GRN_TEXT_INIT(&value, 0); heap = score_heap_open(ctx, SCORE_HEAP_SIZE); if (!heap) { grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); return GRN_NO_MEMORY_AVAILABLE; } while ((id = grn_table_cursor_next(ctx, tc))) { unsigned int distance = 0; grn_obj *domain; GRN_BULK_REWIND(&value); grn_obj_get_value(ctx, column, id, &value); domain = grn_ctx_at(ctx, ((&value))->header.domain); if ((&(value))->header.type == GRN_VECTOR) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { unsigned int length; const char *vector_value = NULL; length = grn_vector_get_element(ctx, &value, i, &vector_value, NULL, NULL); if (!prefix_match_size || (prefix_match_size > 0 && length >= prefix_match_size && !memcmp(sx, vector_value, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, (char *)vector_value, (char *)vector_value + length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else if ((&(value))->header.type == GRN_UVECTOR && grn_obj_is_table(ctx, domain)) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = grn_uvector_get_element(ctx, &value, i, NULL); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else { if (grn_obj_is_reference_column(ctx, column)) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = GRN_RECORD_VALUE(&value); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } else { if (!prefix_match_size || (prefix_match_size > 0 && GRN_TEXT_LEN(&value) >= prefix_match_size && !memcmp(sx, GRN_TEXT_VALUE(&value), prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, GRN_TEXT_VALUE(&value), GRN_BULK_CURR(&value), flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } } grn_obj_unlink(ctx, domain); } grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); for (i = 0; i < heap->n_entries; i++) { if (max_expansion > 0 && i >= max_expansion) { break; } { grn_posting posting; posting.rid = heap->nodes[i].id; posting.sid = 1; posting.pos = 0; posting.weight = max_distance - heap->nodes[i].score; grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op); } } grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op); score_heap_close(ctx, heap); } return GRN_SUCCESS; }
static void set_vector(grn_ctx *ctx, grn_obj *column, grn_id id, grn_obj *vector) { int n = GRN_UINT32_VALUE(vector); grn_obj buf, *v = vector + 1; grn_id range_id; grn_obj *range; range_id = DB_OBJ(column)->range; range = grn_ctx_at(ctx, range_id); if (grn_obj_is_table(ctx, range)) { GRN_RECORD_INIT(&buf, GRN_OBJ_VECTOR, range_id); while (n--) { grn_bool cast_failed = GRN_FALSE; grn_obj record, *element = v; if (range_id != element->header.domain) { GRN_RECORD_INIT(&record, 0, range_id); if (grn_obj_cast(ctx, element, &record, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &record; } if (!cast_failed) { GRN_UINT32_PUT(ctx, &buf, GRN_RECORD_VALUE(element)); } if (element == &record) { GRN_OBJ_FIN(ctx, element); } v = values_next(ctx, v); } } else { if (((struct _grn_type *)range)->obj.header.flags & GRN_OBJ_KEY_VAR_SIZE) { GRN_TEXT_INIT(&buf, GRN_OBJ_VECTOR); while (n--) { switch (v->header.domain) { case GRN_DB_TEXT : { grn_bool cast_failed = GRN_FALSE; grn_obj casted_element, *element = v; if (range_id != element->header.domain) { GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id); if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &casted_element; } if (!cast_failed) { grn_vector_add_element(ctx, &buf, GRN_TEXT_VALUE(element), GRN_TEXT_LEN(element), 0, element->header.domain); } if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); } break; } case GRN_JSON_LOAD_OPEN_BRACE : add_weight_vector(ctx, column, v, &buf); n -= GRN_UINT32_VALUE(v); break; default : ERR(GRN_INVALID_ARGUMENT, "array must contain string or object"); break; } v = values_next(ctx, v); } } else { grn_id value_size = ((grn_db_obj *)range)->range; GRN_VALUE_FIX_SIZE_INIT(&buf, GRN_OBJ_VECTOR, range_id); while (n--) { grn_bool cast_failed = GRN_FALSE; grn_obj casted_element, *element = v; if (range_id != element->header.domain) { GRN_OBJ_INIT(&casted_element, GRN_BULK, 0, range_id); if (grn_obj_cast(ctx, element, &casted_element, GRN_TRUE)) { cast_failed = GRN_TRUE; ERR_CAST(column, range, element); } element = &casted_element; } if (!cast_failed) { grn_bulk_write(ctx, &buf, GRN_TEXT_VALUE(element), value_size); } if (element == &casted_element) { GRN_OBJ_FIN(ctx, element); } v = values_next(ctx, v); } } } grn_obj_set_value(ctx, column, id, &buf, GRN_OBJ_SET); GRN_OBJ_FIN(ctx, &buf); }
static void command_schema_column_command_collect_arguments(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *arguments) { #define ADD(name_, value_) \ grn_vector_add_element(ctx, arguments, \ name_, strlen(name_), \ 0, GRN_DB_TEXT); \ grn_vector_add_element(ctx, arguments, \ value_, strlen(value_), \ 0, GRN_DB_TEXT) #define ADD_OBJECT_NAME(name_, object_) do { \ char object_name[GRN_TABLE_MAX_KEY_SIZE]; \ unsigned int object_name_size; \ object_name_size = grn_obj_name(ctx, object_, \ object_name, \ GRN_TABLE_MAX_KEY_SIZE); \ object_name[object_name_size] = '\0'; \ ADD(name_, object_name); \ } while (GRN_FALSE) ADD_OBJECT_NAME("table", table); { char column_name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int column_name_size; column_name_size = grn_column_name(ctx, column, column_name, GRN_TABLE_MAX_KEY_SIZE); column_name[column_name_size] = '\0'; ADD("name", column_name); } { grn_obj flags; GRN_TEXT_INIT(&flags, 0); grn_dump_column_create_flags(ctx, column->header.flags & ~GRN_OBJ_PERSISTENT, &flags); GRN_TEXT_PUTC(ctx, &flags, '\0'); ADD("flags", GRN_TEXT_VALUE(&flags)); GRN_OBJ_FIN(ctx, &flags); } { grn_obj *value_type; value_type = grn_ctx_at(ctx, grn_obj_get_range(ctx, column)); ADD_OBJECT_NAME("type", value_type); } if (column->header.type == GRN_COLUMN_INDEX) { grn_obj source_ids; unsigned int n_ids; GRN_RECORD_INIT(&source_ids, GRN_OBJ_VECTOR, GRN_ID_NIL); grn_obj_get_info(ctx, column, GRN_INFO_SOURCE, &source_ids); n_ids = GRN_BULK_VSIZE(&source_ids) / sizeof(grn_id); if (n_ids > 0) { grn_obj sources; unsigned int i; GRN_TEXT_INIT(&sources, 0); for (i = 0; i < n_ids; i++) { grn_id source_id; grn_obj *source; char name[GRN_TABLE_MAX_KEY_SIZE]; unsigned int name_size; source_id = GRN_RECORD_VALUE_AT(&source_ids, i); source = grn_ctx_at(ctx, source_id); if (grn_obj_is_table(ctx, source)) { grn_strcpy(name, GRN_TABLE_MAX_KEY_SIZE, "_key"); name_size = strlen(name); } else { name_size = grn_column_name(ctx, source, name, GRN_TABLE_MAX_KEY_SIZE); } if (i > 0) { GRN_TEXT_PUTC(ctx, &sources, ','); } GRN_TEXT_PUT(ctx, &sources, name, name_size); } GRN_TEXT_PUTC(ctx, &sources, '\0'); ADD("sources", GRN_TEXT_VALUE(&sources)); GRN_OBJ_FIN(ctx, &sources); } GRN_OBJ_FIN(ctx, &source_ids); } #undef ADD_OBJECT_NAME #undef ADD }