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;
}