package com.alvazan.ssql.cmdline;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import jline.ConsoleReader;
import jline.History;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import com.alvazan.orm.api.base.Bootstrap;
import com.alvazan.orm.api.base.DbTypeEnum;
import com.alvazan.orm.api.base.NoSqlEntityManager;
import com.alvazan.orm.api.base.NoSqlEntityManagerFactory;
import com.alvazan.orm.api.z8spi.meta.DboDatabaseMeta;
import com.alvazan.orm.api.z8spi.meta.DboTableMeta;
public class PlayOrm {
private static final Logger log = LoggerFactory.getLogger(PlayOrm.class);
private NoSqlEntityManagerFactory factory;
private CmdHelp help = new CmdHelp();
private CmdSelect select = new CmdSelect();
private CmdIndex index = new CmdIndex();
private CmdUpdate update = new CmdUpdate();
private CmdDelete delete = new CmdDelete();
public final static String HISTORYFILE = ".playorm.history";
private CmdListPartitions partitions = new CmdListPartitions();
public PlayOrm(NoSqlEntityManagerFactory factory) {
this.factory = factory;
}
public static void main(String[] args) {
// String hex = "44626f5461626c654d6574613a636f6c756d6e46616d696c79";
// byte[] d = Hex.decodeHex(hex.toCharArray());
// String value = StandardConverters.convertToString(String.class, d);
//
// log.info("val="+ value);
// byte[] data = StandardConverters.convertToBytes("ejktest001:time");
// char[] str = Hex.encodeHex(data);
// String s = new String(str);
// log.info("s="+s);
PlayOptions bean = new PlayOptions();
CmdLineParser parser = new CmdLineParser(bean);
try {
parser.parseArgument(args);
} catch( CmdLineException e ) {
printErr(e.getMessage());
printUsage(parser);
System.exit(-1);
}
DbTypeEnum storeType = DbTypeEnum.lookup(bean.getType());
if(storeType == null) {
printErr("type must be inmemory or cassandra");
printUsage(parser);
System.exit(-2);
} else if(storeType == DbTypeEnum.CASSANDRA) {
if(bean.getKeyspace() == null || bean.getSeeds() == null) {
printErr("-k and -s must be specified with -t cassandra");
printUsage(parser);
System.exit(-3);
}
}
if(!bean.isVerbose()) {
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(Level.WARN);
}
Map<String, Object> properties = new HashMap<String, Object>();
if(storeType == DbTypeEnum.CASSANDRA) {
Bootstrap.createAndAddBestCassandraConfiguration(properties , "", bean.getKeyspace(), bean.getSeeds());
}
else if (storeType == DbTypeEnum.MONGODB) {
Bootstrap.createAndAddBestMongoDbConfiguration(properties ,"", bean.getKeyspace(), bean.getSeeds());
}
properties.put(Bootstrap.AUTO_CREATE_KEY, "create");
NoSqlEntityManagerFactory factory = Bootstrap.create(storeType, properties);
new PlayOrm(factory).start();
}
private static void printErr(String msg) {
System.err.println(msg);
}
private static void printUsage(CmdLineParser parser) {
System.err.println("playcli ([option] argument)...");
parser.printUsage(System.err);
}
private void start() {
System.out.println("Welcome to PlayOrm Command Line");
System.out.println("Type 'help;' for help");
System.out.println("Type 'exit;' to exit");
try {
ConsoleReader reader = new ConsoleReader();
reader.setBellEnabled(false);
String historyFile = System.getProperty("user.home")
+ File.separator + HISTORYFILE;
History history = new History(new File(historyFile));
reader.setHistory(history);
String prompt;
String line = "";
String currentStatement = "";
boolean inCompoundStatement = false;
while (line != null) {
prompt = (inCompoundStatement) ? "...\t" : "playorm >>";
line = reader.readLine(prompt);
if (line == null)
return;
line = line.trim();
// skipping empty and comment lines
if (line.isEmpty() || line.startsWith("--"))
continue;
currentStatement += line;
if (line.endsWith(";") || line.equals("?")) {
try {
process(currentStatement);
} catch (Exception exp) {
if (log.isWarnEnabled())
log.warn("Exception occurred", exp);
println("Sorry, we ran into a bug, recovering now so you can continue using command line");
println("playorm >> ");
}
currentStatement = "";
inCompoundStatement = false;
} else {
currentStatement += " "; // ready for new line
inCompoundStatement = true;
}
}
} catch (IOException exp) {
if (log.isWarnEnabled())
log.warn("Exception occurred", exp);
}
}
private void process(String newLine) {
if(log.isDebugEnabled())
log.debug("processing line="+newLine);
String[] commands = newLine.split(";");
for(String cmd : commands) {
try {
String justCmd = cmd.trim();
processCommand(justCmd);
} catch (InvalidCommand e) {
if (log.isInfoEnabled())
log.info("invalid command", e);
println("Invalid command: '"+cmd+"'. Skipping it");
if(e.getMessage() != null)
println(e.getMessage());
}
}
}
private void processCommand(String cmd) {
NoSqlEntityManager mgr = factory.createEntityManager();
if("help".equals(cmd)) {
println("Getting around");
println("help; Display this help");
println("help <command> Display command-specific help.");
println("exit; Exit this utility");
println("");
println("Commands:");
println("SELECT Selects dataset matching expression. type 'help SELECT' for more info");
println("UPDATE Updates dataset matching expression. type 'help UPDATE' for more info");
println("DELETE Delete dataset matching expression. type 'help DELETE' for more info");
println("DELETECOLUMN Delete a column from the rows which matching expression. type 'help DELETECOLUMN' for more info");
println("PARTITIONS Selects dataset matching expression in a partition. type 'help PARTITIONS for more info");
println("VIEWINDEX Views an index. type 'help VIEWINDEX' for more info");
println("REINDEX Rebuild a particular index. type 'help REINDEX' for more info");
println("CREATE TABLE Not in yet");
println("INSERT Not in yet");
println("LIST TABLES To list all non-virtual column families. To list virual column families use LIST TABLES -all");
println("LISTPARTITIONS IF you partition on a field with @ManyToOne, you can list the partitions. type 'help LISTPARTITIONS' for more info");
} else if("exit".equals(cmd)) {
System.exit(0);
} else if(startsWithIgnoreCase("help ", cmd)) {
help.processHelpCmd(cmd);
} else if(startsWithIgnoreCase("CREATE ", cmd)) {
processCreate(cmd);
} else if(startsWithIgnoreCase("SELECT ", cmd) || startsWithIgnoreCase("PARTITIONS ", cmd)) {
select.processSelect(cmd, mgr);
} else if(startsWithIgnoreCase("VIEWINDEX ", cmd)) {
index.processIndex(cmd, mgr);
} else if (startsWithIgnoreCase("UPDATE ", cmd)) {
update.processUpdate(cmd, mgr);
} else if (startsWithIgnoreCase("DELETE ", cmd)) {
delete.processDelete(cmd, mgr);
} else if (startsWithIgnoreCase("DELETECOLUMN ", cmd)) {
delete.processDeleteColumn(cmd, mgr);
} else if(startsWithIgnoreCase("REINDEX ", cmd)) {
index.reindex(cmd, mgr);
} else if(startsWithIgnoreCase("LISTPARTITIONS ", cmd)) {
partitions.list(cmd, mgr);
} else if(startsWithIgnoreCase("LIST TABLES", cmd)) {
listTables(cmd, mgr);
} else {
throw new InvalidCommand();
}
}
private boolean startsWithIgnoreCase(String target, String cmd) {
int size = target.length();
int min = Math.min(size, cmd.length());
String partOfCmd = cmd.substring(0, min);
if(target.equalsIgnoreCase(partOfCmd))
return true;
return false;
}
private void processCreate(String cmd) {
String command = cmd.substring(7);
String newCmd = command.trim();
if(startsWithIgnoreCase("TABLE ", newCmd)) {
processCreateTable(newCmd);
} else {
throw new InvalidCommand();
}
}
private void processCreateTable(String newCmd) {
String leftOver = newCmd.substring(6);
String command = leftOver.trim();
}
private void listTables(String cmd, NoSqlEntityManager mgr) {
DboDatabaseMeta database = mgr.find(DboDatabaseMeta.class,
DboDatabaseMeta.META_DB_ROWKEY);
Collection<DboTableMeta> allTables = database.getAllTables();
int count = 0;
if (cmd.contains("-all") || cmd.contains("-ALL")) {
for (DboTableMeta tableMeta : allTables) {
println(tableMeta.getColumnFamily());
count++;
}
} else {
for (DboTableMeta tableMeta : allTables) {
if (!tableMeta.isVirtualCf()) {
println(tableMeta.getColumnFamily());
count++;
}
}
}
println("");
println(count + " tables");
println("");
}
private static void println(String msg) {
System.out.println(msg);
}
}