[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug-recutils] [PATCH 08/13] utils: add recfix -- add-index command.
From: |
Michał Masłowski |
Subject: |
[bug-recutils] [PATCH 08/13] utils: add recfix -- add-index command. |
Date: |
Mon, 20 Aug 2012 18:21:29 +0200 |
It's the only recfix command working on a single type only, parts of
recutl.h record selection code are copied for this option.
---
ChangeLog | 12 +++
utils/recfix.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 238 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2df5fca..bef69c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2012-08-18 Michał Masłowski <address@hidden>
+ utils: add recfix --add-index command.
+ * utils/recfix.c (recfix_op): Add RECFIX_OP_ADD_INDEX.
+ (recfix_type): New global variable.
+ (recfix_index_fields): Likewise.
+ (GNU_longOptions): Add --add-index and --type.
+ (recutl_print_help): Document --add-index and --type.
+ (recfix_parse_args): Handle --add-index and --type.
+ (recfix_do_add_index): New function.
+ (main): Handle --add-index.
+
+2012-08-18 Michał Masłowski <address@hidden>
+
src: fix index range checks.
* src/rec-idx-file.c (rec_idx_file_index): Check if the end of the
index is after the end of buffer, not after the start.
diff --git a/utils/recfix.c b/utils/recfix.c
index 840a52d..bd0c384 100644
--- a/utils/recfix.c
+++ b/utils/recfix.c
@@ -47,6 +47,7 @@ static int recfix_do_crypt (void);
#endif
static int recfix_do_auto (void);
static int recfix_do_build_index (void);
+static int recfix_do_add_index (void);
/*
* Data types.
@@ -65,7 +66,8 @@ enum recfix_op
#endif
RECFIX_OP_SORT,
RECFIX_OP_AUTO,
- RECFIX_OP_BUILD_INDEX
+ RECFIX_OP_BUILD_INDEX,
+ RECFIX_OP_ADD_INDEX
};
/*
@@ -77,6 +79,8 @@ char *recfix_file = NULL;
int recfix_op = RECFIX_OP_INVALID;
char *recfix_password = NULL;
bool recfix_force = false;
+char *recfix_type = NULL;
+rec_fex_t recfix_index_fields = NULL;
/*
* Command line options management.
@@ -95,7 +99,9 @@ enum
#endif
OP_CHECK_ARG,
OP_AUTO_ARG,
- OP_BUILD_INDEX_ARG
+ OP_BUILD_INDEX_ARG,
+ OP_ADD_INDEX_ARG,
+ TYPE_ARG
};
static const struct option GNU_longOptions[] =
@@ -112,6 +118,8 @@ static const struct option GNU_longOptions[] =
#endif
{"auto", no_argument, NULL, OP_AUTO_ARG},
{"build-index", no_argument, NULL, OP_BUILD_INDEX_ARG},
+ {"add-index", required_argument, NULL, OP_ADD_INDEX_ARG},
+ {"type", required_argument, NULL, TYPE_ARG},
{NULL, 0, NULL, 0}
};
@@ -147,7 +155,8 @@ Operations:\n\
--check check integrity of the specified file.
Default.\n\
--sort sort the records in the specified
file.\n\
--auto insert auto-generated fields in records
missing them.\n\
- --build-index build the index file for the specified
file.\n"),
+ --build-index build the index file for the specified
file.\n\
+ --add-index=FIELD,... add an index for specified fields.\n"),
stdout);
#if defined REC_CRYPT_SUPPORT
@@ -169,6 +178,12 @@ De/Encryption options:\n\
#endif /* REC_CRYPT_SUPPORT */
puts("");
+ fputs (_("\
+Index options:\n\
+ -t, --type=TYPE add the index for records of the
specified type.\n"),
+ stdout);
+
+ puts("");
/* TRANSLATORS: --help output, notes on recfix.
no-wrap */
fputs (_("\
@@ -188,7 +203,7 @@ recfix_parse_args (int argc,
while ((ret = getopt_long (argc,
argv,
- ENCRYPTION_SHORT_ARGS,
+ ENCRYPTION_SHORT_ARGS "t:",
GNU_longOptions,
NULL)) != -1)
{
@@ -270,6 +285,39 @@ recfix_parse_args (int argc,
recfix_op = RECFIX_OP_BUILD_INDEX;
break;
}
+ case TYPE_ARG:
+ case 't':
+ {
+ recfix_type = xstrdup (optarg);
+ if (!rec_field_name_p (recfix_type))
+ {
+ recutl_fatal ("invalid record type %s\n",
+ recfix_type);
+ }
+ break;
+ }
+ case OP_ADD_INDEX_ARG:
+ {
+ if (recfix_op != RECFIX_OP_INVALID)
+ {
+ recutl_fatal (_("please specify just one operation.\n"));
+ }
+
+ recfix_op = RECFIX_OP_ADD_INDEX;
+
+ /* Parse the field names. */
+ if (!rec_fex_check (optarg, REC_FEX_CSV))
+ {
+ recutl_fatal (_("invalid field names in --add-index.\n"));
+ }
+
+ recfix_index_fields = rec_fex_new (optarg, REC_FEX_CSV);
+ if (!recfix_index_fields)
+ {
+ recutl_fatal (_("internal error creating fex.\n"));
+ }
+ break;
+ }
#if defined REC_CRYPT_SUPPORT
case OP_ENCRYPT_ARG:
{
@@ -790,6 +838,175 @@ recfix_do_build_index (void)
return res ? EXIT_SUCCESS : EXIT_FAILURE;
}
+static int
+recfix_do_add_index (void)
+{
+ FILE *recfile, *idx = NULL;
+ rec_db_t db;
+ int64_t time, index_type;
+ size_t size, index_size, n_fields, n, rset_number;
+ char *index_name;
+ rec_idx_file_t idx_file = NULL;
+ bool res = true;
+ uint8_t *index_data = NULL;
+ rec_rset_t rset;
+ const char **field_names, *rset_type;
+ rec_idx_tree_key_t *field_types;
+ rec_fex_elem_t fex_elem;
+
+ if (!recfix_file)
+ {
+ recutl_fatal (_("a file name is required"));
+ }
+
+ /* Read the database. */
+ db = rec_db_new ();
+ if (!db)
+ {
+ return EXIT_FAILURE;
+ }
+
+ recfile = fopen (recfix_file, "r");
+ if (!recfile || !recutl_parse_db_from_file (recfile, recfix_file, db))
+ {
+ res = false;
+ }
+
+ /* Get its metadata. */
+ if (res && !rec_idx_get_time_size (recfile, &time, &size))
+ {
+ res = false;
+ }
+
+ if (recfile)
+ {
+ fclose (recfile);
+ }
+
+ /* Get the rset. */
+ if (recfix_type)
+ {
+ for (rset_number = 0; rset_number < rec_db_size (db); rset_number++)
+ {
+ rset = rec_db_get_rset (db, rset_number);
+ rset_type = rec_rset_type (rset);
+ if ((rset_type != NULL) && !strcmp (rset_type, recfix_type))
+ {
+ break;
+ }
+ }
+
+ if (rset_number == rec_db_size (db))
+ {
+ recutl_fatal (_("unknown record type: %s.\n"), recfix_type);
+ }
+ }
+ else if (rec_db_size (db) == 1)
+ {
+ rset_number = 0;
+ rset = rec_db_get_rset (db, 0);
+ }
+ else
+ {
+ recutl_fatal (_("several record types found. Please use -t to specify
one.\n"));
+ }
+
+ /* Get the index file name. */
+ if (res)
+ {
+ index_name = rec_idx_get_file_name (recfix_file);
+ if (!index_name)
+ {
+ res = false;
+ }
+ }
+
+ /* Open the index file for read and write. */
+ if (res)
+ {
+ idx = fopen (index_name, "r+b");
+ if (idx)
+ {
+ idx_file = rec_idx_file_new (idx);
+ }
+ }
+
+ if (!idx_file)
+ {
+ res = false;
+ }
+
+ /* Construct key type data. */
+ if (res)
+ {
+ n_fields = rec_fex_size (recfix_index_fields);
+ field_names = malloc (sizeof (*field_names) * n_fields);
+ field_types = malloc (sizeof (*field_types) * n_fields);
+
+ if (!field_names || !field_types)
+ {
+ res = false;
+ }
+ }
+
+ if (res)
+ {
+ for (n = 0; n < n_fields; n++)
+ {
+ fex_elem = rec_fex_get (recfix_index_fields, n);
+ field_names[n] = rec_fex_elem_field_name (fex_elem);
+ field_types[n] = REC_IDX_KEY_STRING;
+ }
+ }
+
+ /* Build the new index. */
+ if (res)
+ {
+ res = rec_idx_tree_build (rset, rset_number, n_fields,
+ field_names, field_types,
+ &index_data, &index_size, &index_type);
+ }
+
+ if (res)
+ {
+ res = rec_idx_build_add_index (idx, index_type, index_size,
+ (char *) index_data);
+ free (index_data);
+ }
+
+ if (field_names)
+ {
+ free (field_names);
+ }
+
+ if (field_types)
+ {
+ free (field_types);
+ }
+
+ if (res)
+ {
+ rec_idx_build_num_indices (idx, rec_idx_file_num_indices (idx_file) + 1);
+ }
+
+ if (db)
+ {
+ rec_db_destroy (db);
+ }
+
+ if (idx_file)
+ {
+ rec_idx_file_destroy (idx_file);
+ }
+
+ if (idx)
+ {
+ fclose (idx);
+ }
+
+ return res ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
int
main (int argc, char *argv[])
{
@@ -826,6 +1043,11 @@ main (int argc, char *argv[])
res = recfix_do_build_index ();
break;
}
+ case RECFIX_OP_ADD_INDEX:
+ {
+ res = recfix_do_add_index ();
+ break;
+ }
#if defined REC_CRYPT_SUPPORT
case RECFIX_OP_ENCRYPT:
case RECFIX_OP_DECRYPT:
--
1.7.11.4
- [bug-recutils] Index trees, Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 01/13] src,torture: imple ment abstract record iterators., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 02/13] src,torture: imple ment initial index tree support without nodes., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 06/13] utils,doc: make re cfix --build-index add index trees., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 05/13] src: fix index file builder., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 04/13] src,torture: imple ment index builder., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 12/13] src: implement a tri vial query planner., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 09/13] src,torture: suppo rt duplicating index tree objects., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 10/13] src: keep indexes in rsets., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 11/13] src: support index t rees that point to a leaf too left of the key searched f or., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 08/13] utils: add recfix -- add-index command.,
Michał Masłowski <=
- [bug-recutils] [PATCH 13/13] torture: use index t rees for performance tests., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 07/13] src: fix index range checks., Michał Masłowski, 2012/08/20
- [bug-recutils] [PATCH 03/13] src,torture: imple ment index tree scans., Michał Masłowski, 2012/08/20