mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-22 15:49:34 -05:00
ITS#8662 Add -a append option to mdb_load
To allow reloading of custom-sorted DBs from mdb_dump
This commit is contained in:
parent
b4e1e00e9e
commit
7796aaebcd
3 changed files with 55 additions and 9 deletions
|
|
@ -6597,7 +6597,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||||
|
|
||||||
dkey.mv_size = 0;
|
dkey.mv_size = 0;
|
||||||
|
|
||||||
if (flags == MDB_CURRENT) {
|
if (flags & MDB_CURRENT) {
|
||||||
if (!(mc->mc_flags & C_INITIALIZED))
|
if (!(mc->mc_flags & C_INITIALIZED))
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
rc = MDB_SUCCESS;
|
rc = MDB_SUCCESS;
|
||||||
|
|
@ -6992,7 +6992,7 @@ put_sub:
|
||||||
xdata.mv_size = 0;
|
xdata.mv_size = 0;
|
||||||
xdata.mv_data = "";
|
xdata.mv_data = "";
|
||||||
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
|
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
|
||||||
if (flags & MDB_CURRENT) {
|
if (flags == MDB_CURRENT) {
|
||||||
xflags = MDB_CURRENT|MDB_NOSPILL;
|
xflags = MDB_CURRENT|MDB_NOSPILL;
|
||||||
} else {
|
} else {
|
||||||
mdb_xcursor_init1(mc, leaf);
|
mdb_xcursor_init1(mc, leaf);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,13 @@ option below.
|
||||||
.BR \-V
|
.BR \-V
|
||||||
Write the library version number to the standard output, and exit.
|
Write the library version number to the standard output, and exit.
|
||||||
.TP
|
.TP
|
||||||
|
.BR \-a
|
||||||
|
Append all records in the order they appear in the input. The input is assumed to already be
|
||||||
|
in correctly sorted order and no sorting or checking for redundant values will be performed.
|
||||||
|
This option must be used to reload data that was produced by running
|
||||||
|
.B mdb_dump
|
||||||
|
on a database that uses custom compare functions.
|
||||||
|
.TP
|
||||||
.BR \-f \ file
|
.BR \-f \ file
|
||||||
Read from the specified file instead of from the standard input.
|
Read from the specified file instead of from the standard input.
|
||||||
.TP
|
.TP
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ static int Eof;
|
||||||
static MDB_envinfo info;
|
static MDB_envinfo info;
|
||||||
|
|
||||||
static MDB_val kbuf, dbuf;
|
static MDB_val kbuf, dbuf;
|
||||||
|
static MDB_val k0buf;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define Z "I"
|
#define Z "I"
|
||||||
|
|
@ -278,10 +279,15 @@ badend:
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: %s [-V] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog);
|
fprintf(stderr, "usage: %s [-V] [-a] [-f input] [-n] [-s name] [-N] [-T] dbpath\n", prog);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int greater(const MDB_val *a, const MDB_val *b)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
@ -290,8 +296,9 @@ int main(int argc, char *argv[])
|
||||||
MDB_cursor *mc;
|
MDB_cursor *mc;
|
||||||
MDB_dbi dbi;
|
MDB_dbi dbi;
|
||||||
char *envname;
|
char *envname;
|
||||||
int envflags = 0, putflags = 0;
|
int envflags = MDB_NOSYNC, putflags = 0;
|
||||||
int dohdr = 0;
|
int dohdr = 0, append = 0;
|
||||||
|
MDB_val prevk;
|
||||||
|
|
||||||
prog = argv[0];
|
prog = argv[0];
|
||||||
|
|
||||||
|
|
@ -299,19 +306,23 @@ int main(int argc, char *argv[])
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -f: load file instead of stdin
|
/* -a: append records in input order
|
||||||
|
* -f: load file instead of stdin
|
||||||
* -n: use NOSUBDIR flag on env_open
|
* -n: use NOSUBDIR flag on env_open
|
||||||
* -s: load into named subDB
|
* -s: load into named subDB
|
||||||
* -N: use NOOVERWRITE on puts
|
* -N: use NOOVERWRITE on puts
|
||||||
* -T: read plaintext
|
* -T: read plaintext
|
||||||
* -V: print version and exit
|
* -V: print version and exit
|
||||||
*/
|
*/
|
||||||
while ((i = getopt(argc, argv, "f:ns:NTV")) != EOF) {
|
while ((i = getopt(argc, argv, "af:ns:NTV")) != EOF) {
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case 'V':
|
case 'V':
|
||||||
printf("%s\n", MDB_VERSION_STRING);
|
printf("%s\n", MDB_VERSION_STRING);
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
append = 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
if (freopen(optarg, "r", stdin) == NULL) {
|
if (freopen(optarg, "r", stdin) == NULL) {
|
||||||
fprintf(stderr, "%s: %s: reopen: %s\n",
|
fprintf(stderr, "%s: %s: reopen: %s\n",
|
||||||
|
|
@ -370,11 +381,16 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2;
|
kbuf.mv_size = mdb_env_get_maxkeysize(env) * 2 + 2;
|
||||||
kbuf.mv_data = malloc(kbuf.mv_size);
|
kbuf.mv_data = malloc(kbuf.mv_size * 2);
|
||||||
|
k0buf.mv_size = kbuf.mv_size;
|
||||||
|
k0buf.mv_data = (char *)kbuf.mv_data + kbuf.mv_size;
|
||||||
|
prevk.mv_data = k0buf.mv_data;
|
||||||
|
|
||||||
while(!Eof) {
|
while(!Eof) {
|
||||||
MDB_val key, data;
|
MDB_val key, data;
|
||||||
int batch = 0;
|
int batch = 0;
|
||||||
|
flags = 0;
|
||||||
|
int appflag;
|
||||||
|
|
||||||
if (!dohdr) {
|
if (!dohdr) {
|
||||||
dohdr = 1;
|
dohdr = 1;
|
||||||
|
|
@ -392,6 +408,12 @@ int main(int argc, char *argv[])
|
||||||
fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
fprintf(stderr, "mdb_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
prevk.mv_size = 0;
|
||||||
|
if (append) {
|
||||||
|
mdb_set_compare(txn, dbi, greater);
|
||||||
|
if (flags & MDB_DUPSORT)
|
||||||
|
mdb_set_dupsort(txn, dbi, greater);
|
||||||
|
}
|
||||||
|
|
||||||
rc = mdb_cursor_open(txn, dbi, &mc);
|
rc = mdb_cursor_open(txn, dbi, &mc);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
|
@ -410,7 +432,20 @@ int main(int argc, char *argv[])
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = mdb_cursor_put(mc, &key, &data, putflags);
|
if (append) {
|
||||||
|
appflag = MDB_APPEND;
|
||||||
|
if (flags & MDB_DUPSORT) {
|
||||||
|
if (prevk.mv_size == key.mv_size && !memcmp(prevk.mv_data, key.mv_data, key.mv_size))
|
||||||
|
appflag = MDB_CURRENT|MDB_APPENDDUP;
|
||||||
|
else {
|
||||||
|
memcpy(prevk.mv_data, key.mv_data, key.mv_size);
|
||||||
|
prevk.mv_size = key.mv_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appflag = 0;
|
||||||
|
}
|
||||||
|
rc = mdb_cursor_put(mc, &key, &data, putflags|appflag);
|
||||||
if (rc == MDB_KEYEXIST && putflags)
|
if (rc == MDB_KEYEXIST && putflags)
|
||||||
continue;
|
continue;
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
|
@ -435,6 +470,10 @@ int main(int argc, char *argv[])
|
||||||
fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
|
if (appflag & MDB_APPENDDUP) {
|
||||||
|
MDB_val k, d;
|
||||||
|
mdb_cursor_get(mc, &k, &d, MDB_LAST);
|
||||||
|
}
|
||||||
batch = 0;
|
batch = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue