
org.jsimpledb.cli.cmd.KVSaveCommand Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsimpledb-cli Show documentation
Show all versions of jsimpledb-cli Show documentation
JSimpleDB classes supporting command line interfaces.
The newest version!
/*
* Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
*/
package org.jsimpledb.cli.cmd;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Map;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import org.dellroad.stuff.io.AtomicUpdateFileOutputStream;
import org.dellroad.stuff.xml.IndentXMLStreamWriter;
import org.jsimpledb.Session;
import org.jsimpledb.SessionMode;
import org.jsimpledb.cli.CliSession;
import org.jsimpledb.kv.util.XMLSerializer;
import org.jsimpledb.parse.Parser;
import org.jsimpledb.util.ParseContext;
public class KVSaveCommand extends AbstractCommand {
public KVSaveCommand() {
super("kvsave -i:indent -w:weak file.xml:file minKey? maxKey?");
}
@Override
public String getHelpSummary() {
return "Exports key/value pairs to an XML file";
}
@Override
public String getHelpDetail() {
return "Writes all key/value pairs to the specified XML file. Data can be read back in later via `kvload'."
+ "\n\nIf `minKey' and/or `maxKey' are specified, the keys are restricted to the specified range."
+ " `minKey' and `maxKey' may be given as hexadecimal strings or C-style doubly-quoted strings.\n"
+ "The `-i' flag causes the output XML to be indented.\n"
+ "If the `-w' flag is given, for certain key/value stores a weaker consistency level is used for"
+ " the tranasction to reduce the chance of conflicts.";
}
@Override
public EnumSet getSessionModes() {
return EnumSet.allOf(SessionMode.class);
}
@Override
protected Parser> getParser(String typeName) {
return "file".equals(typeName) ? new OutputFileParser() : super.getParser(typeName);
}
@Override
public CliSession.Action getAction(CliSession session, ParseContext ctx, boolean complete, Map params) {
// Parse parameters
final File file = (File)params.get("file.xml");
final boolean indent = params.containsKey("indent");
final boolean weak = params.containsKey("weak");
final byte[] minKey = (byte[])params.get("minKey");
final byte[] maxKey = (byte[])params.get("maxKey");
// Return action
return new SaveAction(file, indent, weak, minKey, maxKey);
}
private static class SaveAction implements CliSession.Action, Session.RetryableAction, Session.HasTransactionOptions {
private final File file;
private final boolean indent;
private final boolean weak;
private final byte[] minKey;
private final byte[] maxKey;
SaveAction(File file, boolean indent, boolean weak, byte[] minKey, byte[] maxKey) {
this.file = file;
this.indent = indent;
this.weak = weak;
this.minKey = minKey;
this.maxKey = maxKey;
}
@Override
public void run(CliSession session) throws Exception {
final FileOutputStream updateOutput = !this.isWindows() ?
new AtomicUpdateFileOutputStream(this.file) : new FileOutputStream(this.file);
final BufferedOutputStream output = new BufferedOutputStream(updateOutput);
boolean success = false;
final int count;
try {
XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(output, "UTF-8");
if (this.indent)
writer = new IndentXMLStreamWriter(writer);
writer.writeStartDocument("UTF-8", "1.0");
final XMLSerializer serializer = new XMLSerializer(session.getKVTransaction());
count = serializer.write(writer, this.minKey, this.maxKey);
output.flush();
success = true;
} finally {
if (success) {
try {
output.close();
} catch (IOException e) {
// ignore
}
} else if (updateOutput instanceof AtomicUpdateFileOutputStream)
((AtomicUpdateFileOutputStream)updateOutput).cancel();
}
session.getWriter().println("Wrote " + count + " key/value pairs to `" + this.file + "'");
}
// Use EVENTUAL_COMMITTED consistency for Raft key/value stores to avoid retries
@Override
public Map getTransactionOptions() {
return this.weak ? Collections.singletonMap("consistency", "EVENTUAL") : null;
}
private boolean isWindows() {
return System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH).contains("win");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy