Ejemplo n.º 1
0
void
test_is_key_accessor(gconstpointer data)
{
  const gchar *name;
  grn_obj *table;
  grn_obj *object;

  assert_send_command("table_create Names TABLE_HASH_KEY ShortText");
  assert_send_command("table_create Users TABLE_HASH_KEY ShortText");
  assert_send_command("column_create Users name COLUMN_SCALAR Names");

  table = grn_ctx_get(context, "Users", -1);
  name = gcut_data_get_string(data, "name");
  object = grn_obj_column(context, table, name, strlen(name));
  if (gcut_data_get_string(data, "expected")) {
    cut_assert_true(grn_obj_is_key_accessor(context, object));
  } else {
    cut_assert_false(grn_obj_is_key_accessor(context, object));
  }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static grn_rc
selector_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *index,
                      int nargs, grn_obj **args,
                      grn_obj *res, grn_operator op)
{
  grn_rc rc = GRN_SUCCESS;
  grn_obj *target = NULL;
  grn_obj *obj;
  grn_obj *query;
  uint32_t max_distance = 1;
  uint32_t prefix_length = 0;
  uint32_t prefix_match_size = 0;
  uint32_t max_expansion = 0;
  int flags = 0;
  grn_bool use_sequential_search = GRN_FALSE;

  if ((nargs - 1) < 2) {
    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                     "fuzzy_search(): wrong number of arguments (%d ...)",
                     nargs - 1);
    rc = ctx->rc;
    goto exit;
  }
  obj = args[1];
  query = args[2];

  if (nargs == 4) {
    grn_obj *options = args[3];
    grn_hash_cursor *cursor;
    void *key;
    grn_obj *value;
    int key_size;

    if (options->header.type != GRN_TABLE_HASH_KEY) {
      GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                       "fuzzy_search(): "
                       "3rd argument must be object literal: <%.*s>",
                       (int)GRN_TEXT_LEN(options),
                       GRN_TEXT_VALUE(options));
      goto exit;
    }

    cursor = grn_hash_cursor_open(ctx, (grn_hash *)options,
                                  NULL, 0, NULL, 0,
                                  0, -1, 0);
    if (!cursor) {
      GRN_PLUGIN_ERROR(ctx, GRN_NO_MEMORY_AVAILABLE,
                       "fuzzy_search(): couldn't open cursor");
      goto exit;
    }
    while (grn_hash_cursor_next(ctx, cursor) != GRN_ID_NIL) {
      grn_hash_cursor_get_key_value(ctx, cursor, &key, &key_size,
                                    (void **)&value);

      if (key_size == 12 && !memcmp(key, "max_distance", 12)) {
        max_distance = GRN_UINT32_VALUE(value);
      } else if (key_size == 13 && !memcmp(key, "prefix_length", 13)) {
        prefix_length = GRN_UINT32_VALUE(value);
      } else if (key_size == 13 && !memcmp(key, "max_expansion", 13)) {
        max_expansion = GRN_UINT32_VALUE(value);
      } else if (key_size == 18 && !memcmp(key, "with_transposition", 18)) {
        if (GRN_BOOL_VALUE(value)) {
          flags |= GRN_TABLE_FUZZY_SEARCH_WITH_TRANSPOSITION;
        }
      } else {
        GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                         "invalid option name: <%.*s>",
                         key_size, (char *)key);
        grn_hash_cursor_close(ctx, cursor);
        goto exit;
      }
    }
    grn_hash_cursor_close(ctx, cursor);
  }

  if (index) {
    target = index;
  } else {
    if (obj->header.type == GRN_COLUMN_INDEX) {
      target = obj;
    } else {
      grn_column_index(ctx, obj, GRN_OP_FUZZY, &target, 1, NULL);
    }
  }

  if (target) {
    grn_obj *lexicon;
    use_sequential_search = GRN_TRUE;
    lexicon = grn_ctx_at(ctx, target->header.domain);
    if (lexicon) {
      if (lexicon->header.type == GRN_TABLE_PAT_KEY) {
        use_sequential_search = GRN_FALSE;
      }
      grn_obj_unlink(ctx, lexicon);
    }
  } else {
    if (grn_obj_is_key_accessor(ctx, obj) &&
        table->header.type == GRN_TABLE_PAT_KEY) {
      target = table;
    } else {
      use_sequential_search = GRN_TRUE;
    }
  }

  if (prefix_length) {
    const char *s = GRN_TEXT_VALUE(query);
    const char *e = GRN_BULK_CURR(query);
    const char *p;
    unsigned int cl = 0;
    unsigned int length = 0;
    for (p = s; p < e && (cl = grn_charlen(ctx, p, e)); p += cl) {
      length++;
      if (length > prefix_length) {
        break;
      }
    }
    prefix_match_size = p - s;
  }

  if (use_sequential_search) {
    rc = sequential_fuzzy_search(ctx, table, obj, query,
                                 max_distance, prefix_match_size,
                                 max_expansion, flags, res, op);
    goto exit;
  }

  if (!target) {
    grn_obj inspected;
    GRN_TEXT_INIT(&inspected, 0);
    grn_inspect(ctx, &inspected, target);
    GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT,
                     "fuzzy_search(): "
                     "column must be COLUMN_INDEX or TABLE_PAT_KEY: <%.*s>",
                     (int)GRN_TEXT_LEN(&inspected),
                     GRN_TEXT_VALUE(&inspected));
    rc = ctx->rc;
    GRN_OBJ_FIN(ctx, &inspected);
  } else {
    grn_search_optarg options = {0};
    options.mode = GRN_OP_FUZZY;
    options.fuzzy.prefix_match_size = prefix_match_size;
    options.fuzzy.max_distance = max_distance;
    options.fuzzy.max_expansion = max_expansion;
    options.fuzzy.flags = flags;
    grn_obj_search(ctx, target, query, res, op, &options);
  }

exit :
  return rc;
}