/*
* Copyright 2011 Future Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.krakenapps.script;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.krakenapps.api.PathAutoCompleter;
import org.krakenapps.api.Primitive;
import org.krakenapps.api.Script;
import org.krakenapps.api.ScriptArgument;
import org.krakenapps.api.ScriptContext;
import org.krakenapps.api.ScriptUsage;
import org.krakenapps.confdb.CommitLog;
import org.krakenapps.confdb.Config;
import org.krakenapps.confdb.ConfigCollection;
import org.krakenapps.confdb.ConfigDatabase;
import org.krakenapps.confdb.ConfigIterator;
import org.krakenapps.confdb.ConfigService;
import org.krakenapps.confdb.Manifest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConfScript implements Script {
private final Logger logger = LoggerFactory.getLogger(ConfScript.class);
private ConfigService conf;
private ScriptContext context;
public ConfScript(ConfigService conf) {
this.conf = conf;
}
@Override
public void setScriptContext(ScriptContext context) {
this.context = context;
}
public void databases(String[] args) {
context.println("Databases");
context.println("-----------");
for (String name : conf.getDatabaseNames())
context.println(name);
}
@ScriptUsage(description = "create conf db", arguments = { @ScriptArgument(name = "name", type = "string", description = "database name") })
public void createdb(String[] args) {
conf.createDatabase(args[0]);
context.println("created");
}
@ScriptUsage(description = "drop conf db", arguments = { @ScriptArgument(name = "name", type = "string", description = "database name") })
public void dropdb(String[] args) {
conf.dropDatabase(args[0]);
context.println("dropped");
}
@ScriptUsage(description = "print documents", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "collection name", type = "string", description = "collection name") })
public void createcol(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
db.ensureCollection(args[1]);
context.println("created");
}
@ScriptUsage(description = "print documents", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "collection name", type = "string", description = "collection name") })
public void dropcol(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
db.dropCollection(args[1]);
context.println("dropped");
}
@ScriptUsage(description = "print manifest", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "rev id", type = "integer", description = "changelog revision id", optional = true) })
public void manifest(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
Integer revId = null;
if (args.length >= 2)
revId = Integer.parseInt(args[1]);
Manifest m = db.getManifest(revId);
if (m == null) {
context.println("manifest not found");
return;
}
context.println(db.getManifest(revId).toString());
}
@ScriptUsage(description = "show revision logs", arguments = {
@ScriptArgument(name = "name", type = "string", description = "database name"),
@ScriptArgument(name = "offset", type = "integer", optional = true, description = "log offset"),
@ScriptArgument(name = "limit", type = "integer", optional = true, description = "log count limit") })
public void logs(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
long offset = 0;
long limit = 10;
if (args.length > 1)
offset = Long.parseLong(args[1]);
if (args.length > 2)
limit = Long.parseLong(args[2]);
List<CommitLog> logs = db.getCommitLogs(offset, limit);
for (CommitLog log : logs)
context.println(log);
}
@ScriptUsage(description = "print collection names", arguments = { @ScriptArgument(name = "name", type = "string", description = "database name") })
public void cols(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
context.println("Collections");
context.println("-------------");
for (String name : db.getCollectionNames()) {
ConfigCollection col = db.getCollection(name);
context.println(col);
}
}
@ScriptUsage(description = "print documents", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "collection name", type = "string", description = "collection name") })
public void docs(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
ConfigCollection col = db.getCollection(args[1]);
if (col == null) {
context.println("collection not found");
return;
}
context.println("Documents");
context.println("-----------");
ConfigIterator it = col.findAll();
try {
while (it.hasNext()) {
Config c = it.next();
String s = "id=" + c.getId() + ", rev=" + c.getRevision() + ", doc=" + Primitive.stringify(c.getDocument());
context.println(s);
}
} finally {
it.close();
}
}
@ScriptUsage(description = "print documents", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "collection name", type = "string", description = "collection name"),
@ScriptArgument(name = "doc id", type = "integer", description = "document id") })
public void delete(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
ConfigCollection col = db.getCollection(args[1]);
if (col == null) {
context.println("collection not found");
return;
}
int id = Integer.parseInt(args[2]);
ConfigIterator it = col.findAll();
Config config = null;
try {
while (it.hasNext()) {
Config c = it.next();
if (c.getId() == id) {
config = c;
break;
}
}
} finally {
it.close();
}
if (config != null) {
col.remove(config);
context.println("removed");
} else {
context.println("document not found");
}
}
@ScriptUsage(description = "print documents", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "rollback revision", type = "integer", description = "rollback revision id") })
public void rollback(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
db.rollback(Integer.parseInt(args[1]));
context.println("complete");
}
@ScriptUsage(description = "shrink log", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "limit", type = "integer", description = "log acount limit") })
public void shrink(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not fount");
return;
}
if (args[1] == null) {
context.println("count should be input over 0");
return;
}
try {
db.shrink(Integer.parseInt(args[1]));
context.println("ok");
} catch (Exception e) {
logger.error("kraken core: failed to shrink [" + db.getName() + "]", e);
context.println("failed to shrink [" + db.getName() + "], " + e.getMessage());
}
}
@ScriptUsage(description = "export db data", arguments = {
@ScriptArgument(name = "database name", type = "string", description = "database name"),
@ScriptArgument(name = "file path", type = "string", description = "export file path", autocompletion = PathAutoCompleter.class),
@ScriptArgument(name = "export revision", type = "integer", description = "export revision id", optional = true) })
public void exportFile(String[] args) {
Integer rev = null;
if (args.length > 2)
rev = Integer.parseInt(args[2]);
ConfigDatabase db = conf.getDatabase(args[0], rev);
if (db == null) {
context.println("database not found");
return;
}
OutputStream os = null;
File dir = (File) context.getSession().getProperty("dir");
File exportFile = canonicalize(dir, args[1]);
try {
if (exportFile.exists()) {
context.println("file already exists: " + exportFile.getAbsolutePath());
return;
}
os = new FileOutputStream(exportFile);
db.exportData(os);
context.println("exported " + db.getName() + " to " + exportFile.getAbsolutePath());
} catch (IOException e) {
logger.error("kraken core: cannot export data", e);
context.println("export failed due to " + e.getMessage());
} finally {
try {
if (os != null)
os.close();
} catch (IOException e) {
}
}
}
@ScriptUsage(description = "import db data", arguments = {
@ScriptArgument(name = "database name", type = "String", description = "database name"),
@ScriptArgument(name = "file path", type = "string", description = "target file path", autocompletion = PathAutoCompleter.class) })
public void importFile(String[] args) {
ConfigDatabase db = conf.getDatabase(args[0]);
if (db == null) {
context.println("database not found");
return;
}
if (args[1] == null) {
context.println("input file name");
return;
}
File dir = (File) context.getSession().getProperty("dir");
File targetFile = canonicalize(dir, args[1]);
if (!targetFile.exists()) {
context.println("file does not exist: " + targetFile.getAbsolutePath());
return;
}
if (!targetFile.canRead()) {
context.println("cannot read file, check permission");
return;
}
InputStream is = null;
try {
is = new FileInputStream(targetFile);
db.importData(is);
context.println("imported " + db.getName() + " from " + targetFile.getAbsolutePath());
} catch (IOException e) {
logger.error("kraken core: cannot import data", e);
context.println("import failed due to " + e.getMessage());
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
}
private File canonicalize(File dir, String path) {
if (path.startsWith("/"))
return new File(path);
else
return new File(dir, path);
}
}