diff --git a/.classpath b/.classpath
index bded8da..32d8ef3 100644
--- a/.classpath
+++ b/.classpath
@@ -25,6 +25,6 @@
-
+
diff --git a/src/fr/devinsy/sikevadb/SikevaDBLauncher.java b/src/fr/devinsy/sikevadb/SikevaDBLauncher.java
index c734f40..51b53b9 100644
--- a/src/fr/devinsy/sikevadb/SikevaDBLauncher.java
+++ b/src/fr/devinsy/sikevadb/SikevaDBLauncher.java
@@ -20,12 +20,14 @@ package fr.devinsy.sikevadb;
import java.io.File;
+import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.sikevadb.cli.SikevaDBCLI;
+import fr.devinsy.sikevadb.demo.SikevaDBDemo;
/**
* This class Siba stands for Simple Backup. This is the main class.
@@ -70,6 +72,10 @@ public final class SikevaDBLauncher
// TODO
// SikevaGUI.run();
}
+ else if (ArrayUtils.contains(args, "-demo"))
+ {
+ SikevaDBDemo.run(args);
+ }
else
{
SikevaDBCLI.run(args);
diff --git a/src/fr/devinsy/sikevadb/core/Archiver.java b/src/fr/devinsy/sikevadb/core/Archiver.java
index 5e09052..26829b1 100644
--- a/src/fr/devinsy/sikevadb/core/Archiver.java
+++ b/src/fr/devinsy/sikevadb/core/Archiver.java
@@ -36,6 +36,8 @@ public interface Archiver
void clear() throws SikevaDBException;
+ void close();
+
boolean isActivated();
boolean isSuspended();
diff --git a/src/fr/devinsy/sikevadb/core/SikevaDB.java b/src/fr/devinsy/sikevadb/core/SikevaDB.java
index add98c6..0a1632f 100644
--- a/src/fr/devinsy/sikevadb/core/SikevaDB.java
+++ b/src/fr/devinsy/sikevadb/core/SikevaDB.java
@@ -41,6 +41,8 @@ public interface SikevaDB
public void create() throws SikevaDBException;
+ public void destroy() throws SikevaDBException;
+
public Element getElement(String key) throws SikevaDBException;
public Element getElement(String key, String subkey) throws SikevaDBException;
diff --git a/src/fr/devinsy/sikevadb/core/SikevaDBFactory.java b/src/fr/devinsy/sikevadb/core/SikevaDBFactory.java
index 8f3ee41..870c1d4 100644
--- a/src/fr/devinsy/sikevadb/core/SikevaDBFactory.java
+++ b/src/fr/devinsy/sikevadb/core/SikevaDBFactory.java
@@ -34,8 +34,9 @@ public class SikevaDBFactory
*
* @param path
* @return
+ * @throws SikevaDBException
*/
- public static SikevaDB get(final File path)
+ public static SikevaDB get(final File path) throws SikevaDBException
{
SikevaDB result;
diff --git a/src/fr/devinsy/sikevadb/demo/SikevaDBDemo.java b/src/fr/devinsy/sikevadb/demo/SikevaDBDemo.java
new file mode 100644
index 0000000..bdb19bd
--- /dev/null
+++ b/src/fr/devinsy/sikevadb/demo/SikevaDBDemo.java
@@ -0,0 +1,256 @@
+/**
+ * Copyright (C) 2013-2017 Christian Pierre MOMON
+ *
+ * This file is part of SikevaDB, simple key value database.
+ *
+ * SikevaDB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * SikevaDB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with SikevaDB. If not, see .
+ */
+
+package fr.devinsy.sikevadb.demo;
+
+import java.io.File;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.PropertyConfigurator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import utils.BuildInformation;
+import fr.devinsy.sikevadb.core.SikevaDB;
+import fr.devinsy.sikevadb.core.SikevaDBException;
+import fr.devinsy.sikevadb.core.SikevaDBFactory;
+import fr.devinsy.util.strings.StringList;
+
+/**
+ * This class manage a Command Line Interface for SikevaDB.
+ *
+ *
+ */
+public final class SikevaDBDemo
+{
+ private static Logger logger = LoggerFactory.getLogger(SikevaDBDemo.class);
+
+ /**
+ *
+ */
+ private SikevaDBDemo()
+ {
+ }
+
+ /**
+ * @throws SikevaDBException
+ *
+ */
+ public static void demo() throws SikevaDBException
+ {
+ SikevaDB database = null;
+ try
+ {
+ File homeDirectory = new File("/tmp/footest");
+ database = SikevaDBFactory.get(homeDirectory);
+
+ if (database.isCreated())
+ {
+ database.destroy();
+ }
+
+ database.create();
+ database.open();
+
+ // Single key value.
+ {
+ database.put("alpha", "alpha value");
+ database.put("bravo", "bravo value");
+ database.put("charlie", "charlie value");
+
+ String value = database.getValue("alpha");
+ if (StringUtils.equals(value, "alpha value"))
+ {
+ System.out.println("alpha is correctly stored.");
+ }
+ else
+ {
+ System.out.println("alpha is NOT correctly stored.");
+ }
+
+ //
+ database.remove("alpha");
+ if (database.getValue("alpha") == null)
+ {
+ System.out.println("alpha is correctly removed.");
+ }
+ else
+ {
+ System.out.println("alpha is NOT correctly removed.");
+ }
+ }
+
+ // Double key values.
+ {
+ for (int index = 0; index < 10; index++)
+ {
+ database.put("victor", String.valueOf(index), "victor" + index);
+ }
+
+ String value = database.getValue("victor", String.valueOf(7));
+ if (StringUtils.equals(value, "victor7"))
+ {
+ System.out.println("victor is correctly stored.");
+ }
+ else
+ {
+ System.out.println("victor is NOT correctly stored.");
+ }
+
+ //
+ database.remove("victor", String.valueOf(5));
+ if (database.getValue("victor", String.valueOf(5)) == null)
+ {
+ System.out.println("(victor, 5) is correctly removed.");
+ }
+ else
+ {
+ System.out.println("(victor, 5) is NOT correctly removed.");
+ }
+ }
+
+ //
+ database.close();
+ }
+ finally
+ {
+ if ((database != null) && (database.isCreated()))
+ {
+ database.destroy();
+ }
+ }
+ }
+
+ /**
+ * This method displays the CLI help.
+ *
+ */
+ public static void help()
+ {
+ StringList message = new StringList();
+
+ message.append("SikevaDB Demo version ").appendln(BuildInformation.instance().version());
+ message.appendln("Usage:");
+ message.appendln(" sikevadbdemo [ -h | -help | --help ]");
+ message.appendln(" sikevadb -demo [ -h | -help | --help ]");
+
+ System.out.println(message.toString());
+ }
+
+ /**
+ *
+ * @param args
+ */
+ public static void main(final String[] args)
+ {
+ // Configure log.
+ File loggerConfig = new File("log4j.properties");
+ if (loggerConfig.exists())
+ {
+ PropertyConfigurator.configure(loggerConfig.getAbsolutePath());
+ logger.info("Dedicated log configuration done.");
+ logger.info("Configuration file was found in [{}].", loggerConfig.getAbsoluteFile());
+ }
+ else
+ {
+ BasicConfigurator.configure();
+ logger.info("Basic log configuration done.");
+ logger.info("Configuration file was not found in [{}].", loggerConfig.getAbsoluteFile());
+ }
+
+ // Run.
+ SikevaDBDemo.run(args);
+ }
+
+ /**
+ *
+ * This method launch CLI.
+ *
+ * @param args
+ * necessary arguments
+ */
+ public static void run(final String[] args)
+ {
+ try
+ {
+ // Set default catch.
+ Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
+ {
+ @Override
+ public void uncaughtException(final Thread thread, final Throwable exception)
+ {
+ String message;
+ if (exception instanceof OutOfMemoryError)
+ {
+ message = "Java ran out of memory!\n\n";
+ }
+ else
+ {
+ message = String.format("An error occured: %1s(%2s)", exception.getClass(), exception.getMessage());
+ }
+
+ logger.error("uncaughtException ", exception);
+ logger.error(message);
+ logger.info("Oups, an unexpected error occured. Please try again.");
+ }
+ });
+
+ // This part implements an automate.
+ int parameterCount = args.length;
+ if (parameterCount == 0)
+ {
+ demo();
+ }
+ else if (StringUtils.equals(args[0], "-h") || StringUtils.equals(args[0], "-help") || StringUtils.equals(args[0], "--help"))
+ {
+ help();
+ }
+ else if (StringUtils.equals(args[0], "get"))
+ {
+ switch (parameterCount)
+ {
+ case 2:
+ {
+ }
+ break;
+
+ case 3:
+ {
+ }
+ break;
+
+ default:
+ throw new SikevaDBException("Bad parameter count.");
+ }
+ }
+ else
+ {
+ System.out.println("Bad usage detected.");
+ help();
+ }
+ }
+ catch (SikevaDBException exception)
+ {
+ System.err.println("SibaException = " + exception.getMessage());
+ logger.error(exception.getMessage(), exception);
+ help();
+ }
+ }
+}
diff --git a/src/fr/devinsy/sikevadb/demo/SikevaDBDemoException.java b/src/fr/devinsy/sikevadb/demo/SikevaDBDemoException.java
new file mode 100644
index 0000000..49afc4e
--- /dev/null
+++ b/src/fr/devinsy/sikevadb/demo/SikevaDBDemoException.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2013-2017 Christian Pierre MOMON
+ *
+ * This file is part of SikevaDB, simple key value database.
+ *
+ * SikevaDB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * SikevaDB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with SikevaDB. If not, see .
+ */
+package fr.devinsy.sikevadb.demo;
+
+import fr.devinsy.sikevadb.core.SikevaDBException;
+
+/**
+ *
+ */
+public class SikevaDBDemoException extends SikevaDBException
+{
+ private static final long serialVersionUID = 1162267847144476595L;
+
+ /**
+ *
+ */
+ public SikevaDBDemoException()
+ {
+ super();
+ }
+
+ /**
+ *
+ * @param message
+ */
+ public SikevaDBDemoException(final String message)
+ {
+ super(message);
+ }
+
+ /**
+ *
+ * @param message
+ * @param cause
+ */
+ public SikevaDBDemoException(final String message, final Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ /**
+ *
+ * @param cause
+ */
+ public SikevaDBDemoException(final Throwable cause)
+ {
+ super(cause);
+ }
+}
\ No newline at end of file
diff --git a/src/fr/devinsy/sikevadb/filetree/FileTreeArchiver.java b/src/fr/devinsy/sikevadb/filetree/FileTreeArchiver.java
index 8bc9058..529b618 100644
--- a/src/fr/devinsy/sikevadb/filetree/FileTreeArchiver.java
+++ b/src/fr/devinsy/sikevadb/filetree/FileTreeArchiver.java
@@ -97,6 +97,15 @@ public class FileTreeArchiver implements Archiver
}
+ /**
+ *
+ */
+ @Override
+ public void close()
+ {
+ // TODO
+ }
+
/**
*
* @return
diff --git a/src/fr/devinsy/sikevadb/filetree/FileTreeSikevaDB.java b/src/fr/devinsy/sikevadb/filetree/FileTreeSikevaDB.java
index 96000cf..e8d6da0 100644
--- a/src/fr/devinsy/sikevadb/filetree/FileTreeSikevaDB.java
+++ b/src/fr/devinsy/sikevadb/filetree/FileTreeSikevaDB.java
@@ -22,6 +22,8 @@ import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
@@ -32,6 +34,7 @@ import fr.devinsy.sikevadb.core.Element;
import fr.devinsy.sikevadb.core.Elements;
import fr.devinsy.sikevadb.core.SikevaDB;
import fr.devinsy.sikevadb.core.SikevaDBException;
+import fr.devinsy.util.ToolBox;
import fr.devinsy.util.strings.StringList;
/**
@@ -63,7 +66,7 @@ public class FileTreeSikevaDB implements SikevaDB
private Status status;
private String login;
private String password;
- private File fileTreeDirectory;
+ private File homeDirectory;
private File dataDirectory;
private Archiver archiver;
private File configDirectory;
@@ -71,16 +74,28 @@ public class FileTreeSikevaDB implements SikevaDB
/**
*
* @param contextName
+ * @throws SikevaDBException
*/
- public FileTreeSikevaDB(final File fileTreeDirectory, final String login, final String password)
+ public FileTreeSikevaDB(final File homeDirectory, final String login, final String password) throws SikevaDBException
{
- this.status = Status.CLOSED;
- this.fileTreeDirectory = fileTreeDirectory;
- this.dataDirectory = new File(this.fileTreeDirectory, "data");
- this.configDirectory = new File(this.fileTreeDirectory, "config");
- this.login = login;
- this.password = password;
- this.archiver = null;
+ if (homeDirectory == null)
+ {
+ throw new SikevaDBException("Invalid home directory (null).");
+ }
+ else if (StringUtils.equals(homeDirectory.getAbsolutePath(), "/"))
+ {
+ throw new SikevaDBException("Invalide home directory (file system root).");
+ }
+ else
+ {
+ this.status = Status.CLOSED;
+ this.homeDirectory = homeDirectory;
+ this.dataDirectory = new File(this.homeDirectory, "data");
+ this.configDirectory = new File(this.homeDirectory, "config");
+ this.login = login;
+ this.password = password;
+ this.archiver = null;
+ }
}
/**
@@ -118,7 +133,7 @@ public class FileTreeSikevaDB implements SikevaDB
@Override
public void close()
{
- this.archiver = null;
+ this.archiver.close();
this.status = Status.CLOSED;
}
@@ -224,22 +239,83 @@ public class FileTreeSikevaDB implements SikevaDB
{
throw new SikevaDBException("Invalid state.");
}
- else if (this.fileTreeDirectory == null)
+ else if (this.homeDirectory == null)
{
throw new SikevaDBException("Invalid root directory.");
}
- else if (this.fileTreeDirectory.exists())
+ else if (this.homeDirectory.exists())
{
throw new SikevaDBException("Root directory already is existing.");
}
else
{
- this.fileTreeDirectory.mkdir();
+ this.homeDirectory.mkdir();
this.dataDirectory.mkdir();
this.configDirectory.mkdir();
}
}
+ /**
+ *
+ */
+ @Override
+ public void destroy() throws SikevaDBException
+ {
+ if (this.homeDirectory == null)
+ {
+ throw new SikevaDBException("Invalid home directory (undefined), destroy operation is cancelled.");
+ }
+ else
+ {
+ String databaseHome = this.homeDirectory.getAbsolutePath();
+ databaseHome = StringUtils.removeEnd(databaseHome, "/.");
+
+ if (StringUtils.isBlank(databaseHome))
+ {
+ throw new SikevaDBException("Invalid home directory (blank), destroy operation is cancelled.");
+ }
+ else if (this.dataDirectory == null)
+ {
+ throw new SikevaDBException("Invalid data directory (undefined), destroy operation is cancelled.");
+ }
+ else if (StringUtils.isBlank(this.dataDirectory.getAbsolutePath()))
+ {
+ throw new SikevaDBException("Invalid data directory (blank), destroy operation is cancelled.");
+ }
+ else if (this.configDirectory == null)
+ {
+ throw new SikevaDBException("Invalid config directory (undefined), destroy operation is cancelled.");
+ }
+ else if (StringUtils.isBlank(this.configDirectory.getAbsolutePath()))
+ {
+ throw new SikevaDBException("Invalid config directory (blank), destroy operation is cancelled.");
+ }
+ else if (ToolBox.matchesAny(databaseHome, "/", "/root", "/usr", "/home", "/tmp", "/var", "/srv", "/boot"))
+ {
+ throw new SikevaDBException("Invalid home directory (system file), destroy operation is cancelled.");
+ }
+ else if (StringUtils.equals(databaseHome, SystemUtils.USER_HOME))
+ {
+ throw new SikevaDBException("Invalid config directory (), destroy operation is cancelled.");
+ }
+ else if (isCreated())
+ {
+ try
+ {
+ FileUtils.deleteDirectory(this.homeDirectory);
+ }
+ catch (IOException exception)
+ {
+ throw new SikevaDBException("Error destroying database. You have to achieve the operation manually.", exception);
+ }
+ }
+ else
+ {
+ throw new SikevaDBException("Impossible to destroy a none existing database.");
+ }
+ }
+ }
+
/**
*
* @return
@@ -397,7 +473,7 @@ public class FileTreeSikevaDB implements SikevaDB
*/
public File getFileTreeDirectory()
{
- return this.fileTreeDirectory;
+ return this.homeDirectory;
}
/**
@@ -657,7 +733,7 @@ public class FileTreeSikevaDB implements SikevaDB
{
boolean result;
- if ((this.fileTreeDirectory.isDirectory()) && (this.dataDirectory.isDirectory()) && (this.configDirectory.isDirectory()))
+ if ((this.homeDirectory.isDirectory()) && (this.dataDirectory.isDirectory()) && (this.configDirectory.isDirectory()))
{
result = true;
}
@@ -819,12 +895,22 @@ public class FileTreeSikevaDB implements SikevaDB
@Override
public void open() throws SikevaDBException
{
- //
- close();
-
- //
- this.status = Status.OPENED;
- this.archiver = new FileTreeArchiver(this);
+ if (isCreated())
+ {
+ if (isOpened())
+ {
+ throw new SikevaDBException("Database already opened.");
+ }
+ else
+ {
+ this.status = Status.OPENED;
+ this.archiver = new FileTreeArchiver(this);
+ }
+ }
+ else
+ {
+ throw new SikevaDBException("Database is not existing.");
+ }
}
/**
diff --git a/src/fr/devinsy/sikevadb/sql/SQLSikevaDB.java b/src/fr/devinsy/sikevadb/sql/SQLSikevaDB.java
index 192de8d..6c1fcbb 100644
--- a/src/fr/devinsy/sikevadb/sql/SQLSikevaDB.java
+++ b/src/fr/devinsy/sikevadb/sql/SQLSikevaDB.java
@@ -445,6 +445,15 @@ public class SQLSikevaDB implements SikevaDB
}
}
+ /**
+ *
+ */
+ @Override
+ public void destroy() throws SikevaDBException
+ {
+ // TODO
+ }
+
/**
*
* @param id