null+****@clear*****
null+****@clear*****
2010年 7月 14日 (水) 18:28:27 JST
Daijiro MORI 2010-07-14 09:28:27 +0000 (Wed, 14 Jul 2010) New Revision: bf348555c0a34d254069c0d99c6c796f451a9678 Log: check whether deletable or not in grn_table_delete(). Modified files: lib/db.c Modified: lib/db.c (+76 -43) =================================================================== --- lib/db.c 2010-07-14 06:02:01 +0000 (0b22830) +++ lib/db.c 2010-07-14 09:28:27 +0000 (3a5ccdd) @@ -1191,6 +1191,35 @@ clear_column_values(grn_ctx *ctx, grn_obj *table, grn_id rid) } } +static int +is_deletable(grn_ctx *ctx, grn_obj *table, grn_id id) +{ + int res = 1; + if (id) { + grn_hash *cols; + if ((cols = grn_hash_create(ctx, NULL, sizeof(grn_id), 0, + GRN_OBJ_TABLE_HASH_KEY|GRN_HASH_TINY))) { + if (grn_table_columns(ctx, table, "", 0, (grn_obj *)cols)) { + grn_id *key; + uint32_t esize; + GRN_HASH_EACH(ctx, cols, tid, &key, NULL, NULL, { + grn_obj *col = grn_ctx_at(ctx, *key); + if (col && col->header.type == GRN_COLUMN_INDEX && + (esize = grn_ii_estimate_size(ctx, (grn_ii *)col, id))) { + GRN_LOG(ctx, GRN_WARN, "undeletable record(%d:%d) has value (%d:%d)", + DB_OBJ(table)->id, id, *key, esize); + res = 0; + } + }); + } + grn_hash_close(ctx, cols); + } + } else { + res = 0; + } + return res; +} + grn_rc grn_table_delete(grn_ctx *ctx, grn_obj *table, const void *key, unsigned key_size) { @@ -1202,39 +1231,41 @@ grn_table_delete(grn_ctx *ctx, grn_obj *table, const void *key, unsigned key_siz rid = grn_table_get(ctx, table, key, key_size); call_delete_hook(ctx, table, rid, key, key_size); } - switch (table->header.type) { - case GRN_DB : - /* todo : delete tables and columns from db */ - break; - case GRN_TABLE_PAT_KEY : - WITH_NORMALIZE((grn_pat *)table, key, key_size, { - grn_pat *pat = (grn_pat *)table; - if (pat->io && !(pat->io->flags & GRN_IO_TEMPORARY)) { - if (!(rc = grn_io_lock(ctx, pat->io, 10000000))) { + if (is_deletable(ctx, table, rid)) { + switch (table->header.type) { + case GRN_DB : + /* todo : delete tables and columns from db */ + break; + case GRN_TABLE_PAT_KEY : + WITH_NORMALIZE((grn_pat *)table, key, key_size, { + grn_pat *pat = (grn_pat *)table; + if (pat->io && !(pat->io->flags & GRN_IO_TEMPORARY)) { + if (!(rc = grn_io_lock(ctx, pat->io, 10000000))) { + rc = grn_pat_delete(ctx, pat, key, key_size, NULL); + grn_io_unlock(pat->io); + } + } else { rc = grn_pat_delete(ctx, pat, key, key_size, NULL); - grn_io_unlock(pat->io); } - } else { - rc = grn_pat_delete(ctx, pat, key, key_size, NULL); - } - }); - break; - case GRN_TABLE_HASH_KEY : - WITH_NORMALIZE((grn_hash *)table, key, key_size, { - grn_hash *hash = (grn_hash *)table; - if (hash->io && !(hash->io->flags & GRN_IO_TEMPORARY)) { - if (!(rc = grn_io_lock(ctx, hash->io, 10000000))) { + }); + break; + case GRN_TABLE_HASH_KEY : + WITH_NORMALIZE((grn_hash *)table, key, key_size, { + grn_hash *hash = (grn_hash *)table; + if (hash->io && !(hash->io->flags & GRN_IO_TEMPORARY)) { + if (!(rc = grn_io_lock(ctx, hash->io, 10000000))) { + rc = grn_hash_delete(ctx, hash, key, key_size, NULL); + grn_io_unlock(hash->io); + } + } else { rc = grn_hash_delete(ctx, hash, key, key_size, NULL); - grn_io_unlock(hash->io); } - } else { - rc = grn_hash_delete(ctx, hash, key, key_size, NULL); - } - }); - break; + }); + break; + } + clear_column_values(ctx, table, rid); + grn_obj_touch(ctx, table, NULL); } - clear_column_values(ctx, table, rid); - grn_obj_touch(ctx, table, NULL); } GRN_API_RETURN(rc); } @@ -1247,22 +1278,24 @@ _grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id, if (table) { const void *key; unsigned key_size; - if ((key = _grn_table_key(ctx, table, id, &key_size))) { - call_delete_hook(ctx, table, id, key, key_size); - } - // todo : support optarg - switch (table->header.type) { - case GRN_TABLE_PAT_KEY : - rc = grn_pat_delete_by_id(ctx, (grn_pat *)table, id, optarg); - break; - case GRN_TABLE_HASH_KEY : - rc = grn_hash_delete_by_id(ctx, (grn_hash *)table, id, optarg); - break; - case GRN_TABLE_NO_KEY : - rc = grn_array_delete_by_id(ctx, (grn_array *)table, id, optarg); - break; + if (is_deletable(ctx, table, id)) { + if ((key = _grn_table_key(ctx, table, id, &key_size))) { + call_delete_hook(ctx, table, id, key, key_size); + } + // todo : support optarg + switch (table->header.type) { + case GRN_TABLE_PAT_KEY : + rc = grn_pat_delete_by_id(ctx, (grn_pat *)table, id, optarg); + break; + case GRN_TABLE_HASH_KEY : + rc = grn_hash_delete_by_id(ctx, (grn_hash *)table, id, optarg); + break; + case GRN_TABLE_NO_KEY : + rc = grn_array_delete_by_id(ctx, (grn_array *)table, id, optarg); + break; + } + clear_column_values(ctx, table, id); } - clear_column_values(ctx, table, id); } return rc; }