use of com.laytonsmith.persistence.DataSource in project CommandHelper by EngineHub.
the class Manager method hiddenKeys.
public static void hiddenKeys() {
String action;
while (true) {
pl(WHITE + "Would you like to \"" + GREEN + "view" + WHITE + "\" or \"" + RED + "delete" + WHITE + "\" the hidden keys (default: view)? [view/delete]");
action = prompt();
if ("".equals(action)) {
action = "view";
}
if ("view".equals(action) || "delete".equals(action)) {
break;
} else {
pl(RED + "Invalid selection.");
}
}
File configuration = MethodScriptFileLocations.getDefault().getPersistenceConfig();
while (true) {
pl("Currently, " + configuration.getAbsolutePath() + " is being used as the persistence config file, but you may" + " specify another (blank to use the default).");
String file = prompt();
if ("".equals(file)) {
break;
} else {
File f = new File(file);
if (f.exists()) {
configuration = f;
break;
} else {
pl(RED + "The file you specified doesn't seem to exist, please enter it again.");
}
}
}
pl(YELLOW + "Using " + configuration.getAbsolutePath() + " as our Persistence Network config.");
File workingDirectory = MethodScriptFileLocations.getDefault().getConfigDirectory();
while (true) {
pl("Currently, " + workingDirectory.getAbsolutePath() + " is being used as the default \"working directory\" for the" + " persistence config file, but you may specify another (blank to use the default).");
String file = prompt();
if ("".equals(file)) {
break;
} else {
File f = new File(file);
if (f.exists()) {
workingDirectory = f;
break;
} else {
pl(RED + "The file you specified doesn't seem to exist, please enter it again.");
}
}
}
pl(YELLOW + "Using " + workingDirectory.getAbsolutePath() + " as our Persistence Network config working directory.");
try {
DataSourceFilter filter = new DataSourceFilter(configuration, new URI("sqlite://persistence.db"));
ConnectionMixinFactory.ConnectionMixinOptions options = new ConnectionMixinFactory.ConnectionMixinOptions();
options.setWorkingDirectory(workingDirectory);
Set<URI> uris = filter.getAllConnections();
boolean noneFound = true;
int runningTotal = 0;
for (URI uri : uris) {
DataSource ds = DataSourceFactory.GetDataSource(uri, options);
Map<String[], String> db = ds.getValues(ArrayUtils.EMPTY_STRING_ARRAY);
Map<String[], String> map = new HashMap<>();
DaemonManager dm = new DaemonManager();
try {
for (String[] key : db.keySet()) {
if (!filter.getConnection(key).equals(uri)) {
map.put(key, db.get(key));
if ("delete".equals(action)) {
ds.clearKey(dm, key);
}
}
}
runningTotal += map.size();
} catch (ReadOnlyException ex) {
pl(RED + "Cannot delete any keys from " + uri + " as it is marked as read only, so it is being skipped.");
}
if ("delete".equals(action)) {
try {
dm.waitForThreads();
} catch (InterruptedException ex) {
// Ignored
}
}
if (!map.isEmpty()) {
noneFound = false;
if ("view".equals(action)) {
pl("Found " + StringUtils.PluralTemplateHelper(map.size(), "one hidden key", "%d hidden keys") + " in data source " + MAGENTA + uri.toString());
for (String[] key : map.keySet()) {
pl("\t" + GREEN + StringUtils.Join(key, ".") + WHITE + ":" + CYAN + map.get(key));
}
if (ds.hasModifier(DataSource.DataSourceModifier.READONLY)) {
pl(YELLOW + "This data source is marked as read only, and the keys cannot be deleted from it by this utility.");
}
pl();
}
}
}
if (noneFound) {
pl(GREEN + "Done searching, no hidden keys were found.");
} else {
if ("delete".equals(action)) {
pl(GREEN + "Done, " + StringUtils.PluralTemplateHelper(runningTotal, "one hidden key was", "%d hidden keys were") + " deleted.");
} else {
pl(GREEN + "Found " + StringUtils.PluralTemplateHelper(runningTotal, "one hidden key", "%d hidden keys") + " in total.");
}
}
} catch (URISyntaxException | IOException | DataSourceException ex) {
pl(RED + ex.getMessage());
ex.printStackTrace(StreamUtils.GetSystemErr());
}
}
use of com.laytonsmith.persistence.DataSource in project CommandHelper by EngineHub.
the class Manager method merge.
public static void merge() {
cls();
pl(GREEN + "Transferring a database takes all the keys from a database connection, and puts\n" + "them straight into another database. If there are key conflicts, this tool will prompt\n" + "you for an action.");
ConnectionMixinFactory.ConnectionMixinOptions mixinOptions = new ConnectionMixinFactory.ConnectionMixinOptions();
mixinOptions.setWorkingDirectory(chDirectory);
DataSource source;
DataSource destination;
do {
// the exact same value.
do {
// Get the source connection set up
pl(YELLOW + "What is the source connection you would like to read the keys from?\n" + "(Type the connection exactly as you would in the persistence configuration,\n" + "aliases are not supported)");
String ssource = prompt();
try {
source = DataSourceFactory.GetDataSource(ssource, mixinOptions);
break;
} catch (DataSourceException | URISyntaxException ex) {
pl(RED + ex.getMessage());
}
} while (true);
do {
// Get the destination connection set up
pl(YELLOW + "What is the destination connection?");
String sdestination = prompt();
try {
destination = DataSourceFactory.GetDataSource(sdestination, mixinOptions);
break;
} catch (DataSourceException | URISyntaxException ex) {
pl(RED + ex.getMessage());
}
} while (true);
try {
// Run through all the source's keys, and check to see that either the
// destination's key doesn't exist, or the value at that key is the
// exact same as the source's value
boolean acceptAllDestination = false;
boolean acceptAllSource = false;
DaemonManager dm = new DaemonManager();
for (String[] key : source.keySet(ArrayUtils.EMPTY_STRING_ARRAY)) {
if (destination.hasKey(key)) {
if (!source.get(key).equals(destination.get(key))) {
String data;
// ask.
if (destination.get(key) != null) {
boolean useSource = false;
boolean useDestination = false;
if (acceptAllDestination || acceptAllSource) {
p(RED + "Conflict found for " + StringUtils.Join(key, ".") + ", using ");
if (useSource) {
useSource = true;
p("source");
} else {
useDestination = true;
p("destination");
}
pl(" value.");
} else {
pl(BG_RED + BRIGHT_WHITE + "The key " + StringUtils.Join(key, ".") + " has a different value" + " in the source and the destination: " + reset());
pl(WHITE + "Source: " + source.get(key));
pl(WHITE + "Destination: " + destination.get(key));
do {
pl(YELLOW + "Would you like to keep " + CYAN + "S" + YELLOW + "ource, " + "keep " + GREEN + "D" + YELLOW + "estination, keep " + MAGENTA + "A" + YELLOW + "ll " + MAGENTA + "S" + YELLOW + "ource, or keep " + BLUE + "A" + YELLOW + "ll " + BLUE + "D" + YELLOW + "estination?");
pl(WHITE + "[" + CYAN + "S" + WHITE + "/" + GREEN + "D" + WHITE + "/" + MAGENTA + "AS" + WHITE + "/" + BLUE + "AD" + WHITE + "]");
String response = prompt();
if ("AS".equalsIgnoreCase(response)) {
acceptAllSource = true;
useSource = true;
} else if ("AD".equalsIgnoreCase(response)) {
acceptAllDestination = true;
useDestination = true;
} else if ("S".equalsIgnoreCase(response)) {
useSource = true;
} else if ("D".equalsIgnoreCase(response)) {
useDestination = true;
} else {
continue;
}
break;
} while (true);
}
if (useSource) {
data = source.get(key);
} else if (useDestination) {
data = destination.get(key);
} else {
throw new RuntimeException("Invalid state, both useSource and useDestination are false");
}
// Ok, now put the data in the destination
} else {
// Otherwise, just use the data in the source
data = source.get(key);
}
destination.set(dm, key, data);
}
} else {
// Else there is no conflict, it's not in the destination.
destination.set(dm, key, source.get(key));
}
}
try {
dm.waitForThreads();
} catch (InterruptedException ex) {
//
}
break;
} catch (DataSourceException | ReadOnlyException | IOException ex) {
pl(RED + ex.getMessage());
}
} while (true);
pl(GREEN + "Done merging!");
}
Aggregations