From 3b8d35405ccf194fede69da3c158aa0753860bfd Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 07:13:56 +0300 Subject: [PATCH 01/13] ???????? --- .../gudkov394/telnet/RemoteTableProviderFactoryClass.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java index 9653fc720..3ed3199bd 100644 --- a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java +++ b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java @@ -1,9 +1,12 @@ package ru.fizteh.fivt.students.gudkov394.telnet; + import ru.fizteh.fivt.storage.structured.RemoteTableProvider; import ru.fizteh.fivt.storage.structured.RemoteTableProviderFactory; import java.io.IOException; - +/** + * Created by kagudkov on 07.12.14. + */ public class RemoteTableProviderFactoryClass implements RemoteTableProviderFactory { @Override From 9622715c8dcf8cdc37077867bd60b43a4affc174 Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 07:14:16 +0300 Subject: [PATCH 02/13] Revert "????????" This reverts commit 3b8d35405ccf194fede69da3c158aa0753860bfd. --- .../gudkov394/telnet/RemoteTableProviderFactoryClass.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java index 3ed3199bd..9653fc720 100644 --- a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java +++ b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java @@ -1,12 +1,9 @@ package ru.fizteh.fivt.students.gudkov394.telnet; - import ru.fizteh.fivt.storage.structured.RemoteTableProvider; import ru.fizteh.fivt.storage.structured.RemoteTableProviderFactory; import java.io.IOException; -/** - * Created by kagudkov on 07.12.14. - */ + public class RemoteTableProviderFactoryClass implements RemoteTableProviderFactory { @Override From ab326f374435c59822acf733a92acb2a69df01cb Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 07:15:38 +0300 Subject: [PATCH 03/13] ??? --- .gitignore | 3 ++- .../telnet/RemoteTableProviderFactoryClass.java | 13 ------------- 2 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java diff --git a/.gitignore b/.gitignore index 8256e2aa4..6ec87e8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,5 @@ workbench.xmi .settings .checkstyle /MultiFileHashMap/nbproject/private/ -/MultiFileHashMap/build/ \ No newline at end of file +/MultiFileHashMap/build/ +src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java \ No newline at end of file diff --git a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java deleted file mode 100644 index 9653fc720..000000000 --- a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java +++ /dev/null @@ -1,13 +0,0 @@ -package ru.fizteh.fivt.students.gudkov394.telnet; -import ru.fizteh.fivt.storage.structured.RemoteTableProvider; -import ru.fizteh.fivt.storage.structured.RemoteTableProviderFactory; - -import java.io.IOException; - -public class RemoteTableProviderFactoryClass implements RemoteTableProviderFactory { - - @Override - public RemoteTableProvider connect(String hostname, int port) throws IOException { - return null; - } -} From 45d58c36beca218f1ba88ffc3e9631424822a02d Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 10:05:03 +0300 Subject: [PATCH 04/13] First. --- .../Storeable/database/FileUtils.java | 65 +++ .../Storeable/database/TableByVolodden.java | 393 ++++++++++++++ .../database/TableProviderByVolodden.java | 142 +++++ .../TableProviderFactoryByVolodden.java | 20 + .../DatabaseCorruptedException.java | 11 + .../DatabaseReadErrorException.java | 11 + .../DatabaseWriteErrorException.java | 11 + ...nterpreterInvalidCommandNameException.java | 11 + .../exceptions/ProhibitedAccessException.java | 11 + .../exceptions/SomethingWrongException.java | 11 + .../exceptions/WrongInputException.java | 11 + .../WrongQuantityOfArgumentsException.java | 11 + .../Storeable/interpreter/Command.java | 19 + .../Storeable/interpreter/CommandHandler.java | 48 ++ .../Storeable/interpreter/Interpreter.java | 67 +++ .../interpreter/InterpreterState.java | 5 + .../commands/CommandProviderCreate.java | 40 ++ .../commands/CommandProviderDrop.java | 38 ++ .../commands/CommandProviderUse.java | 43 ++ .../commands/CommandTableCommit.java | 37 ++ .../interpreter/commands/CommandTableGet.java | 42 ++ .../commands/CommandTableList.java | 46 ++ .../interpreter/commands/CommandTablePut.java | 43 ++ .../commands/CommandTableRemove.java | 42 ++ .../commands/CommandTableRollback.java | 37 ++ .../commands/CommandTableSize.java | 36 ++ .../StoreableByVolodden.java | 119 +++++ .../TableByVolodden.java | 491 ++++++++++++++++++ .../Storeable/main/ErrorFunctions.java | 59 +++ .../Volodin_Denis/Storeable/main/JUnit.java | 46 ++ .../Storeable/main/ReturnCodes.java | 6 + .../main/StringInterpreterState.java | 26 + .../Storeable/strings/Table.java | 82 +++ .../Storeable/strings/TableProvider.java | 34 ++ .../strings/TableProviderFactory.java | 19 + .../structured/ColumnFormatException.java | 23 + .../Storeable/structured/Index.java | 26 + .../Storeable/structured/IndexProvider.java | 30 ++ .../structured/RemoteTableProvider.java | 9 + .../RemoteTableProviderFactory.java | 22 + .../Storeable/structured/Storeable.java | 96 ++++ .../Storeable/structured/Table.java | 92 ++++ .../Storeable/structured/TableProvider.java | 106 ++++ .../structured/TableProviderFactory.java | 22 + .../Storeable/tests/ErrorFunctionsTest.java | 69 +++ .../Storeable/tests/FileUtilsTest.java | 109 ++++ .../Storeable/tests/ReturnCodesTest.java | 15 + .../Storeable/tests/TableByVoloddenTest.java | 254 +++++++++ .../tests/TableProviderByVoloddenTest.java | 83 +++ .../TableProviderFactoryByVoloddenTest.java | 18 + 50 files changed, 3107 insertions(+) create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/FileUtils.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseCorruptedException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseReadErrorException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseWriteErrorException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/InterpreterInvalidCommandNameException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/ProhibitedAccessException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/SomethingWrongException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongInputException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongQuantityOfArgumentsException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/InterpreterState.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ErrorFunctions.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ReturnCodes.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/ColumnFormatException.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Index.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/IndexProvider.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProvider.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProviderFactory.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Storeable.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Table.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProvider.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProviderFactory.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ErrorFunctionsTest.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/FileUtilsTest.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ReturnCodesTest.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderFactoryByVoloddenTest.java diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/FileUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/FileUtils.java new file mode 100644 index 000000000..43800c77d --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/FileUtils.java @@ -0,0 +1,65 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class FileUtils { + + public static void createDirectory(final String path) throws IOException { + Files.createDirectory(Paths.get(path)); + } + + public static boolean createDirectory(final String path, final String secondPath) { + return Paths.get(path, secondPath).normalize().toFile().mkdir(); + } + + public static boolean delete(final String path, final String secondPath) { + return Paths.get(path, secondPath).normalize().toFile().delete(); + } + + public static boolean exists(final String path) { + return Paths.get(path).normalize().toFile().exists(); + } + + public static boolean exists(final String path, final String secondPath) { + return Paths.get(path, secondPath).normalize().toFile().exists(); + } + + public static Path get(final String path) { + return Paths.get(path).toAbsolutePath().normalize(); + } + + public static Path get(final String path, final String secondPath) { + return Paths.get(path, secondPath).toAbsolutePath().normalize(); + } + + public static String getFileName(final String path) { + return Paths.get(path).toAbsolutePath().normalize().getFileName().toString(); + } + + public static String getFileName(final String path, final String secondPath) { + return Paths.get(path, secondPath).normalize().getFileName().toString(); + } + + public static String getParentName(final String path) { + return Paths.get(path).normalize().getParent().getFileName().toString(); + } + + public static String getParentName(final String path, final String secondPath) { + return Paths.get(path, secondPath).normalize().getParent().getFileName().toString(); + } + + public static boolean isDirectory(final String path) { + return Paths.get(path).toAbsolutePath().normalize().toFile().isDirectory(); + } + + public static boolean isDirectory(final String path, final String secondPath) { + return Paths.get(path, secondPath).toAbsolutePath().normalize().toFile().isDirectory(); + } + + public static String toAbsolutePath(final String path) { + return Paths.get(path).toAbsolutePath().normalize().toString(); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java new file mode 100644 index 000000000..994bd4fae --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java @@ -0,0 +1,393 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +public class TableByVolodden implements Table { + + private String dbPath; + private FileMap fileMap; + + public TableByVolodden(final String path) throws Exception { + dbPath = FileUtils.toAbsolutePath(path); + fileMap = new FileMap(dbPath); + } + + //--- + class HelpMap { + public HashMap map; + public HelpMap() { + map = new HashMap(); + } + } + + class FileMap implements Map, AutoCloseable { + + private final int folders = 16; + private final int files = 16; + private final String encoding = "UTF-8"; + private final String dir = ".dir"; + private final String dat = ".dat"; + + private String databasePath; + private Map database; + private Map diff; + + public FileMap(final String dbPath) throws Exception { + databasePath = dbPath; + database = new HashMap(); + diff = new HashMap(); + if (FileUtils.exists(databasePath)) { + readFromDisk(); + } else { + FileUtils.createDirectory(databasePath); + } + } + + private void readFromDisk() throws Exception { + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) + + dat).normalize(); + if (somePath.toFile().exists()) { + try (DataInputStream input = new DataInputStream(new FileInputStream(somePath.toString()))) { + while (true) { + try { + String key = readOneWordFromDisk(input); + String value = readOneWordFromDisk(input); + + if ((Math.abs(key.hashCode()) % folders != i) + || (Math.abs(key.hashCode()) / folders % files != j)) { + throw new Exception("wrong input"); + } + database.put(key, value); + } catch (EOFException e) { + break; + } + } + } catch (Exception e) { + ErrorFunctions.errorRead(); + } + } + } + } + } + + private String readOneWordFromDisk(DataInputStream input) throws Exception { + byte[] word = new byte[input.readInt()]; + input.readFully(word); + return new String(word, encoding); + } + + private void writeOnDisk() throws Exception { + HelpMap[][] helpMap = new HelpMap[folders][files]; + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + helpMap[i][j] = new HelpMap(); + } + } + Set keys = database.keySet(); + for (String key : keys) { + helpMap[Math.abs(key.hashCode()) % folders][Math.abs(key.hashCode()) / folders % files].map + .put(key, database.get(key)); + } + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) + + dat).normalize(); + if (somePath.toFile().exists()) { + if (!somePath.toFile().delete()) { + ErrorFunctions.smthWrong("write", "file is not deleted"); + } + } + } + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); + if (somePath.toFile().exists()) { + if (!somePath.toFile().delete()) { + ErrorFunctions.smthWrong("write", "folder is not deleted"); + } + } + } + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Set keyList = helpMap[i][j].map.keySet(); + if (!keyList.isEmpty()) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); + if (!somePath.toFile().exists()) { + Files.createDirectory(somePath); + } + somePath = Paths.get(somePath.toString(), j + dat).normalize(); + Files.createFile(somePath); + + try (FileOutputStream output = new FileOutputStream(somePath.toString())) { + for (String key : keyList) { + writeOneWordOnDisk(key, output); + writeOneWordOnDisk(database.get(key), output); + } + } catch (Exception e) { + ErrorFunctions.errorWrite(); + } + } + } + } + } + + private void writeOneWordOnDisk(final String word, FileOutputStream output) throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(4); + byte[] wordByte = buffer.putInt(word.getBytes(encoding).length).array(); + output.write(wordByte); + output.write(word.getBytes(encoding)); + } + + private void upgrade() throws Exception { + for (String key : diff.keySet()) { + if (diff.get(key) == null) { + database.remove(key); + } else { + database.put(key, diff.get(key)); + } + } + diff.clear(); + writeOnDisk(); + } + + private void downgrade() { + diff.clear(); + } + + public int numUncommitedChanges() { + return diff.size(); + } + + @Override + public void close() throws Exception { + } + + //Not used. + @Override + public void clear() { + database.clear(); + diff.clear(); + } + + //Not used. + @Override + public boolean containsKey(Object key) { + if (database.containsKey(key)) { + if (diff.containsKey(key)) { + return (diff.get(key) != null); + } + return true; + } else { + return diff.containsKey(key); + } + } + + //Not used. + @Override + public boolean containsValue(Object value) { + if (diff.containsValue(value)) { + return true; + } else { + for (String key : database.keySet()) { + if (database.get(key).equals(value)) { + if (!diff.containsKey(key)) { + return true; + } + } + } + return false; + } + } + + // Not used. + @Override + public Set> entrySet() { + return null; + } + + @Override + public String get(Object key) { + if (diff.containsKey(key)) { + return diff.get(key); + } else { + return database.get(key); + } + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public Set keySet() { + + Set keysList = new HashSet(); + if (isEmpty()) { + return keysList; + } + + for (String key : database.keySet()) { + if (diff.containsKey(key)) { + if (diff.get(key) != null) { + keysList.add(key); + } + } else { + keysList.add(key); + } + } + for (String key : diff.keySet()) { + if (!keysList.contains(key)) { + keysList.add(key); + } + } + return keysList; + } + + @Override + public String put(String key, String value) { + if (diff.containsKey(key)) { + if (database.containsKey(key)) { + if (database.get(key).equals(value)) { + String oldValue = diff.get(key); + diff.remove(key); + return oldValue; + } else { + return diff.put(key, value); + } + } else { + return diff.put(key, value); + } + } else { + if (database.containsKey(key)) { + if (database.get(key).equals(value)) { + return database.get(key); + } else { + diff.put(key, value); + return database.get(key); + } + } else { + return diff.put(key, value); + } + } + } + + // Not used. + @Override + public void putAll(Map m) { + return; + } + + @Override + public String remove(Object key) { + if (diff.containsKey(key)) { + if (diff.get(key) == null) { + return null; + } else { + return diff.put((String) key, null); + } + } else { + if (database.containsKey(key)) { + diff.put((String) key, null); + } + return database.get(key); + } + } + + @Override + public int size() { + int result = database.size(); + for (String key : database.keySet()) { + if (diff.containsKey(key)) { + if (diff.get(key) == null) { + --result; + } + } + } + for (String key : diff.keySet()) { + if (!database.containsKey(key)) { + if (diff.get(key) != null) { + ++result; + } + } + } + return result; + } + + // Not used. + @Override + public Collection values() { + return null; + } + } + + //--- + + @Override + public String getName() { + return FileUtils.getFileName(dbPath); + } + + @Override + public String get(final String key) { + return fileMap.get(key); + } + + @Override + public String put(String key, String value) { + return fileMap.put(key, value); + } + + @Override + public String remove(String key) { + return fileMap.remove(key); + } + + @Override + public int size() { + return fileMap.size(); + } + + @Override + public int getNumberOfUncommittedChanges() { + return fileMap.numUncommitedChanges(); + } + + @Override + public int commit() { + int changes = 0; + try { + fileMap.upgrade(); + } catch (Exception exception) { + exception.printStackTrace(); + } + return changes; + } + + @Override + public int rollback() { + int changes = fileMap.numUncommitedChanges(); + fileMap.downgrade(); + return changes; + } + + @Override + public List list() { + List keys = new ArrayList(); + for (String key : fileMap.keySet()) { + keys.add(key); + } + return keys; + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java new file mode 100644 index 000000000..1f8683e51 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java @@ -0,0 +1,142 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashSet; +import java.util.Set; + +public class TableProviderByVolodden implements TableProvider { + + private String dbPath; + private Set tables; + + public TableProviderByVolodden(String dir) throws Exception { + dbPath = FileUtils.toAbsolutePath(dir); + if (!FileUtils.exists(dbPath)) { + FileUtils.createDirectory(dbPath); + } + tables = readOldTables(Paths.get(dbPath)); + } + + @Override + public Table getTable(String name) throws IllegalArgumentException { + if (!FileUtils.exists(dbPath, name)) { + ErrorFunctions.notExists("get table", name); + } + Table dbTable; + try { + dbTable = new TableByVolodden(FileUtils.get(dbPath, name).toString()); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + return dbTable; + } + + @Override + public Table createTable(String name) throws IllegalArgumentException { + if (name == null) { + ErrorFunctions.nameIsNull("create", name); + } + Table dbTable = null; + if (FileUtils.exists(dbPath, name)) { + if (!FileUtils.isDirectory(dbPath, name)) { + ErrorFunctions.tableNameIsFile("create", name); + } + } else { + boolean exists = false; + try { + exists = FileUtils.createDirectory(dbPath, name); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + if (exists) { + try { + dbTable = new TableByVolodden(Paths.get(dbPath, name).normalize().toFile().toString()); + tables.add(name); + } catch (Exception exception) { + exception.printStackTrace(); + } + } else { + ErrorFunctions.notMkdir("create", name); + } + } + return dbTable; + } + + @Override + public void removeTable(String name) throws IllegalArgumentException, IllegalStateException { + if (!FileUtils.exists(dbPath, name)) { + throw new IllegalStateException("[" + name + "] not exists"); + } + if (!FileUtils.getParentName(dbPath, name).equals(FileUtils.getFileName(dbPath))) { + ErrorFunctions.notExists("drop", name); + } + if (!FileUtils.isDirectory(dbPath)) { + ErrorFunctions.notDirectory("drop", name); + } + + try { + recursiveDrop(FileUtils.get(dbPath)); + tables.remove(name); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + + private static void recursiveDrop(final Path pathToFile) throws Exception { + if (!pathToFile.toFile().exists()) { + return; + } + if (pathToFile.toFile().isFile()) { + if (!pathToFile.toFile().delete()) { + ErrorFunctions.smthWrong("drop"); + } + } + try { + if (pathToFile.toFile().isDirectory()) { + String[] names = pathToFile.toFile().list(); + if (names.length != 0) { + for (String name : names) { + if (FileUtils.isDirectory(pathToFile.toString(), name)) { + recursiveDrop(Paths.get(pathToFile.toString(), name).normalize()); + } else { + if (!FileUtils.delete(pathToFile.toString(), name)) { + ErrorFunctions.smthWrong("drop"); + } + } + } + } + if (!pathToFile.toFile().delete()) { + ErrorFunctions.smthWrong("drop"); + } + } + } catch (SecurityException secException) { + ErrorFunctions.security("drop", secException.getMessage()); + } + } + + private Set readOldTables(final Path path) throws Exception { + Set setOfNames = new HashSet(); + String[] names = path.toFile().list(); + try { + for (String name : names) { + if (FileUtils.isDirectory(path.toString(), name)) { + Table temp = new TableByVolodden(name); + temp.size(); + setOfNames.add(name); + } else { + Files.delete(Paths.get(dbPath, name)); + } + } + return setOfNames; + } catch (Exception exception) { + ErrorFunctions.smthWrong("read"); + return null; + } + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java new file mode 100644 index 000000000..0a5e187e4 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java @@ -0,0 +1,20 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProviderFactory; + +public class TableProviderFactoryByVolodden implements TableProviderFactory { + + @Override + public TableProviderByVolodden create(String dir) { + if (dir == null) { + throw new IllegalArgumentException("wrong directory"); + } + + try { + return new TableProviderByVolodden(dir); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseCorruptedException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseCorruptedException.java new file mode 100644 index 000000000..aabfa642d --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseCorruptedException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class DatabaseCorruptedException extends Exception { + public DatabaseCorruptedException() { + super(); + } + + public DatabaseCorruptedException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseReadErrorException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseReadErrorException.java new file mode 100644 index 000000000..86b315630 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseReadErrorException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class DatabaseReadErrorException extends Exception { + public DatabaseReadErrorException() { + super(); + } + + public DatabaseReadErrorException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseWriteErrorException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseWriteErrorException.java new file mode 100644 index 000000000..89df5aec9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/DatabaseWriteErrorException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class DatabaseWriteErrorException extends Exception { + public DatabaseWriteErrorException() { + super(); + } + + public DatabaseWriteErrorException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/InterpreterInvalidCommandNameException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/InterpreterInvalidCommandNameException.java new file mode 100644 index 000000000..a3ec322c5 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/InterpreterInvalidCommandNameException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class InterpreterInvalidCommandNameException extends Exception { + public InterpreterInvalidCommandNameException() { + super(); + } + + public InterpreterInvalidCommandNameException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/ProhibitedAccessException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/ProhibitedAccessException.java new file mode 100644 index 000000000..197289854 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/ProhibitedAccessException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class ProhibitedAccessException extends Exception { + public ProhibitedAccessException() { + super(); + } + + public ProhibitedAccessException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/SomethingWrongException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/SomethingWrongException.java new file mode 100644 index 000000000..66a5cade9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/SomethingWrongException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class SomethingWrongException extends Exception { + public SomethingWrongException() { + super(); + } + + public SomethingWrongException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongInputException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongInputException.java new file mode 100644 index 000000000..8e0f3a858 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongInputException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class WrongInputException extends Exception { + public WrongInputException() { + super(); + } + + public WrongInputException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongQuantityOfArgumentsException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongQuantityOfArgumentsException.java new file mode 100644 index 000000000..952b67289 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/exceptions/WrongQuantityOfArgumentsException.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions; + +public class WrongQuantityOfArgumentsException extends Exception { + public WrongQuantityOfArgumentsException() { + super(); + } + + public WrongQuantityOfArgumentsException(final String message) { + super(message); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java new file mode 100644 index 000000000..72fec86a8 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java @@ -0,0 +1,19 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +public abstract class Command { + + protected String name; + protected int quantityOfArguments; + + protected static void tableIsNull(final Table table) throws Exception { + if (table == null) { + System.out.print("no table"); + throw new Exception(); + } + } + + public abstract CommandHandler create(); + +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java new file mode 100644 index 000000000..33d47ce81 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java @@ -0,0 +1,48 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; + +import java.util.function.BiConsumer; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; + +public class CommandHandler { + + private String name; + private int quantityOfArguments; + private BiConsumer callback; + + public CommandHandler(String name, int quantityOfArguments, + BiConsumer callback) { + this.name = name; + this.quantityOfArguments = quantityOfArguments; + this.callback = callback; + } + + public CommandHandler(final String name, final int quantityOfArguments) { + this.name = name; + this.quantityOfArguments = quantityOfArguments; + } + + public String getName() { + return name; + } + + private void checkQuantityOfArguments(final String[] args, + final String commandName) throws Exception { + if (args.length != quantityOfArguments) { + ErrorFunctions.wrongQuantityOfArguments(commandName); + } + if (args.length > 1) { + for (int i = 1; i < args.length; ++i) { + if (args[i].isEmpty()) { + ErrorFunctions.wrongInput(commandName); + } + } + } + } + + public void execute(InterpreterState interpreterState, String[] args) throws Exception { + checkQuantityOfArguments(args, name); + + callback.accept(interpreterState, args); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java new file mode 100644 index 000000000..48953e849 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java @@ -0,0 +1,67 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ReturnCodes; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +public class Interpreter { + + private final String promt = "$ "; + private final String statementDelimiter = ";"; + private final String paramRegExp = "\\s+"; + + private final Map commands; + private final InterpreterState interpreterState; + + public Interpreter(InterpreterState interpreter, CommandHandler[] comms) { + commands = new HashMap(); + interpreterState = interpreter; + for (CommandHandler command : comms) { + commands.put(command.getName(), command); + } + } + + private void executeLine(final String[] input) { + for (int i = 0; i < input.length; ++i) { + if (input[i].length() > 0) { + String[] buffer = input[i].trim().split(paramRegExp); + String commandName = buffer[0]; + if (commandName.equals("exit")) { + System.exit(ReturnCodes.SUCCESS); + } + CommandHandler command = commands.get(commandName); + if (command == null) { + System.err.println("Command does not exist: [" + commandName + "]"); + return; + } + try { + command.execute(interpreterState, Arrays.copyOfRange(buffer, 1, buffer.length)); + } catch (Exception exception) { + System.err.println(exception.getMessage()); + } + } + } + } + + public void run(String[] args) { + while (args.length == 0) { + try (Scanner scanner = new Scanner(System.in)) { + System.out.print(promt); + String[] input = scanner.nextLine().split(statementDelimiter); + executeLine(input); + } catch (Throwable exception) { + System.err.println("Smth wrong: " + exception.getMessage()); + System.exit(ReturnCodes.ERROR); + } + } + StringBuilder helpArray = new StringBuilder(); + for (int i = 0; i < args.length; ++i) { + helpArray.append(args[i]).append(' '); + } + String[] input = helpArray.toString().split(statementDelimiter); + executeLine(input); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/InterpreterState.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/InterpreterState.java new file mode 100644 index 000000000..49b1bb6b9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/InterpreterState.java @@ -0,0 +1,5 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; + +public interface InterpreterState { + +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java new file mode 100644 index 000000000..67bf111cd --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java @@ -0,0 +1,40 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; + +import java.util.function.BiConsumer; + +public class CommandProviderCreate extends Command { + + public CommandProviderCreate() { + name = "create"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + TableProvider tableProvider = state.getTableProvider(); + + try { + tableProvider.getTable(args[0]); + System.out.println(name + " exists"); + } catch (IllegalArgumentException e) { + Table table = tableProvider.createTable(args[0]); + if (table != null) { + System.out.println("created"); + } + } + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java new file mode 100644 index 000000000..bbc73e0d5 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java @@ -0,0 +1,38 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; + +import java.util.function.BiConsumer; + +public class CommandProviderDrop extends Command { + + public CommandProviderDrop() { + name = "drop"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + TableProvider tableProvider = state.getTableProvider(); + + try { + tableProvider.removeTable(args[0]); + System.out.println("dropped"); + } catch (IllegalArgumentException e) { + System.err.println(e.getMessage()); + } catch (IllegalStateException e) { + System.err.println(e.getMessage()); + } + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java new file mode 100644 index 000000000..0ec176010 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java @@ -0,0 +1,43 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandProviderUse extends Command { + + public CommandProviderUse() { + name = "use"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + if (table.getName().equals(args[0])) { + System.out.println("[" + args[0] + "] already used"); + return; + } + int changes = table.getNumberOfUncommittedChanges(); + if (changes != 0) { + System.out.println(changes + " unsaved changes"); + return; + } + try { + state.setTable(state.getTableProvider().getTable(args[0])); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java new file mode 100644 index 000000000..d1d9c6777 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java @@ -0,0 +1,37 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTableCommit extends Command { + + public CommandTableCommit() { + name = "commit"; + quantityOfArguments = 0; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + System.out.println(table.commit()); + state.setTable(table); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java new file mode 100644 index 000000000..b2a2a55c7 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java @@ -0,0 +1,42 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTableGet extends Command { + + public CommandTableGet() { + name = "get"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + String value = table.get(args[0]); + if (value == null) { + System.out.println("not found"); + } else { + System.out.println("found"); + System.out.println(value); + } + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java new file mode 100644 index 000000000..3db497ce9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java @@ -0,0 +1,46 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.List; +import java.util.function.BiConsumer; + +public class CommandTableList extends Command { + + public CommandTableList() { + name = "list"; + quantityOfArguments = 0; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + List list = table.list(); + int i = list.size(); + for (String key : list) { + System.out.print(key); + --i; + if (i > 0) { + System.out.print(", "); + } + } + System.out.println(); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java new file mode 100644 index 000000000..8917f08c7 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java @@ -0,0 +1,43 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTablePut extends Command { + + public CommandTablePut() { + name = "put"; + quantityOfArguments = 2; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + String value = table.put(args[0], args[1]); + if (value == null) { + System.out.println("new"); + } else { + System.out.println("overwrite"); + System.out.println(value); + } + state.setTable(table); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java new file mode 100644 index 000000000..3541f00ea --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java @@ -0,0 +1,42 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTableRemove extends Command { + + public CommandTableRemove() { + name = "remove"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + String value = table.remove(args[0]); + if (value == null) { + System.out.println("not found"); + } else { + System.out.println("removed"); + } + state.setTable(table); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java new file mode 100644 index 000000000..10c601526 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java @@ -0,0 +1,37 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTableRollback extends Command { + + public CommandTableRollback() { + name = "rollback"; + quantityOfArguments = 1; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + System.out.println(table.rollback()); + state.setTable(table); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java new file mode 100644 index 000000000..ff114c044 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java @@ -0,0 +1,36 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import java.util.function.BiConsumer; + +public class CommandTableSize extends Command { + + public CommandTableSize() { + name = "size"; + quantityOfArguments = 0; + } + + @Override + public CommandHandler create() { + return new CommandHandler(name, quantityOfArguments, + new BiConsumer() { + @Override + public void accept(InterpreterState interpreterState, String[] args) { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + System.out.println(table.size()); + } + }); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java new file mode 100644 index 000000000..8f1e12b83 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java @@ -0,0 +1,119 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; + +import java.util.List; + +public class StoreableByVolodden implements Storeable{ + + private List> types; + private List values; + + StoreableByVolodden(String string, List> _types) { + types = _types; + String[] array = string.split(", "); + for (int i = 0; i < array.length; ++i) { + if (array[i] == "null") { + values.add(null); + } + if (types.get(i) == Integer.class) { + values.add(Integer.parseInt(array[i])); + } + if (types.get(i) == Long.class) { + values.add(Long.parseLong(array[i])); + } + if (types.get(i) == Byte.class) { + values.add(Byte.parseByte(array[i])); + } + if (types.get(i) == Float.class) { + values.add(Float.parseFloat(array[i])); + } + if (types.get(i) == Double.class) { + values.add(Double.parseDouble(array[i])); + } + if (types.get(i) == Boolean.class) { + values.add(Boolean.parseBoolean(array[i])); + } + if (types.get(i) == String.class) { + values.add(array[i]); + } + } + } + + @Override + public void setColumnAt(int columnIndex, Object value) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + if (value != null) { + checkFormat(columnIndex, value.getClass()); + } + values.set(columnIndex, value); + } + + @Override + public Object getColumnAt(int columnIndex) throws IndexOutOfBoundsException { + checkBounds(columnIndex); + return values.get(columnIndex); + } + + @Override + public Integer getIntAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Integer.class); + return (Integer) values.get(columnIndex); + } + + @Override + public Long getLongAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Long.class); + return (Long) values.get(columnIndex); + } + + @Override + public Byte getByteAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Byte.class); + return (Byte) values.get(columnIndex); + } + + @Override + public Float getFloatAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Float.class); + return (Float) values.get(columnIndex); + } + + @Override + public Double getDoubleAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Double.class); + return (Double) values.get(columnIndex); + } + + @Override + public Boolean getBooleanAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, Boolean.class); + return (Boolean) values.get(columnIndex); + } + + @Override + public String getStringAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException { + checkBounds(columnIndex); + checkFormat(columnIndex, String.class); + return (String) values.get(columnIndex); + } + + private void checkBounds(int index) throws IndexOutOfBoundsException { + if (index >= types.size()) { + throw new IndexOutOfBoundsException("Invalid index."); + } + } + + private void checkFormat(int index, Class type) throws ColumnFormatException { + if (!types.get(index).equals(type)) { + throw new ColumnFormatException("Invalid format."); + } + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java new file mode 100644 index 000000000..b1472d06e --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java @@ -0,0 +1,491 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions.DatabaseCorruptedException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; + +public class TableByVolodden implements Table { + + private String dbPath; + private FileMap fileMap; + private List> types; + + private final String signatureFileName = "signature.tsv"; + + public TableByVolodden(final String path) throws Exception { + dbPath = FileUtils.toAbsolutePath(path); + fileMap = new FileMap(dbPath); + } + + //--- + class HelpMap { + public HashMap map; + public HelpMap() { + map = new HashMap(); + } + } + + class FileMap implements Map, AutoCloseable { + + private final int folders = 16; + private final int files = 16; + private final String encoding = "UTF-8"; + private final String dir = ".dir"; + private final String dat = ".dat"; + + private String databasePath; + private Map database; + private Map diff; + + public FileMap(final String dbPath) throws Exception { + databasePath = dbPath; + database = new HashMap(); + diff = new HashMap(); + if (FileUtils.exists(databasePath)) { + readFromDisk(); + readTypes(); + } else { + throw new Exception("Table was not found"); + } + } + + private void readTypes() throws DatabaseCorruptedException { + types = new ArrayList<>(); + List list; + try (Scanner in = new Scanner(new File(FileUtils.get(dbPath, signatureFileName).toString()))) { + list = Arrays.asList(in.nextLine().split("\\s+")); + for (String type : list) { + types.add(stringToType(type)); + } + } catch (FileNotFoundException e) { + throw new DatabaseCorruptedException("Can't find a file with signatures."); + } catch (IllegalArgumentException e) { + throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); + } catch (NoSuchElementException e) { + throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); + } + } + + private void readFromDisk() throws Exception { + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) + + dat).normalize(); + if (somePath.toFile().exists()) { + try (DataInputStream input = new DataInputStream(new FileInputStream(somePath.toString()))) { + while (true) { + try { + String key = readOneWordFromDisk(input); + String value = readOneWordFromDisk(input); + + if ((Math.abs(key.hashCode()) % folders != i) + || (Math.abs(key.hashCode()) / folders % files != j)) { + throw new Exception("wrong input"); + } + database.put(key, value); + } catch (EOFException e) { + break; + } + } + } catch (Exception e) { + ErrorFunctions.errorRead(); + } + } + } + } + } + + private String readOneWordFromDisk(DataInputStream input) throws Exception { + byte[] word = new byte[input.readInt()]; + input.readFully(word); + return new String(word, encoding); + } + + private void writeOnDisk() throws Exception { + HelpMap[][] helpMap = new HelpMap[folders][files]; + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + helpMap[i][j] = new HelpMap(); + } + } + Set keys = database.keySet(); + for (String key : keys) { + helpMap[Math.abs(key.hashCode()) % folders][Math.abs(key.hashCode()) / folders % files].map + .put(key, database.get(key)); + } + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) + + dat).normalize(); + if (somePath.toFile().exists()) { + if (!somePath.toFile().delete()) { + ErrorFunctions.smthWrong("write", "file is not deleted"); + } + } + } + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); + if (somePath.toFile().exists()) { + if (!somePath.toFile().delete()) { + ErrorFunctions.smthWrong("write", "folder is not deleted"); + } + } + } + for (int i = 0; i < folders; ++i) { + for (int j = 0; j < files; ++j) { + Set keyList = helpMap[i][j].map.keySet(); + if (!keyList.isEmpty()) { + Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); + if (!somePath.toFile().exists()) { + Files.createDirectory(somePath); + } + somePath = Paths.get(somePath.toString(), j + dat).normalize(); + Files.createFile(somePath); + + try (FileOutputStream output = new FileOutputStream(somePath.toString())) { + for (String key : keyList) { + writeOneWordOnDisk(key, output); + writeOneWordOnDisk(database.get(key), output); + } + } catch (Exception e) { + ErrorFunctions.errorWrite(); + } + } + } + } + } + + private void writeOneWordOnDisk(final String word, FileOutputStream output) throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(4); + byte[] wordByte = buffer.putInt(word.getBytes(encoding).length).array(); + output.write(wordByte); + output.write(word.getBytes(encoding)); + } + + private void upgrade() throws Exception { + for (String key : diff.keySet()) { + if (diff.get(key) == null) { + database.remove(key); + } else { + database.put(key, diff.get(key)); + } + } + diff.clear(); + writeOnDisk(); + } + + private void downgrade() { + diff.clear(); + } + + public int numUncommitedChanges() { + return diff.size(); + } + + @Override + public void close() throws Exception { + } + + //Not used. + @Override + public void clear() { + database.clear(); + diff.clear(); + } + + //Not used. + @Override + public boolean containsKey(Object key) { + if (database.containsKey(key)) { + if (diff.containsKey(key)) { + return (diff.get(key) != null); + } + return true; + } else { + return diff.containsKey(key); + } + } + + //Not used. + @Override + public boolean containsValue(Object value) { + if (diff.containsValue(value)) { + return true; + } else { + for (String key : database.keySet()) { + if (database.get(key).equals(value)) { + if (!diff.containsKey(key)) { + return true; + } + } + } + return false; + } + } + + // Not used. + @Override + public Set> entrySet() { + return null; + } + + @Override + public String get(Object key) { + if (diff.containsKey(key)) { + return diff.get(key); + } else { + return database.get(key); + } + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public Set keySet() { + + Set keysList = new HashSet(); + if (isEmpty()) { + return keysList; + } + + for (String key : database.keySet()) { + if (diff.containsKey(key)) { + if (diff.get(key) != null) { + keysList.add(key); + } + } else { + keysList.add(key); + } + } + for (String key : diff.keySet()) { + if (!keysList.contains(key)) { + keysList.add(key); + } + } + return keysList; + } + + @Override + public String put(String key, String value) { + if (diff.containsKey(key)) { + if (database.containsKey(key)) { + if (database.get(key).equals(value)) { + String oldValue = diff.get(key); + diff.remove(key); + return oldValue; + } else { + return diff.put(key, value); + } + } else { + return diff.put(key, value); + } + } else { + if (database.containsKey(key)) { + if (database.get(key).equals(value)) { + return database.get(key); + } else { + diff.put(key, value); + return database.get(key); + } + } else { + return diff.put(key, value); + } + } + } + + // Not used. + @Override + public void putAll(Map m) { + return; + } + + @Override + public String remove(Object key) { + if (diff.containsKey(key)) { + if (diff.get(key) == null) { + return null; + } else { + return diff.put((String) key, null); + } + } else { + if (database.containsKey(key)) { + diff.put((String) key, null); + } + return database.get(key); + } + } + + @Override + public int size() { + int result = database.size(); + for (String key : database.keySet()) { + if (diff.containsKey(key)) { + if (diff.get(key) == null) { + --result; + } + } + } + for (String key : diff.keySet()) { + if (!database.containsKey(key)) { + if (diff.get(key) != null) { + ++result; + } + } + } + return result; + } + + // Not used. + @Override + public Collection values() { + return null; + } + } + + //--- + + @Override + public Storeable put(String key, Storeable value) throws ColumnFormatException { + return stringToStoreable(fileMap.put(key, storeableToString(value))); + } + + @Override + public Storeable remove(String key) { + return stringToStoreable(fileMap.remove(key)); + } + + @Override + public int size() { + return fileMap.size(); + } + + @Override + public List list() { + List keys = new ArrayList(); + for (String key : fileMap.keySet()) { + keys.add(key); + } + return keys; + } + + @Override + public int commit() { + int changes = 0; + try { + fileMap.upgrade(); + } catch (Exception exception) { + exception.printStackTrace(); + } + return changes; + } + + @Override + public int rollback() { + int changes = fileMap.numUncommitedChanges(); + fileMap.downgrade(); + return changes; + } + + @Override + public int getNumberOfUncommittedChanges() { + return fileMap.numUncommitedChanges(); + } + + @Override + public int getColumnsCount() { + return types.size(); + } + + @Override + public Class getColumnType(int columnIndex) throws IndexOutOfBoundsException { + return types.get(columnIndex); + } + + @Override + public String getName() { + return FileUtils.getFileName(dbPath); + } + + @Override + public Storeable get(String key) { + return stringToStoreable(fileMap.get(key)); + } + + private Storeable stringToStoreable(String string) { + return new StoreableByVolodden(string, types); + } + + private String storeableToString(Storeable storeable) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < getColumnsCount(); ++i) { + builder.append(valueInStoreable(storeable, i)).append(", "); + } + builder.deleteCharAt(builder.length() - 1); + builder.deleteCharAt(builder.length() - 1); + builder.append("]"); + return builder.toString(); + } + + private String valueInStoreable(Storeable storeable, int index) { + Class type = getColumnType(index); + if (type == Integer.class) { + return storeable.getIntAt(index).toString(); + } + if (type == Long.class) { + return storeable.getLongAt(index).toString(); + } + if (type == Byte.class) { + return storeable.getByteAt(index).toString(); + } + if (type == Float.class) { + return storeable.getFloatAt(index).toString(); + } + if (type == Double.class) { + return storeable.getDoubleAt(index).toString(); + } + if (type == Boolean.class) { + return storeable.getBooleanAt(index).toString(); + } + if (type == String.class) { + return storeable.getStringAt(index).toString(); + } + return "null"; + } + + private Class stringToType(String string) { + if (string.equals("int")) { + return Integer.class; + } + if (string.equals("long")) { + return Long.class; + } + if (string.equals("byte")) { + return Byte.class; + } + if (string.equals("float")) { + return Float.class; + } + if (string.equals("double")) { + return Double.class; + } + if (string.equals("bool")) { + return Boolean.class; + } + if (string.equals("string")) { + return String.class; + } + throw new NoSuchElementException(); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ErrorFunctions.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ErrorFunctions.java new file mode 100644 index 000000000..db8594ab7 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ErrorFunctions.java @@ -0,0 +1,59 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions.*; + +public class ErrorFunctions { + + public static void errorRead() throws DatabaseReadErrorException { + throw new DatabaseReadErrorException("error reading from file"); + } + + public static void errorWrite() throws DatabaseWriteErrorException { + throw new DatabaseWriteErrorException("error writing to file"); + } + + public static void invalidName(final String commandName, final String arg) + throws InterpreterInvalidCommandNameException { + throw new InterpreterInvalidCommandNameException(commandName + ": [" + arg + "] is invalid name."); + } + + public static void nameIsNull(final String commandName, final String arg) throws IllegalArgumentException { + throw new IllegalArgumentException(commandName + ": [" + arg + "] is null."); + } + + public static void notDirectory(final String commandName, final String arg) throws IllegalStateException { + throw new IllegalStateException(commandName + ": [" + arg + "] is not a directory."); + } + + public static void notExists(final String commandName, final String arg) throws IllegalStateException { + throw new IllegalStateException(commandName + ": [" + arg + "] does not exists."); + } + + public static void notMkdir(final String commandName, final String arg) throws IllegalArgumentException { + throw new IllegalArgumentException(commandName + ": failed to create a directory [" + arg + "]."); + } + + public static void security(final String commandName, final String arg) throws ProhibitedAccessException { + throw new ProhibitedAccessException(commandName + ": access to the [" + arg + "] is prohibited."); + } + + public static void smthWrong(final String commandName) throws SomethingWrongException { + throw new SomethingWrongException(commandName + "something gone wrong."); + } + + public static void smthWrong(final String commandName, final String message) throws SomethingWrongException { + throw new SomethingWrongException(commandName + " :" + message); + } + + public static void tableNameIsFile(final String commandName, final String arg) throws IllegalArgumentException { + throw new IllegalArgumentException(commandName + ": [" + arg + "] is file"); + } + + public static void wrongInput(final String commandName) throws WrongInputException { + throw new WrongInputException(commandName + ": wrong input."); + } + + public static void wrongQuantityOfArguments(final String commandName) throws WrongQuantityOfArgumentsException { + throw new WrongQuantityOfArgumentsException(commandName + ": wrong quantity of arguments."); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java new file mode 100644 index 000000000..19c23cf07 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java @@ -0,0 +1,46 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProviderFactory; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderFactoryByVolodden; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Interpreter; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderCreate; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderDrop; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderUse; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableCommit; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableGet; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableList; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTablePut; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableRemove; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableSize; + +public class JUnit { + + public static void main(final String[] args) { + try { + TableProviderFactory tpf = new TableProviderFactoryByVolodden(); + String dir = System.getProperty("fizteh.db.dir"); + TableProvider tableProvider = tpf.create(dir); + InterpreterState interpreterState = new StringInterpreterState(tableProvider); + new Interpreter(interpreterState, + new CommandHandler[] { + new CommandTableGet().create(), + new CommandTableList().create(), + new CommandTablePut().create(), + new CommandTableRemove().create(), + new CommandTableSize().create(), + new CommandTableCommit().create(), + new CommandProviderCreate().create(), + new CommandProviderDrop().create(), + new CommandTableCommit().create(), + new CommandProviderUse().create()}) + .run(args); + } catch (Exception exception) { + System.err.println(exception.getMessage()); + System.exit(ReturnCodes.ERROR); + } + System.exit(ReturnCodes.SUCCESS); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ReturnCodes.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ReturnCodes.java new file mode 100644 index 000000000..6a94dce09 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/ReturnCodes.java @@ -0,0 +1,6 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; + +public class ReturnCodes { + public static final int SUCCESS = 0; + public static final int ERROR = 1; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java new file mode 100644 index 000000000..96c88f0b0 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java @@ -0,0 +1,26 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; + +public class StringInterpreterState implements InterpreterState { + private TableProvider tableProvider; + private Table table; + + public StringInterpreterState(TableProvider tableProvider) { + this.tableProvider = tableProvider; + } + + public TableProvider getTableProvider() { + return tableProvider; + } + + public Table getTable() { + return table; + } + + public void setTable(Table table) { + this.table = table; + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java new file mode 100644 index 000000000..790c2994f --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java @@ -0,0 +1,82 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; + +import java.util.List; +/** + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface Table { + + /** + * Возвращает название базы данных. + */ + String getName(); + + /** + * Получает значение по указанному ключу. + * + * @param key Ключ. + * @return Значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + String get(String key) throws IllegalArgumentException; + + /** + * Устанавливает значение по указанному ключу. + * + * @param key Ключ. + * @param value Значение. + * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было записано, + * возвращает null. + * + * @throws IllegalArgumentException Если значение параметров key или value является null. + */ + String put(String key, String value) throws IllegalArgumentException; + + /** + * Удаляет значение по указанному ключу. + * + * @param key Ключ. + * @return Значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + String remove(String key) throws IllegalArgumentException; + + /** + * Возвращает количество ключей в таблице. + * + * @return Количество ключей в таблице. + */ + int size(); + + /** + * Возвращает количество изменений в таблице. + * + * @return Количество изменений в таблице. + */ + int getNumberOfUncommittedChanges(); + + /** + * Выполняет фиксацию изменений. + * + * @return Количество сохранённых ключей. + */ + int commit(); + + /** + * Выполняет откат изменений с момента последней фиксации. + * + * @return Количество отменённых ключей. + */ + int rollback(); + + /** + * Выводит список ключей таблицы + * + * @return Список ключей. + */ + List list(); +} + diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java new file mode 100644 index 000000000..fee5fb2d8 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java @@ -0,0 +1,34 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; +/** + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface TableProvider { + + /** + * Возвращает таблицу с указанным названием. + * + * @param name Название таблицы. + * @return Объект, представляющий таблицу. Если таблицы с указанным именем не существует, возвращает null. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + */ + Table getTable(String name); + + /** + * Создаёт таблицу с указанным названием. + * + * @param name Название таблицы. + * @return Объект, представляющий таблицу. Если таблица уже существует, возвращает null. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + */ + Table createTable(String name); + + /** + * Удаляет таблицу с указанным названием. + * + * @param name Название таблицы. + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + * @throws IllegalStateException Если таблицы с указанным названием не существует. + */ + void removeTable(String name); +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java new file mode 100644 index 000000000..5823e3792 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java @@ -0,0 +1,19 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; +/** + * Представляет интерфейс для создание экземпляров {@link TableProvider}. Предполагается, что реализация интерфейса + * фабрики будет иметь публичный конструктор без параметров. + * + * @author Fedor Lavrentyev + * @author Dmitriy Komanov + */ +public interface TableProviderFactory { + + /** + * Возвращает объект для работы с базой данных. + * + * @param dir Директория с файлами базы данных. + * @return Объект для работы с базой данных. + * @throws IllegalArgumentException Если значение директории null или имеет недопустимое значение. + */ + TableProvider create(String dir); +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/ColumnFormatException.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/ColumnFormatException.java new file mode 100644 index 000000000..23c575531 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/ColumnFormatException.java @@ -0,0 +1,23 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +/** + * Бросается при попытке извлечь из колонки {@link Storeable} значение не соответствующего типа, + * либо подставить в колонку значение несоответствующего типа. + */ +public class ColumnFormatException extends IllegalArgumentException { + + public ColumnFormatException() { + } + + public ColumnFormatException(String s) { + super(s); + } + + public ColumnFormatException(String message, Throwable cause) { + super(message, cause); + } + + public ColumnFormatException(Throwable cause) { + super(cause); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Index.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Index.java new file mode 100644 index 000000000..b8cd65427 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Index.java @@ -0,0 +1,26 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +/** + * Представляет базу для интерфейс для работы с таблицей, содержащей ключи-значения. + * Используется также для доступа к поисковому индексу. + */ +public interface Index { + /** + * Возвращает название таблицы или индекса. + * + * @return Название таблицы. + */ + String getName(); + + /** + * Получает значение по указанному ключу. + * + * @param key Ключ для поиска значения. Не может быть null. + * Для индексов по не-строковым полям аргумент представляет собой сериализованное значение колонки. + * Его потребуется распарсить. + * @return Значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + Storeable get(String key); +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/IndexProvider.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/IndexProvider.java new file mode 100644 index 000000000..e7701f1a1 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/IndexProvider.java @@ -0,0 +1,30 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +/** + * Дополнительный интерфейс к {@link ru.fizteh.fivt.storage.structured.TableProvider}, позволяющий создавать индексы на + * основе имеющейся таблицы. + */ +public interface IndexProvider extends TableProvider { + /** + * + * Возвращает индекс с таким именем, если он существует. + * + * @param name Имя индекса. Не должно быть null. + * @return Объект индекса + * @throws IllegalArgumentException Если имя индекса невалидно. + */ + Index getIndex(String name) throws IllegalArgumentException; + + /** + * Создает индекс. + * + * @param table Таблица, для которой нужно создать индекс. + * @param column Номер колонки. + * @param name Имя для будущего индекса. + * @return Свежесозданный индекс. null, если индекс уже был создан. + * @throws IllegalArgumentException Если таблица невалидна, указана неверная колонка или имя индекса, + * а также, если сущность с таким именем уже существует. + * @throws IllegalStateException Если индекс содержит невалидные элементы. + */ + Index createIndex(Table table, int column, String name) throws IllegalArgumentException, IllegalStateException; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProvider.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProvider.java new file mode 100644 index 000000000..21d817b7d --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProvider.java @@ -0,0 +1,9 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +import java.io.Closeable; + +/** + * Расширенный интерфейс {@link TableProvider}, с предоставлением метода {@link #close()}. + */ +public interface RemoteTableProvider extends TableProvider, Closeable { +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProviderFactory.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProviderFactory.java new file mode 100644 index 000000000..994cd8054 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/RemoteTableProviderFactory.java @@ -0,0 +1,22 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +import java.io.IOException; + +/** + * Представляет интерфейс для подключения к удаленному хранилищу. + * + * Предполагается, что реализация интерфейса клиента будет иметь публичный конструктор без параметров. + */ +public interface RemoteTableProviderFactory { + /** + * Возвращает {@link RemoteTableProvider} для работы с удаленных хранилищем. + * + * @param hostname Имя узла, на котором работает TCP-сервер хранилища. + * @param port Порт, на котором работает TCP-сервер хранилища. + * @return Remote-{@link RemoteTableProvider}, который подключен к TCP-серверу хранилища по заданному адресу. + * + * @throws IllegalArgumentException В случае некорректных входных параметров. + * @throws java.io.IOException В случае ошибок ввода/вывода. + */ + RemoteTableProvider connect(String hostname, int port) throws IOException; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Storeable.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Storeable.java new file mode 100644 index 000000000..1fee0a0f0 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Storeable.java @@ -0,0 +1,96 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +/** + * Список фиксированной структуры, строка таблицы {@link Table}. + * + * Нумерация колонок с нуля. Позиция в списке соответствует колонке таблицы под тем же номером. + * + * С помощью {@link TableProvider} может быть сериализован или десериализован. + * + * Для получения объекта из нужной колонки воспользуйтесь соответствующим геттером. + * Для установки объекта а колонку воспользуйтесь {@link #setColumnAt(int, Object)} . + */ +public interface Storeable { + + /** + * Установить значение в колонку + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @param value - значение, которое нужно установить. + * Может быть null. + * Тип значения должен соответствовать декларированному типу колонки. + * @throws ColumnFormatException - Тип значения не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + void setColumnAt(int columnIndex, Object value) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, не приводя его к конкретному типу. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, без приведения типа. Может быть null. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Object getColumnAt(int columnIndex) throws IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Integer. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Integer. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Integer getIntAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Long. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Long. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Long getLongAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Byte. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Byte. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Byte getByteAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Float. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Float. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Float getFloatAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Double. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Double. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Double getDoubleAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к Boolean. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к Boolean. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + Boolean getBooleanAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает значение из данной колонки, приведя его к String. + * @param columnIndex - индекс колонки в таблице, начиная с нуля + * @return - значение в этой колонке, приведенное к String. Может быть null. + * @throws ColumnFormatException - Запрошенный тип не соответствует типу колонки. + * @throws IndexOutOfBoundsException - Неверный индекс колонки. + */ + String getStringAt(int columnIndex) throws ColumnFormatException, IndexOutOfBoundsException; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Table.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Table.java new file mode 100644 index 000000000..f7913a4fc --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/Table.java @@ -0,0 +1,92 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +import java.io.IOException; +import java.util.List; + +/** + * Представляет интерфейс для работы с таблицей, содержащей ключи-значения. Ключи должны быть уникальными. + * + * Транзакционность: изменения фиксируются или откатываются с помощью методов {@link #commit()} или {@link #rollback()}, + * соответственно. Предполагается, что между вызовами этих методов никаких операций ввода-вывода не происходит. + * + * Данный интерфейс не является потокобезопасным. + */ +public interface Table extends Index { + + /** + * Устанавливает значение по указанному ключу. + * + * @param key Ключ для нового значения. Не может быть null. + * @param value Новое значение. Не может быть null. + * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было записано, + * возвращает null. + * + * @throws IllegalArgumentException Если значение параметров key или value является null. + * @throws ColumnFormatException - при попытке передать Storeable с колонками другого типа. + */ + Storeable put(String key, Storeable value) throws ColumnFormatException; + + /** + * Удаляет значение по указанному ключу. + * + * @param key Ключ для поиска значения. Не может быть null. + * @return Предыдущее значение. Если не найдено, возвращает null. + * + * @throws IllegalArgumentException Если значение параметра key является null. + */ + Storeable remove(String key); + + /** + * Возвращает количество ключей в таблице. Возвращает размер текущей версии, с учётом незафиксированных изменений. + * + * @return Количество ключей в таблице. + */ + int size(); + + /** + * Выводит список ключей таблицы, с учётом незафиксированных изменений. + * + * @return Список ключей. + */ + List list(); + + /** + * Выполняет фиксацию изменений. + * + * @return Число записанных изменений. + * + * @throws java.io.IOException если произошла ошибка ввода/вывода. Целостность таблицы не гарантируется. + */ + int commit() throws IOException; + + /** + * Выполняет откат изменений с момента последней фиксации. + * + * @return Число откаченных изменений. + */ + int rollback(); + + /** + * Возвращает количество изменений, ожидающих фиксации. + * + * @return Количество изменений, ожидающих фиксации. + */ + int getNumberOfUncommittedChanges(); + + /** + * Возвращает количество колонок в таблице. + * + * @return Количество колонок в таблице. + */ + int getColumnsCount(); + + /** + * Возвращает тип значений в колонке. + * + * @param columnIndex Индекс колонки. Начинается с нуля. + * @return Класс, представляющий тип значения. + * + * @throws IndexOutOfBoundsException - неверный индекс колонки + */ + Class getColumnType(int columnIndex) throws IndexOutOfBoundsException; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProvider.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProvider.java new file mode 100644 index 000000000..527cf70c9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProvider.java @@ -0,0 +1,106 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +import java.io.IOException; +import java.text.ParseException; +import java.util.List; + +/** + * Управляющий класс для работы с {@link Table таблицами} + * + * Предполагает, что актуальная версия с устройства хранения, сохраняется при создании + * экземпляра объекта. Далее ввод-вывод выполняется только в момент создания и удаления + * таблиц. + * + * Данный интерфейс не является потокобезопасным. + */ +public interface TableProvider { + + /** + * Возвращает таблицу с указанным названием. + * + * Последовательные вызовы метода с одинаковыми аргументами должны возвращать один и тот же объект таблицы, + * если он не был удален с помощью {@link #removeTable(String)}. + * + * @param name Название таблицы. + * @return Объект, представляющий таблицу. Если таблицы с указанным именем не существует, возвращает null. + * + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + */ + Table getTable(String name); + + /** + * Создаёт таблицу с указанным названием. + * Создает новую таблицу. Совершает необходимые дисковые операции. + * + * @param name Название таблицы. + * @param columnTypes Типы колонок таблицы. Не может быть пустой. + * @return Объект, представляющий таблицу. Если таблица с указанным именем существует, возвращает null. + * + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. Если список типов + * колонок null или содержит недопустимые значения. + * @throws java.io.IOException При ошибках ввода/вывода. + */ + Table createTable(String name, List> columnTypes) throws IOException; + + /** + * Удаляет существующую таблицу с указанным названием. + * + * Объект удаленной таблицы, если был кем-то взят с помощью {@link #getTable(String)}, + * с этого момента должен бросать {@link IllegalStateException}. + * + * @param name Название таблицы. + * + * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. + * @throws IllegalStateException Если таблицы с указанным названием не существует. + * @throws java.io.IOException - при ошибках ввода/вывода. + */ + void removeTable(String name) throws IOException; + + /** + * Преобразовывает строку в объект {@link Storeable}, соответствующий структуре таблицы. + * + * @param table Таблица, которой должен принадлежать {@link Storeable}. + * @param value Строка, из которой нужно прочитать {@link Storeable}. + * @return Прочитанный {@link Storeable}. + * + * @throws ParseException - при каких-либо несоответстиях в прочитанных данных. + */ + Storeable deserialize(Table table, String value) throws ParseException; + + /** + * Преобразовывает объект {@link Storeable} в строку. + * + * @param table Таблица, которой должен принадлежать {@link Storeable}. + * @param value {@link Storeable}, который нужно записать. + * @return Строка с записанным значением. + * + * @throws ColumnFormatException При несоответствии типа в {@link Storeable} и типа колонки в таблице. + */ + String serialize(Table table, Storeable value) throws ColumnFormatException; + + /** + * Создает новый пустой {@link Storeable} для указанной таблицы. + * + * @param table Таблица, которой должен принадлежать {@link Storeable}. + * @return Пустой {@link Storeable}, нацеленный на использование с этой таблицей. + */ + Storeable createFor(Table table); + + /** + * Создает новый {@link Storeable} для указанной таблицы, подставляя туда переданные значения. + * + * @param table Таблица, которой должен принадлежать {@link Storeable}. + * @param values Список значений, которыми нужно проинициализировать поля Storeable. + * @return {@link Storeable}, проинициализированный переданными значениями. + * @throws ColumnFormatException При несоответствии типа переданного значения и колонки. + * @throws IndexOutOfBoundsException При несоответствии числа переданных значений и числа колонок. + */ + Storeable createFor(Table table, List values) throws ColumnFormatException, IndexOutOfBoundsException; + + /** + * Возвращает имена существующих таблиц, которые могут быть получены с помощью {@link #getTable(String)}. + * + * @return Имена существующих таблиц. + */ + List getTableNames(); +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProviderFactory.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProviderFactory.java new file mode 100644 index 000000000..764b7b5e0 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/structured/TableProviderFactory.java @@ -0,0 +1,22 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured; + +import java.io.IOException; + +/** + * Представляет интерфейс для создание экземпляров {@link TableProvider}. + * + * Предполагается, что реализация интерфейса фабрики будет иметь публичный конструктор без параметров. + */ +public interface TableProviderFactory { + + /** + * Возвращает объект для работы с базой данных. + * + * @param path Директория с файлами базы данных. + * @return Объект для работы с базой данных, который будет работать в указанной директории. + * + * @throws IllegalArgumentException Если значение директории null или имеет недопустимое значение. + * @throws java.io.IOException В случае ошибок ввода/вывода. + */ + TableProvider create(String path) throws IOException; +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ErrorFunctionsTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ErrorFunctionsTest.java new file mode 100644 index 000000000..4ed9c556b --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ErrorFunctionsTest.java @@ -0,0 +1,69 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import org.junit.Test; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions.*; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; + +public class ErrorFunctionsTest { + + final String name = "name"; + final String string = "string"; + + //@SuppressWarnings("static-access") + @Test(expected = Exception.class) + public void testErrorFunctionsClass() throws Exception { + ErrorFunctions error = new ErrorFunctions(); + error.nameIsNull(name, string); } + + @Test(expected = DatabaseReadErrorException.class) + public void testErrorRead() throws Exception { + ErrorFunctions.errorRead(); } + + @Test(expected = DatabaseWriteErrorException.class) + public void testErrorWrite() throws Exception { + ErrorFunctions.errorWrite(); } + + @Test(expected = InterpreterInvalidCommandNameException.class) + public void testInvalidName() throws Exception { + ErrorFunctions.invalidName(name, string); } + + @Test(expected = IllegalArgumentException.class) + public void testNameIsNull() throws IllegalArgumentException { + ErrorFunctions.nameIsNull(name, string); } + + @Test(expected = IllegalStateException.class) + public void testNotDirectory() throws IllegalStateException { + ErrorFunctions.notDirectory(name, string); } + + @Test(expected = IllegalStateException.class) + public void testNotExists() throws IllegalStateException { + ErrorFunctions.notExists(name, string); } + + @Test(expected = IllegalArgumentException.class) + public void testNotMkdir() throws IllegalArgumentException { + ErrorFunctions.notMkdir(name, string); } + + @Test(expected = ProhibitedAccessException.class) + public void testSecurity() throws Exception { + ErrorFunctions.security(name, string); } + + @Test(expected = SomethingWrongException.class) + public void testSmthWrong1() throws Exception { + ErrorFunctions.smthWrong(name); } + + @Test(expected = SomethingWrongException.class) + public void testSmthWrong2() throws Exception { + ErrorFunctions.smthWrong(name, string); } + + @Test(expected = IllegalArgumentException.class) + public void testTableNameIsFile() throws IllegalArgumentException { + ErrorFunctions.tableNameIsFile(name, string); } + + @Test(expected = WrongInputException.class) + public void testWrongInput() throws Exception { + ErrorFunctions.wrongInput(name); } + + @Test(expected = WrongQuantityOfArgumentsException.class) + public void testWrongQuantity() throws Exception { + ErrorFunctions.wrongQuantityOfArguments(name); } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/FileUtilsTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/FileUtilsTest.java new file mode 100644 index 000000000..058aeac79 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/FileUtilsTest.java @@ -0,0 +1,109 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.Assert.*; + +public class FileUtilsTest { + + public final String end = ".." + File.separator + "test123321123321"; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testConstructor() { + FileUtils wwf = new FileUtils(); + wwf.get("Test"); + } + + @Test + public void testCreateDirectoryWithOneArgument() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath(); + FileUtils.createDirectory(path.toString()); + if (!path.toFile().exists()) { + throw new Exception("not exists"); + } + Files.delete(path); } + + @Test + public void testCreateDirectoryWithTwoArguments() throws Exception { + Path path = Paths.get(temporaryFolder.toString()).toAbsolutePath(); + FileUtils.createDirectory(path.toString(), end); + assertTrue("not exists", Paths.get(path.toString(), end).toFile().exists()); + Files.delete(Paths.get(path.toString(), end)); } + + @Test + public void testDelete() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath(); + Files.createDirectory(path); + FileUtils.delete(path.toString(), "dgdfg/.."); } + + @Test + public void testExistsWithOneArgument() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath(); + assertEquals(path.toFile().exists(), FileUtils.exists(path.toString())); } + + @Test + public void testExistsWithTwoArguments() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath(); + assertEquals(path.toFile().exists(), FileUtils.exists(temporaryFolder.toString(), path.getFileName() + .toString())); } + + @Test + public void testGetWithOneArgument() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path, FileUtils.get(path.toString())); } + + @Test + public void testGetWithTwoArguments() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(Paths.get(path.toString(), "1"), FileUtils.get(path.toString(), "1")); } + + @Test + public void testGetFileNameWithOneArgument() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.getFileName().toString(), FileUtils.getFileName(path.toString())); } + + @Test + public void testGetFileNameWithTwoArguments() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.getFileName().toString(), FileUtils + .getFileName(path.toString(), "1" + File.separator + "..")); } + + + @Test + public void testGetParentName() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.getParent().getFileName().toString(), FileUtils.getParentName(path.toString())); } + + @Test + public void testGetParentNameWithTwoArguments() { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.getParent().getFileName().toString(), + FileUtils.getParentName(path.toString(), "1" + File.separator + "..")); } + + @Test + public void testIsDirectoryWithOneArgument() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.toFile().isDirectory(), FileUtils.isDirectory(path.toString())); } + + @Test + public void testIsDirectoryWithTwoArguments() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(Paths.get(path.toString(), "../1").toFile().isDirectory(), + FileUtils.isDirectory(path.toString(), ".." + File.separator + "/1")); } + + @Test + public void testToAbsolutePath() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + assertEquals(path.toString(), FileUtils.toAbsolutePath(path.toString())); } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ReturnCodesTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ReturnCodesTest.java new file mode 100644 index 000000000..8d326e6b9 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/ReturnCodesTest.java @@ -0,0 +1,15 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import org.junit.Test; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ReturnCodes; + +import static org.junit.Assert.*; + +public class ReturnCodesTest { + + @Test + public void testConstructor() { + ReturnCodes rc = new ReturnCodes(); + assertEquals(rc.SUCCESS, ReturnCodes.SUCCESS); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java new file mode 100644 index 000000000..021512baa --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java @@ -0,0 +1,254 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableByVolodden; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TableByVoloddenTest { + + public final String name = "test123321123322"; + public final String end = ".." + File.separator + name; + public final String key1 = "key1key1"; + public final String val1 = "val1val1"; + public final String val2 = "val2lav2"; + public final String val3 = "val3lav3"; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testGetName() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(name, table.getName()); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testGetNameIfTableExist() throws Exception { + Table table = new TableByVolodden(name); + assertEquals(name, table.getName()); + Files.deleteIfExists(Paths.get(temporaryFolder.toString(), ".." + File.separator, name) + .toAbsolutePath().normalize()); + } + + @Test + public void testGet() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(null, table.get(key1)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testGetIfExists() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + assertEquals(val1, table.get(key1)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testPut() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(null, table.put(key1, val1)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testPutIfExists() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + assertEquals(val1, table.put(key1, val2)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testPutIfExistsInDataBase() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + assertEquals(val1, table.put(key1, val1)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testPutIfExistsInDataBaseEqual() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + table.put(key1, val2); + assertEquals(val2, table.put(key1, val1)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testPutIfExistsInDataBaseNotEqual() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + table.put(key1, val2); + assertEquals(val2, table.put(key1, val3)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testRemove() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(null, table.remove(key1)); + Files.deleteIfExists(Paths.get(name)); + } + + + @Test + public void testRemoveNull() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val2); + table.commit(); + table.remove(key1); + assertEquals(null, table.remove(key1)); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testRemoveIfExists() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + assertEquals(val1, table.remove(key1)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testSize() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(0, table.size()); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testSizeWithUncommittedValues() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + table.put(key1, val2); + assertEquals(1, table.size()); + table.remove(key1); + assertEquals(0, table.size()); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testGetNumberOfUncommittedChanges() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(0, table.getNumberOfUncommittedChanges()); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testCommit() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(table.commit(), 0); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testRollback() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + assertEquals(0, table.rollback()); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testList() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + List list = table.list(); + assertEquals(0, list.size()); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testListWithValues() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + List list = table.list(); + assertEquals(1, list.size()); + assertEquals(key1, list.get(0)); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testListWithValuesInDataBase() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + List list = table.list(); + assertEquals(1, list.size()); + assertEquals(key1, list.get(0)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testListWithValuesInDataBaseAndInDiff() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + table.put(key1, val2); + List list = table.list(); + assertEquals(1, list.size()); + assertEquals(key1, list.get(0)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } + + @Test + public void testReadFromDisk() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + Table table = new TableByVolodden(name); + table.put(key1, val1); + table.commit(); + Table table2 = new TableByVolodden(name); + assertEquals(val1, table2.get(key1)); + table.remove(key1); + table.commit(); + Files.deleteIfExists(Paths.get(name)); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java new file mode 100644 index 000000000..57be01f05 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java @@ -0,0 +1,83 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderByVolodden; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; + +public class TableProviderByVoloddenTest { + + public final String name = "test123321123323"; + public final String nameTable = "nameTable"; + public final String end = ".." + File.separator + name; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test(expected = IllegalStateException.class) + public void testGetTableNotExists() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + TableProvider tableProvider = new TableProviderByVolodden(name); + try { + Table table = tableProvider.getTable(Paths.get(name, nameTable).toString()); + } catch (IllegalStateException e) { + Files.deleteIfExists(path); + throw new IllegalStateException(); + } + } + + @Test + public void testGetTable() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + TableProvider tableProvider = new TableProviderByVolodden(name); + Table table = tableProvider.createTable(nameTable); + table.put("k", "v"); + table.commit(); + table = tableProvider.getTable(nameTable); + tableProvider.removeTable(nameTable); + Files.deleteIfExists(path); + } + + @Test + public void testCreateTable() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + TableProvider tableProvider = new TableProviderByVolodden(path.toString()); + Table table = tableProvider.createTable(nameTable); + assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable)); + Files.deleteIfExists(path); + } + + @Test + public void testCreateTableIfExists() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + TableProvider tableProvider = new TableProviderByVolodden(path.toString()); + Files.createDirectory(Paths.get(path.toString(), nameTable)); + Table table = tableProvider.createTable(nameTable); + assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable)); + Files.deleteIfExists(path); + } + + @Test + public void testRemoveTable() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + TableProvider tableProvider = new TableProviderByVolodden(path.toString()); + Table table = tableProvider.createTable(nameTable); + table.put("k", "v"); + table.commit(); + tableProvider.removeTable(nameTable); + assertEquals(false, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable)); + Files.deleteIfExists(path); + } +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderFactoryByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderFactoryByVoloddenTest.java new file mode 100644 index 000000000..fca707515 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderFactoryByVoloddenTest.java @@ -0,0 +1,18 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.tests; + +import junit.framework.TestCase; +import org.junit.Test; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderFactoryByVolodden; + +import java.nio.file.Files; +import java.nio.file.Paths; + +public class TableProviderFactoryByVoloddenTest extends TestCase { + + @Test + public void testCreate() throws Exception { + TableProviderFactoryByVolodden tpf = new TableProviderFactoryByVolodden(); + tpf.create("tableProvider"); + Files.deleteIfExists(Paths.get("tableProvider")); + } +} From 38ae18a49607892ca7008dd2e1314031807bbaf5 Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 16:00:01 +0300 Subject: [PATCH 05/13] Update. --- .../StoreableByVolodden.java | 6 +++--- .../Volodin_Denis/Storeable/main/{JUnit.java => Main.java} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/{JUnit.java => Main.java} (99%) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java index 8f1e12b83..4a84330d9 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java @@ -10,11 +10,11 @@ public class StoreableByVolodden implements Storeable{ private List> types; private List values; - StoreableByVolodden(String string, List> _types) { - types = _types; + StoreableByVolodden(String string, List> inputTypes) { + types = inputTypes; String[] array = string.split(", "); for (int i = 0; i < array.length; ++i) { - if (array[i] == "null") { + if (array[i].equals("null")) { values.add(null); } if (types.get(i) == Integer.class) { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java similarity index 99% rename from src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java rename to src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java index 19c23cf07..1d356a49e 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/JUnit.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java @@ -16,7 +16,7 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableRemove; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableSize; -public class JUnit { +public class Main { public static void main(final String[] args) { try { From a7b2efcfa5a4a54146889420fcf60ae2638f9e08 Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 16:48:38 +0300 Subject: [PATCH 06/13] Add new. --- .../JSONUtils.java | 77 ++++++++ .../StoreableByVolodden.java | 53 +++++- .../TableByVolodden.java | 73 +------ .../TableProviderByVolodden.java | 178 ++++++++++++++++++ 4 files changed, 311 insertions(+), 70 deletions(-) create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java create mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java new file mode 100644 index 000000000..6c21fd2c7 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java @@ -0,0 +1,77 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; + +import java.util.List; +import java.util.NoSuchElementException; + +public class JSONUtils { + + public static String storeableToString(Table table, Storeable storeable) { + StringBuilder builder = new StringBuilder("["); + for (int i = 0; i < table.getColumnsCount(); ++i) { + builder.append(JSONUtils.valueInStoreable(table, storeable, i)).append(", "); + } + builder.deleteCharAt(builder.length() - 1); + builder.deleteCharAt(builder.length() - 1); + builder.append("]"); + return builder.toString(); + } + + public static String valueInStoreable(Table table, Storeable storeable, int index) { + Class type = table.getColumnType(index); + if (type == Integer.class) { + return storeable.getIntAt(index).toString(); + } + if (type == Long.class) { + return storeable.getLongAt(index).toString(); + } + if (type == Byte.class) { + return storeable.getByteAt(index).toString(); + } + if (type == Float.class) { + return storeable.getFloatAt(index).toString(); + } + if (type == Double.class) { + return storeable.getDoubleAt(index).toString(); + } + if (type == Boolean.class) { + return storeable.getBooleanAt(index).toString(); + } + if (type == String.class) { + return storeable.getStringAt(index).toString(); + } + return "null"; + } + + public static Class stringToType(String string) { + if (string.equals("int")) { + return Integer.class; + } + if (string.equals("long")) { + return Long.class; + } + if (string.equals("byte")) { + return Byte.class; + } + if (string.equals("float")) { + return Float.class; + } + if (string.equals("double")) { + return Double.class; + } + if (string.equals("bool")) { + return Boolean.class; + } + if (string.equals("string")) { + return String.class; + } + throw new NoSuchElementException(); + } + + public static Storeable stringToStoreable(List> types, String string) { + return new StoreableByVolodden(string, types); + } +} + diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java index 4a84330d9..1cb1a3e87 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java @@ -2,15 +2,53 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class StoreableByVolodden implements Storeable{ private List> types; private List values; + private Set> validTypes; - StoreableByVolodden(String string, List> inputTypes) { + public StoreableByVolodden(Table table) { + initializeValidTypes(); + List> newTypes = new ArrayList<>(); + for (int i = 0; i < table.getColumnsCount(); ++i) { + newTypes.add(table.getColumnType(i)); + } + for (Class type : newTypes) { + if (!validTypes.contains(type)) { + throw new ColumnFormatException("Invalid column type"); + } + } + types = newTypes; + values = new ArrayList<>(); + for (int i = 0; i < types.size(); i++) { + values.add(null); + } + } + + public StoreableByVolodden(Table table, List newValues) { + this(table); + if (newValues.size() != values.size()) { + throw new IndexOutOfBoundsException("Other size of values"); + } else { + for (int i = 0; i < newValues.size(); ++i) { + if (newValues.get(i).getClass() != types.get(i)) { + throw new ColumnFormatException("Other type"); + } else { + values.set(i, newValues.get(i)); + } + } + } + } + + public StoreableByVolodden(String string, List> inputTypes) { types = inputTypes; String[] array = string.split(", "); for (int i = 0; i < array.length; ++i) { @@ -41,6 +79,19 @@ public class StoreableByVolodden implements Storeable{ } } + private void initializeValidTypes() { + if (validTypes == null) { + validTypes = new HashSet<>(); + validTypes.add(Integer.class); + validTypes.add(Long.class); + validTypes.add(Byte.class); + validTypes.add(Double.class); + validTypes.add(Float.class); + validTypes.add(Boolean.class); + validTypes.add(String.class); + } + } + @Override public void setColumnAt(int columnIndex, Object value) throws ColumnFormatException, IndexOutOfBoundsException { checkBounds(columnIndex); diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java index b1472d06e..fa2d19983 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java @@ -65,7 +65,7 @@ private void readTypes() throws DatabaseCorruptedException { try (Scanner in = new Scanner(new File(FileUtils.get(dbPath, signatureFileName).toString()))) { list = Arrays.asList(in.nextLine().split("\\s+")); for (String type : list) { - types.add(stringToType(type)); + types.add(JSONUtils.stringToType(type)); } } catch (FileNotFoundException e) { throw new DatabaseCorruptedException("Can't find a file with signatures."); @@ -358,12 +358,12 @@ public Collection values() { @Override public Storeable put(String key, Storeable value) throws ColumnFormatException { - return stringToStoreable(fileMap.put(key, storeableToString(value))); + return JSONUtils.stringToStoreable(types, fileMap.put(key, JSONUtils.storeableToString(this, value))); } @Override public Storeable remove(String key) { - return stringToStoreable(fileMap.remove(key)); + return JSONUtils.stringToStoreable(types, fileMap.remove(key)); } @Override @@ -420,72 +420,7 @@ public String getName() { @Override public Storeable get(String key) { - return stringToStoreable(fileMap.get(key)); + return JSONUtils.stringToStoreable(types, fileMap.get(key)); } - private Storeable stringToStoreable(String string) { - return new StoreableByVolodden(string, types); - } - - private String storeableToString(Storeable storeable) { - StringBuilder builder = new StringBuilder("["); - for (int i = 0; i < getColumnsCount(); ++i) { - builder.append(valueInStoreable(storeable, i)).append(", "); - } - builder.deleteCharAt(builder.length() - 1); - builder.deleteCharAt(builder.length() - 1); - builder.append("]"); - return builder.toString(); - } - - private String valueInStoreable(Storeable storeable, int index) { - Class type = getColumnType(index); - if (type == Integer.class) { - return storeable.getIntAt(index).toString(); - } - if (type == Long.class) { - return storeable.getLongAt(index).toString(); - } - if (type == Byte.class) { - return storeable.getByteAt(index).toString(); - } - if (type == Float.class) { - return storeable.getFloatAt(index).toString(); - } - if (type == Double.class) { - return storeable.getDoubleAt(index).toString(); - } - if (type == Boolean.class) { - return storeable.getBooleanAt(index).toString(); - } - if (type == String.class) { - return storeable.getStringAt(index).toString(); - } - return "null"; - } - - private Class stringToType(String string) { - if (string.equals("int")) { - return Integer.class; - } - if (string.equals("long")) { - return Long.class; - } - if (string.equals("byte")) { - return Byte.class; - } - if (string.equals("float")) { - return Float.class; - } - if (string.equals("double")) { - return Double.class; - } - if (string.equals("bool")) { - return Boolean.class; - } - if (string.equals("string")) { - return String.class; - } - throw new NoSuchElementException(); - } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java new file mode 100644 index 000000000..16d8660d3 --- /dev/null +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java @@ -0,0 +1,178 @@ +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.*; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class TableProviderByVolodden implements TableProvider { + + private String dbPath; + private Set tables; + + public TableProviderByVolodden(String dir) throws Exception { + dbPath = FileUtils.toAbsolutePath(dir); + if (!FileUtils.exists(dbPath)) { + FileUtils.createDirectory(dbPath); + } + tables = readOldTables(Paths.get(dbPath)); + } + + @Override + public Table getTable(String name) throws IllegalArgumentException { + if (!FileUtils.exists(dbPath, name)) { + ErrorFunctions.notExists("get table", name); + } + Table dbTable; + try { + dbTable = new TableByVolodden(FileUtils.get(dbPath, name).toString()); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + return dbTable; + } + + @Override + public Table createTable(String name, List> columnTypes) throws IOException { + if (name == null) { + ErrorFunctions.nameIsNull("create", name); + } + Table dbTable = null; + if (FileUtils.exists(dbPath, name)) { + if (!FileUtils.isDirectory(dbPath, name)) { + ErrorFunctions.tableNameIsFile("create", name); + } + } else { + boolean exists = false; + try { + exists = FileUtils.createDirectory(dbPath, name); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + if (exists) { + try { + dbTable = new TableByVolodden(Paths.get(dbPath, name).normalize().toFile().toString()); + tables.add(name); + } catch (Exception exception) { + exception.printStackTrace(); + } + } else { + ErrorFunctions.notMkdir("create", name); + } + } + return dbTable; + } + + @Override + public void removeTable(String name) throws IOException { + if (!FileUtils.exists(dbPath, name)) { + throw new IllegalStateException("[" + name + "] not exists"); + } + if (!FileUtils.getParentName(dbPath, name).equals(FileUtils.getFileName(dbPath))) { + ErrorFunctions.notExists("drop", name); + } + if (!FileUtils.isDirectory(dbPath)) { + ErrorFunctions.notDirectory("drop", name); + } + + try { + recursiveDrop(FileUtils.get(dbPath)); + tables.remove(name); + } catch (Exception exception) { + throw new RuntimeException(exception); + } + } + + @Override + public Storeable deserialize(Table table, String value) throws ParseException { + return null; + } + + @Override + public String serialize(Table table, Storeable value) throws ColumnFormatException { + return JSONUtils.storeableToString(table, value); + } + + @Override + public Storeable createFor(Table table) { + return new StoreableByVolodden(table); + } + + @Override + public Storeable createFor(Table table, List values) throws ColumnFormatException, IndexOutOfBoundsException { + return new StoreableByVolodden(table, values); + } + + @Override + public List getTableNames() { + List result = new ArrayList<>(); + for (String name : tables) { + result.add(name); + } + return result; + } + + private static void recursiveDrop(final Path pathToFile) throws Exception { + if (!pathToFile.toFile().exists()) { + return; + } + if (pathToFile.toFile().isFile()) { + if (!pathToFile.toFile().delete()) { + ErrorFunctions.smthWrong("drop"); + } + } + try { + if (pathToFile.toFile().isDirectory()) { + String[] names = pathToFile.toFile().list(); + if (names.length != 0) { + for (String name : names) { + if (FileUtils.isDirectory(pathToFile.toString(), name)) { + recursiveDrop(Paths.get(pathToFile.toString(), name).normalize()); + } else { + if (!FileUtils.delete(pathToFile.toString(), name)) { + ErrorFunctions.smthWrong("drop"); + } + } + } + } + if (!pathToFile.toFile().delete()) { + ErrorFunctions.smthWrong("drop"); + } + } + } catch (SecurityException secException) { + ErrorFunctions.security("drop", secException.getMessage()); + } + } + + private Set readOldTables(final Path path) throws Exception { + Set setOfNames = new HashSet(); + String[] names = path.toFile().list(); + try { + for (String name : names) { + if (FileUtils.isDirectory(path.toString(), name)) { + ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table temp = new ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableByVolodden(name); + temp.size(); + setOfNames.add(name); + } else { + Files.delete(Paths.get(dbPath, name)); + } + } + return setOfNames; + } catch (Exception exception) { + ErrorFunctions.smthWrong("read"); + return null; + } + } +} From 676e29f33a5fbfbdbfd4158440449a7b5bf3b00d Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 17:23:19 +0300 Subject: [PATCH 07/13] Update. --- .../JSONUtils.java | 25 +++++++++++++++++ .../TableProviderByVolodden.java | 27 ++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java index 6c21fd2c7..b49cdb31c 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java @@ -73,5 +73,30 @@ public static Class stringToType(String string) { public static Storeable stringToStoreable(List> types, String string) { return new StoreableByVolodden(string, types); } + + public static Object stringToOneElementOfStoreable(Class type, String string) { + if (type == Integer.class) { + return Integer.parseInt(string); + } + if (type == Long.class) { + return Long.parseLong(string); + } + if (type == Byte.class) { + return Byte.parseByte(string); + } + if (type == Float.class) { + return Float.parseFloat(string); + } + if (type == Double.class) { + return Double.parseDouble(string); + } + if (type == Boolean.class) { + return Boolean.parseBoolean(string); + } + if (type == String.class) { + return string; + } + return null; + } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java index 16d8660d3..d0d246ca3 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java @@ -22,6 +22,9 @@ public class TableProviderByVolodden implements TableProvider { private String dbPath; private Set tables; + + private final String regExpToSplitJSON = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; + public TableProviderByVolodden(String dir) throws Exception { dbPath = FileUtils.toAbsolutePath(dir); if (!FileUtils.exists(dbPath)) { @@ -97,7 +100,29 @@ public void removeTable(String name) throws IOException { @Override public Storeable deserialize(Table table, String value) throws ParseException { - return null; + if (!value.startsWith("[")) { + throw new ParseException("Can't deserialize <" + value + ">: argument doesn't start with \"[\".", 0); + } + if (!value.endsWith("]")) { + throw new ParseException("Can't deserialize <" + value + ">: argument doesn't end with \"]\".", value.length() - 1); + } + value = value.substring(1, value.length() - 1); + String[] parsedValues = value.split(regExpToSplitJSON); + Storeable answer = createFor(table); + int i = 0; + try { + for (i = 0; i < parsedValues.length; ++i) { + answer.setColumnAt(i, JSONUtils.stringToOneElementOfStoreable(table.getColumnType(i), parsedValues[i])); + } + } catch (ColumnFormatException e) { + throw new ParseException(e.getMessage(), i); + } catch (IndexOutOfBoundsException e) { + throw new ParseException(e.getMessage(), i); + } + if (i < table.getColumnsCount()) { + throw new ParseException("Too few elements.", i); + } + return answer; } @Override From ec643a2b5822cd18c9f35ee0c83f5f6ad2fb3240 Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 17:24:56 +0300 Subject: [PATCH 08/13] Length. --- .../TableProviderByVolodden.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java index d0d246ca3..4bdf5a725 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java @@ -187,7 +187,7 @@ private Set readOldTables(final Path path) throws Exception { try { for (String name : names) { if (FileUtils.isDirectory(path.toString(), name)) { - ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table temp = new ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableByVolodden(name); + Table temp = new TableByVolodden(name); temp.size(); setOfNames.add(name); } else { From 998f4056e7b430f1dd70935b199f314af7db4406 Mon Sep 17 00:00:00 2001 From: volodden Date: Wed, 24 Dec 2014 18:36:54 +0300 Subject: [PATCH 09/13] Length. --- .../TableProviderByVolodden.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java index 4bdf5a725..bde377465 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java @@ -104,7 +104,8 @@ public Storeable deserialize(Table table, String value) throws ParseException { throw new ParseException("Can't deserialize <" + value + ">: argument doesn't start with \"[\".", 0); } if (!value.endsWith("]")) { - throw new ParseException("Can't deserialize <" + value + ">: argument doesn't end with \"]\".", value.length() - 1); + throw new ParseException("Can't deserialize <" + value + ">: argument doesn't end with \"]\".", + value.length() - 1); } value = value.substring(1, value.length() - 1); String[] parsedValues = value.split(regExpToSplitJSON); From d9a00ee8670d90f9c08d69d72126b2b8bd38a308 Mon Sep 17 00:00:00 2001 From: volodden Date: Thu, 25 Dec 2014 07:23:43 +0300 Subject: [PATCH 10/13] Update. --- .../JSONUtils.java | 14 +- .../StoreableByVolodden.java | 47 +- .../Storeable/database/TableByVolodden.java | 100 ++-- .../database/TableProviderByVolodden.java | 79 +++- .../TableProviderFactoryByVolodden.java | 13 +- .../Storeable/interpreter/Command.java | 3 +- .../Storeable/interpreter/CommandHandler.java | 11 +- .../Storeable/interpreter/Interpreter.java | 3 + .../commands/CommandProviderCreate.java | 50 +- .../commands/CommandProviderDrop.java | 36 +- .../commands/CommandProviderUse.java | 44 +- .../commands/CommandTableCommit.java | 34 +- .../interpreter/commands/CommandTableGet.java | 44 +- .../commands/CommandTableList.java | 45 +- .../interpreter/commands/CommandTablePut.java | 51 ++- .../commands/CommandTableRemove.java | 43 +- .../commands/CommandTableRollback.java | 30 +- .../commands/CommandTableSize.java | 30 +- .../TableByVolodden.java | 426 ------------------ .../TableProviderByVolodden.java | 204 --------- .../Volodin_Denis/Storeable/main/Main.java | 14 +- .../main/StringInterpreterState.java | 4 +- .../Storeable/strings/Table.java | 82 ---- .../Storeable/strings/TableProvider.java | 34 -- .../strings/TableProviderFactory.java | 19 - .../Storeable/tests/TableByVoloddenTest.java | 146 ++++-- .../tests/TableProviderByVoloddenTest.java | 42 +- 27 files changed, 554 insertions(+), 1094 deletions(-) rename src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/{it_temporary_folder_name_until_I_came_up_a_suitable => database}/JSONUtils.java (92%) rename src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/{it_temporary_folder_name_until_I_came_up_a_suitable => database}/StoreableByVolodden.java (77%) delete mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java delete mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java delete mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java delete mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java delete mode 100644 src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java similarity index 92% rename from src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java rename to src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java index b49cdb31c..a08de9893 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/JSONUtils.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java @@ -1,4 +1,4 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; @@ -9,6 +9,9 @@ public class JSONUtils { public static String storeableToString(Table table, Storeable storeable) { + if (storeable == null) { + return null; + } StringBuilder builder = new StringBuilder("["); for (int i = 0; i < table.getColumnsCount(); ++i) { builder.append(JSONUtils.valueInStoreable(table, storeable, i)).append(", "); @@ -21,6 +24,9 @@ public static String storeableToString(Table table, Storeable storeable) { public static String valueInStoreable(Table table, Storeable storeable, int index) { Class type = table.getColumnType(index); + if (storeable == null) { + return "null"; + } if (type == Integer.class) { return storeable.getIntAt(index).toString(); } @@ -71,6 +77,9 @@ public static Class stringToType(String string) { } public static Storeable stringToStoreable(List> types, String string) { + if (string == null) { + return null; + } return new StoreableByVolodden(string, types); } @@ -98,5 +107,4 @@ public static Object stringToOneElementOfStoreable(Class type, String string) } return null; } -} - +} \ No newline at end of file diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java similarity index 77% rename from src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java rename to src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java index 1cb1a3e87..62a1887cd 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/StoreableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java @@ -1,13 +1,10 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; +package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class StoreableByVolodden implements Storeable{ @@ -48,12 +45,52 @@ public StoreableByVolodden(Table table, List newValues) { } } + public StoreableByVolodden(Table table, String[] array) { + this(table); + if (array.length != values.size()) { + throw new IndexOutOfBoundsException("Other size of values"); + } else { + for (int i = 0; i < array.length; ++i) { + if (array[i].equals("null")) { + values.set(i, null); + } + if (table.getColumnType(i) == Integer.class) { + values.set(i, Integer.parseInt(array[i])); + } + if (table.getColumnType(i) == Long.class) { + values.set(i, Long.parseLong(array[i])); + } + if (table.getColumnType(i) == Byte.class) { + values.set(i, Byte.parseByte(array[i])); + } + if (table.getColumnType(i) == Float.class) { + values.set(i, Float.parseFloat(array[i])); + } + if (table.getColumnType(i) == Double.class) { + values.set(i, Double.parseDouble(array[i])); + } + if (table.getColumnType(i) == Boolean.class) { + values.set(i, Boolean.parseBoolean(array[i])); + } + if (table.getColumnType(i) == String.class) { + values.set(i, array[i]); + } + } + } + } + public StoreableByVolodden(String string, List> inputTypes) { types = inputTypes; + values = new ArrayList(); + if (string == null) { + string = "[null]"; + } + string = string.substring(1, string.length()-1); String[] array = string.split(", "); for (int i = 0; i < array.length; ++i) { if (array[i].equals("null")) { values.add(null); + continue; } if (types.get(i) == Integer.class) { values.add(Integer.parseInt(array[i])); diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java index 994bd4fae..939da8310 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java @@ -1,12 +1,12 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions.DatabaseCorruptedException; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.FileInputStream; -import java.io.FileOutputStream; +import java.io.*; import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; @@ -17,7 +17,10 @@ public class TableByVolodden implements Table { private String dbPath; private FileMap fileMap; - + private List> types; + + private final String signatureFileName = "signature.tsv"; + public TableByVolodden(final String path) throws Exception { dbPath = FileUtils.toAbsolutePath(path); fileMap = new FileMap(dbPath); @@ -49,8 +52,26 @@ public FileMap(final String dbPath) throws Exception { diff = new HashMap(); if (FileUtils.exists(databasePath)) { readFromDisk(); + readTypes(); } else { - FileUtils.createDirectory(databasePath); + throw new Exception("Table was not found"); + } + } + + private void readTypes() throws DatabaseCorruptedException { + types = new ArrayList<>(); + List list; + try (Scanner in = new Scanner(new File(FileUtils.get(dbPath, signatureFileName).toString()))) { + list = Arrays.asList(in.nextLine().split("\\s+")); + for (String type : list) { + types.add(JSONUtils.stringToType(type)); + } + } catch (FileNotFoundException e) { + throw new DatabaseCorruptedException("Can't find a file with signatures."); + } catch (IllegalArgumentException e) { + throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); + } catch (NoSuchElementException e) { + throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); } } @@ -58,7 +79,7 @@ private void readFromDisk() throws Exception { for (int i = 0; i < folders; ++i) { for (int j = 0; j < files; ++j) { Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) - + dat).normalize(); + + dat).normalize(); if (somePath.toFile().exists()) { try (DataInputStream input = new DataInputStream(new FileInputStream(somePath.toString()))) { while (true) { @@ -67,7 +88,7 @@ private void readFromDisk() throws Exception { String value = readOneWordFromDisk(input); if ((Math.abs(key.hashCode()) % folders != i) - || (Math.abs(key.hashCode()) / folders % files != j)) { + || (Math.abs(key.hashCode()) / folders % files != j)) { throw new Exception("wrong input"); } database.put(key, value); @@ -104,7 +125,7 @@ private void writeOnDisk() throws Exception { for (int i = 0; i < folders; ++i) { for (int j = 0; j < files; ++j) { Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) - + dat).normalize(); + + dat).normalize(); if (somePath.toFile().exists()) { if (!somePath.toFile().delete()) { ErrorFunctions.smthWrong("write", "file is not deleted"); @@ -335,35 +356,29 @@ public Collection values() { //--- @Override - public String getName() { - return FileUtils.getFileName(dbPath); - } - - @Override - public String get(final String key) { - return fileMap.get(key); + public Storeable put(String key, Storeable value) throws ColumnFormatException { + return JSONUtils.stringToStoreable(types, fileMap.put(key, JSONUtils.storeableToString(this, value))); } @Override - public String put(String key, String value) { - return fileMap.put(key, value); - } - - @Override - public String remove(String key) { - return fileMap.remove(key); + public Storeable remove(String key) { + return JSONUtils.stringToStoreable(types, fileMap.remove(key)); } @Override public int size() { - return fileMap.size(); + return fileMap.size(); } @Override - public int getNumberOfUncommittedChanges() { - return fileMap.numUncommitedChanges(); + public List list() { + List keys = new ArrayList(); + for (String key : fileMap.keySet()) { + keys.add(key); + } + return keys; } - + @Override public int commit() { int changes = 0; @@ -383,11 +398,28 @@ public int rollback() { } @Override - public List list() { - List keys = new ArrayList(); - for (String key : fileMap.keySet()) { - keys.add(key); - } - return keys; + public int getNumberOfUncommittedChanges() { + return fileMap.numUncommitedChanges(); + } + + @Override + public int getColumnsCount() { + return types.size(); } + + @Override + public Class getColumnType(int columnIndex) throws IndexOutOfBoundsException { + return types.get(columnIndex); + } + + @Override + public String getName() { + return FileUtils.getFileName(dbPath); + } + + @Override + public Storeable get(String key) { + return JSONUtils.stringToStoreable(types, fileMap.get(key)); + } + } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java index 1f8683e51..df6067c9b 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java @@ -1,20 +1,29 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.text.ParseException; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; public class TableProviderByVolodden implements TableProvider { private String dbPath; private Set tables; - + + + private final String regExpToSplitJSON = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; + public TableProviderByVolodden(String dir) throws Exception { dbPath = FileUtils.toAbsolutePath(dir); if (!FileUtils.exists(dbPath)) { @@ -22,7 +31,7 @@ public TableProviderByVolodden(String dir) throws Exception { } tables = readOldTables(Paths.get(dbPath)); } - + @Override public Table getTable(String name) throws IllegalArgumentException { if (!FileUtils.exists(dbPath, name)) { @@ -38,7 +47,7 @@ public Table getTable(String name) throws IllegalArgumentException { } @Override - public Table createTable(String name) throws IllegalArgumentException { + public Table createTable(String name, List> columnTypes) throws IOException { if (name == null) { ErrorFunctions.nameIsNull("create", name); } @@ -69,7 +78,7 @@ public Table createTable(String name) throws IllegalArgumentException { } @Override - public void removeTable(String name) throws IllegalArgumentException, IllegalStateException { + public void removeTable(String name) throws IOException { if (!FileUtils.exists(dbPath, name)) { throw new IllegalStateException("[" + name + "] not exists"); } @@ -79,7 +88,7 @@ public void removeTable(String name) throws IllegalArgumentException, IllegalSta if (!FileUtils.isDirectory(dbPath)) { ErrorFunctions.notDirectory("drop", name); } - + try { recursiveDrop(FileUtils.get(dbPath)); tables.remove(name); @@ -87,7 +96,59 @@ public void removeTable(String name) throws IllegalArgumentException, IllegalSta throw new RuntimeException(exception); } } - + + @Override + public Storeable deserialize(Table table, String value) throws ParseException { + if (!value.startsWith("[")) { + throw new ParseException("Can't deserialize <" + value + ">: argument doesn't start with \"[\".", 0); + } + if (!value.endsWith("]")) { + throw new ParseException("Can't deserialize <" + value + ">: argument doesn't end with \"]\".", + value.length() - 1); + } + value = value.substring(1, value.length() - 1); + String[] parsedValues = value.split(regExpToSplitJSON); + Storeable answer = createFor(table); + int i = 0; + try { + for (i = 0; i < parsedValues.length; ++i) { + answer.setColumnAt(i, JSONUtils.stringToOneElementOfStoreable(table.getColumnType(i), parsedValues[i])); + } + } catch (ColumnFormatException e) { + throw new ParseException(e.getMessage(), i); + } catch (IndexOutOfBoundsException e) { + throw new ParseException(e.getMessage(), i); + } + if (i < table.getColumnsCount()) { + throw new ParseException("Too few elements.", i); + } + return answer; + } + + @Override + public String serialize(Table table, Storeable value) throws ColumnFormatException { + return JSONUtils.storeableToString(table, value); + } + + @Override + public Storeable createFor(Table table) { + return new StoreableByVolodden(table); + } + + @Override + public Storeable createFor(Table table, List values) throws ColumnFormatException, IndexOutOfBoundsException { + return new StoreableByVolodden(table, values); + } + + @Override + public List getTableNames() { + List result = new ArrayList<>(); + for (String name : tables) { + result.add(name); + } + return result; + } + private static void recursiveDrop(final Path pathToFile) throws Exception { if (!pathToFile.toFile().exists()) { return; @@ -119,7 +180,7 @@ private static void recursiveDrop(final Path pathToFile) throws Exception { ErrorFunctions.security("drop", secException.getMessage()); } } - + private Set readOldTables(final Path path) throws Exception { Set setOfNames = new HashSet(); String[] names = path.toFile().list(); diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java index 0a5e187e4..e7d8d1c38 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderFactoryByVolodden.java @@ -1,20 +1,21 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.database; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProviderFactory; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProviderFactory; -public class TableProviderFactoryByVolodden implements TableProviderFactory { +import java.io.IOException; + +public class TableProviderFactoryByVolodden implements TableProviderFactory{ @Override - public TableProviderByVolodden create(String dir) { + public TableProviderByVolodden create(String dir) throws IOException { if (dir == null) { throw new IllegalArgumentException("wrong directory"); } - + try { return new TableProviderByVolodden(dir); } catch (Exception e) { - e.printStackTrace(); - return null; + throw new IOException("IO wrong."); } } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java index 72fec86a8..984a87a41 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Command.java @@ -1,6 +1,7 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; + +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public abstract class Command { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java index 33d47ce81..5201adec7 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java @@ -1,9 +1,9 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter; -import java.util.function.BiConsumer; - import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; +import java.util.function.BiConsumer; + public class CommandHandler { private String name; @@ -26,9 +26,10 @@ public String getName() { return name; } - private void checkQuantityOfArguments(final String[] args, - final String commandName) throws Exception { - if (args.length != quantityOfArguments) { + private void checkQuantityOfArguments(final String[] args, final String commandName) throws Exception { + if (((args.length != quantityOfArguments) && (quantityOfArguments != -1)) + || (args.length < 2) && (quantityOfArguments == -1)) + { ErrorFunctions.wrongQuantityOfArguments(commandName); } if (args.length > 1) { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java index 48953e849..d8d03a3d6 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/Interpreter.java @@ -57,6 +57,9 @@ public void run(String[] args) { System.exit(ReturnCodes.ERROR); } } + if (args.length == 0) { + return; + } StringBuilder helpArray = new StringBuilder(); for (int i = 0; i < args.length; ++i) { helpArray.append(args[i]).append(' '); diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java index 67bf111cd..96217b84d 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderCreate.java @@ -1,40 +1,48 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.JSONUtils; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; -import java.util.function.BiConsumer; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class CommandProviderCreate extends Command { public CommandProviderCreate() { name = "create"; - quantityOfArguments = 1; + quantityOfArguments = -1; } @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - TableProvider tableProvider = state.getTableProvider(); - - try { - tableProvider.getTable(args[0]); - System.out.println(name + " exists"); - } catch (IllegalArgumentException e) { - Table table = tableProvider.createTable(args[0]); - if (table != null) { - System.out.println("created"); - } - } + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + TableProvider tableProvider = state.getTableProvider(); + + List> list = new ArrayList>(); + for (int i = 1; i < args.length; ++i) { + list.add(JSONUtils.stringToType(args[i])); + } + try { + tableProvider.getTable(args[0]); + System.out.println(name + " exists"); + } catch (IllegalArgumentException e) { + Table table = null; + try { + table = tableProvider.createTable(args[0], list); + } catch (IOException e1) { + e1.printStackTrace(); + } + if (table != null) { + System.out.println("created"); } - }); + } + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java index bbc73e0d5..3e8957c2a 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderDrop.java @@ -2,11 +2,10 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; -import java.util.function.BiConsumer; +import java.io.IOException; public class CommandProviderDrop extends Command { @@ -17,22 +16,21 @@ public CommandProviderDrop() { @Override public CommandHandler create() { - return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - TableProvider tableProvider = state.getTableProvider(); - - try { - tableProvider.removeTable(args[0]); - System.out.println("dropped"); - } catch (IllegalArgumentException e) { - System.err.println(e.getMessage()); - } catch (IllegalStateException e) { - System.err.println(e.getMessage()); - } + return new CommandHandler(name, quantityOfArguments, + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + TableProvider tableProvider = state.getTableProvider(); + + try { + tableProvider.removeTable(args[0]); + System.out.println("dropped"); + } catch (IllegalArgumentException e) { + System.err.println(e.getMessage()); + } catch (IllegalStateException e) { + System.err.println(e.getMessage()); + } catch (IOException e) { + System.err.println(e.getMessage()); } - }); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java index 0ec176010..418b4a5ab 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandProviderUse.java @@ -2,11 +2,8 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; - -import java.util.function.BiConsumer; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public class CommandProviderUse extends Command { @@ -18,26 +15,23 @@ public CommandProviderUse() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - if (table.getName().equals(args[0])) { - System.out.println("[" + args[0] + "] already used"); - return; - } - int changes = table.getNumberOfUncommittedChanges(); - if (changes != 0) { - System.out.println(changes + " unsaved changes"); - return; - } - try { - state.setTable(state.getTableProvider().getTable(args[0])); - } catch (Exception e) { - System.out.println(e.getMessage()); - } - } - }); + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + if (table.getName().equals(args[0])) { + System.out.println("[" + args[0] + "] already used"); + return; + } + int changes = table.getNumberOfUncommittedChanges(); + if (changes != 0) { + System.out.println(changes + " unsaved changes"); + return; + } + try { + state.setTable(state.getTableProvider().getTable(args[0])); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java index d1d9c6777..38ffb1974 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableCommit.java @@ -2,11 +2,10 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; -import java.util.function.BiConsumer; +import java.io.IOException; public class CommandTableCommit extends Command { @@ -18,20 +17,21 @@ public CommandTableCommit() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } - System.out.println(table.commit()); - state.setTable(table); - } - }); + try { + System.out.println(table.commit()); + } catch (IOException e) { + e.printStackTrace(); + } + state.setTable(table); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java index b2a2a55c7..6d9e58094 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableGet.java @@ -1,12 +1,11 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.JSONUtils; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; - -import java.util.function.BiConsumer; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public class CommandTableGet extends Command { @@ -18,25 +17,22 @@ public CommandTableGet() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } - - String value = table.get(args[0]); - if (value == null) { - System.out.println("not found"); - } else { - System.out.println("found"); - System.out.println(value); - } - } - }); + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + Storeable value = table.get(args[0]); + if (value == null) { + System.out.println("not found"); + } else { + System.out.println("found"); + System.out.println(JSONUtils.storeableToString(table, value)); + } + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java index 3db497ce9..bdce6526d 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableList.java @@ -2,12 +2,10 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; import java.util.List; -import java.util.function.BiConsumer; public class CommandTableList extends Command { @@ -19,28 +17,25 @@ public CommandTableList() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } - - List list = table.list(); - int i = list.size(); - for (String key : list) { - System.out.print(key); - --i; - if (i > 0) { - System.out.print(", "); - } - } - System.out.println(); + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + List list = table.list(); + int i = list.size(); + for (String key : list) { + System.out.print(key); + --i; + if (i > 0) { + System.out.print(", "); } - }); + } + System.out.println(); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java index 8917f08c7..62f81f5ab 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTablePut.java @@ -1,43 +1,44 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.JSONUtils; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.StoreableByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; -import java.util.function.BiConsumer; +import java.util.Arrays; public class CommandTablePut extends Command { public CommandTablePut() { name = "put"; - quantityOfArguments = 2; + quantityOfArguments = -1; } @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } - - String value = table.put(args[0], args[1]); - if (value == null) { - System.out.println("new"); - } else { - System.out.println("overwrite"); - System.out.println(value); - } - state.setTable(table); - } - }); + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + String[] buffer = Arrays.copyOfRange(args, 1, args.length); + Storeable newValue = new StoreableByVolodden(table, buffer); + Storeable value = table.put(args[0], newValue); + if (value == null) { + System.out.println("new"); + } else { + System.out.println("overwrite"); + System.out.println(JSONUtils.storeableToString(table, value)); + } + state.setTable(table); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java index 3541f00ea..ae4a00ee1 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java @@ -2,11 +2,9 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; - -import java.util.function.BiConsumer; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public class CommandTableRemove extends Command { @@ -18,25 +16,22 @@ public CommandTableRemove() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } - - String value = table.remove(args[0]); - if (value == null) { - System.out.println("not found"); - } else { - System.out.println("removed"); - } - state.setTable(table); - } - }); + (interpreterState,args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + Storeable value = table.remove(args[0]); + if (value == null) { + System.out.println("not found"); + } else { + System.out.println("removed"); + } + state.setTable(table); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java index 10c601526..501d9d808 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRollback.java @@ -2,11 +2,8 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; - -import java.util.function.BiConsumer; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public class CommandTableRollback extends Command { @@ -18,20 +15,17 @@ public CommandTableRollback() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } - System.out.println(table.rollback()); - state.setTable(table); - } - }); + System.out.println(table.rollback()); + state.setTable(table); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java index ff114c044..874478910 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableSize.java @@ -2,11 +2,8 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Command; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.StringInterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; - -import java.util.function.BiConsumer; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; public class CommandTableSize extends Command { @@ -18,19 +15,16 @@ public CommandTableSize() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - new BiConsumer() { - @Override - public void accept(InterpreterState interpreterState, String[] args) { - StringInterpreterState state = (StringInterpreterState) interpreterState; - Table table = state.getTable(); - try { - tableIsNull(table); - } catch (Exception e) { - return; - } - - System.out.println(table.size()); - } - }); + (interpreterState, args) -> { + StringInterpreterState state = (StringInterpreterState) interpreterState; + Table table = state.getTable(); + try { + tableIsNull(table); + } catch (Exception e) { + return; + } + + System.out.println(table.size()); + }); } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java deleted file mode 100644 index fa2d19983..000000000 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableByVolodden.java +++ /dev/null @@ -1,426 +0,0 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; - -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.exceptions.DatabaseCorruptedException; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; - -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; - -public class TableByVolodden implements Table { - - private String dbPath; - private FileMap fileMap; - private List> types; - - private final String signatureFileName = "signature.tsv"; - - public TableByVolodden(final String path) throws Exception { - dbPath = FileUtils.toAbsolutePath(path); - fileMap = new FileMap(dbPath); - } - - //--- - class HelpMap { - public HashMap map; - public HelpMap() { - map = new HashMap(); - } - } - - class FileMap implements Map, AutoCloseable { - - private final int folders = 16; - private final int files = 16; - private final String encoding = "UTF-8"; - private final String dir = ".dir"; - private final String dat = ".dat"; - - private String databasePath; - private Map database; - private Map diff; - - public FileMap(final String dbPath) throws Exception { - databasePath = dbPath; - database = new HashMap(); - diff = new HashMap(); - if (FileUtils.exists(databasePath)) { - readFromDisk(); - readTypes(); - } else { - throw new Exception("Table was not found"); - } - } - - private void readTypes() throws DatabaseCorruptedException { - types = new ArrayList<>(); - List list; - try (Scanner in = new Scanner(new File(FileUtils.get(dbPath, signatureFileName).toString()))) { - list = Arrays.asList(in.nextLine().split("\\s+")); - for (String type : list) { - types.add(JSONUtils.stringToType(type)); - } - } catch (FileNotFoundException e) { - throw new DatabaseCorruptedException("Can't find a file with signatures."); - } catch (IllegalArgumentException e) { - throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); - } catch (NoSuchElementException e) { - throw new DatabaseCorruptedException(signatureFileName + " is corrupted."); - } - } - - private void readFromDisk() throws Exception { - for (int i = 0; i < folders; ++i) { - for (int j = 0; j < files; ++j) { - Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) - + dat).normalize(); - if (somePath.toFile().exists()) { - try (DataInputStream input = new DataInputStream(new FileInputStream(somePath.toString()))) { - while (true) { - try { - String key = readOneWordFromDisk(input); - String value = readOneWordFromDisk(input); - - if ((Math.abs(key.hashCode()) % folders != i) - || (Math.abs(key.hashCode()) / folders % files != j)) { - throw new Exception("wrong input"); - } - database.put(key, value); - } catch (EOFException e) { - break; - } - } - } catch (Exception e) { - ErrorFunctions.errorRead(); - } - } - } - } - } - - private String readOneWordFromDisk(DataInputStream input) throws Exception { - byte[] word = new byte[input.readInt()]; - input.readFully(word); - return new String(word, encoding); - } - - private void writeOnDisk() throws Exception { - HelpMap[][] helpMap = new HelpMap[folders][files]; - for (int i = 0; i < folders; ++i) { - for (int j = 0; j < files; ++j) { - helpMap[i][j] = new HelpMap(); - } - } - Set keys = database.keySet(); - for (String key : keys) { - helpMap[Math.abs(key.hashCode()) % folders][Math.abs(key.hashCode()) / folders % files].map - .put(key, database.get(key)); - } - for (int i = 0; i < folders; ++i) { - for (int j = 0; j < files; ++j) { - Path somePath = Paths.get(databasePath, Integer.toString(i) + dir, Integer.toString(j) - + dat).normalize(); - if (somePath.toFile().exists()) { - if (!somePath.toFile().delete()) { - ErrorFunctions.smthWrong("write", "file is not deleted"); - } - } - } - Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); - if (somePath.toFile().exists()) { - if (!somePath.toFile().delete()) { - ErrorFunctions.smthWrong("write", "folder is not deleted"); - } - } - } - for (int i = 0; i < folders; ++i) { - for (int j = 0; j < files; ++j) { - Set keyList = helpMap[i][j].map.keySet(); - if (!keyList.isEmpty()) { - Path somePath = Paths.get(databasePath, Integer.toString(i) + dir).normalize(); - if (!somePath.toFile().exists()) { - Files.createDirectory(somePath); - } - somePath = Paths.get(somePath.toString(), j + dat).normalize(); - Files.createFile(somePath); - - try (FileOutputStream output = new FileOutputStream(somePath.toString())) { - for (String key : keyList) { - writeOneWordOnDisk(key, output); - writeOneWordOnDisk(database.get(key), output); - } - } catch (Exception e) { - ErrorFunctions.errorWrite(); - } - } - } - } - } - - private void writeOneWordOnDisk(final String word, FileOutputStream output) throws Exception { - ByteBuffer buffer = ByteBuffer.allocate(4); - byte[] wordByte = buffer.putInt(word.getBytes(encoding).length).array(); - output.write(wordByte); - output.write(word.getBytes(encoding)); - } - - private void upgrade() throws Exception { - for (String key : diff.keySet()) { - if (diff.get(key) == null) { - database.remove(key); - } else { - database.put(key, diff.get(key)); - } - } - diff.clear(); - writeOnDisk(); - } - - private void downgrade() { - diff.clear(); - } - - public int numUncommitedChanges() { - return diff.size(); - } - - @Override - public void close() throws Exception { - } - - //Not used. - @Override - public void clear() { - database.clear(); - diff.clear(); - } - - //Not used. - @Override - public boolean containsKey(Object key) { - if (database.containsKey(key)) { - if (diff.containsKey(key)) { - return (diff.get(key) != null); - } - return true; - } else { - return diff.containsKey(key); - } - } - - //Not used. - @Override - public boolean containsValue(Object value) { - if (diff.containsValue(value)) { - return true; - } else { - for (String key : database.keySet()) { - if (database.get(key).equals(value)) { - if (!diff.containsKey(key)) { - return true; - } - } - } - return false; - } - } - - // Not used. - @Override - public Set> entrySet() { - return null; - } - - @Override - public String get(Object key) { - if (diff.containsKey(key)) { - return diff.get(key); - } else { - return database.get(key); - } - } - - @Override - public boolean isEmpty() { - return size() == 0; - } - - @Override - public Set keySet() { - - Set keysList = new HashSet(); - if (isEmpty()) { - return keysList; - } - - for (String key : database.keySet()) { - if (diff.containsKey(key)) { - if (diff.get(key) != null) { - keysList.add(key); - } - } else { - keysList.add(key); - } - } - for (String key : diff.keySet()) { - if (!keysList.contains(key)) { - keysList.add(key); - } - } - return keysList; - } - - @Override - public String put(String key, String value) { - if (diff.containsKey(key)) { - if (database.containsKey(key)) { - if (database.get(key).equals(value)) { - String oldValue = diff.get(key); - diff.remove(key); - return oldValue; - } else { - return diff.put(key, value); - } - } else { - return diff.put(key, value); - } - } else { - if (database.containsKey(key)) { - if (database.get(key).equals(value)) { - return database.get(key); - } else { - diff.put(key, value); - return database.get(key); - } - } else { - return diff.put(key, value); - } - } - } - - // Not used. - @Override - public void putAll(Map m) { - return; - } - - @Override - public String remove(Object key) { - if (diff.containsKey(key)) { - if (diff.get(key) == null) { - return null; - } else { - return diff.put((String) key, null); - } - } else { - if (database.containsKey(key)) { - diff.put((String) key, null); - } - return database.get(key); - } - } - - @Override - public int size() { - int result = database.size(); - for (String key : database.keySet()) { - if (diff.containsKey(key)) { - if (diff.get(key) == null) { - --result; - } - } - } - for (String key : diff.keySet()) { - if (!database.containsKey(key)) { - if (diff.get(key) != null) { - ++result; - } - } - } - return result; - } - - // Not used. - @Override - public Collection values() { - return null; - } - } - - //--- - - @Override - public Storeable put(String key, Storeable value) throws ColumnFormatException { - return JSONUtils.stringToStoreable(types, fileMap.put(key, JSONUtils.storeableToString(this, value))); - } - - @Override - public Storeable remove(String key) { - return JSONUtils.stringToStoreable(types, fileMap.remove(key)); - } - - @Override - public int size() { - return fileMap.size(); - } - - @Override - public List list() { - List keys = new ArrayList(); - for (String key : fileMap.keySet()) { - keys.add(key); - } - return keys; - } - - @Override - public int commit() { - int changes = 0; - try { - fileMap.upgrade(); - } catch (Exception exception) { - exception.printStackTrace(); - } - return changes; - } - - @Override - public int rollback() { - int changes = fileMap.numUncommitedChanges(); - fileMap.downgrade(); - return changes; - } - - @Override - public int getNumberOfUncommittedChanges() { - return fileMap.numUncommitedChanges(); - } - - @Override - public int getColumnsCount() { - return types.size(); - } - - @Override - public Class getColumnType(int columnIndex) throws IndexOutOfBoundsException { - return types.get(columnIndex); - } - - @Override - public String getName() { - return FileUtils.getFileName(dbPath); - } - - @Override - public Storeable get(String key) { - return JSONUtils.stringToStoreable(types, fileMap.get(key)); - } - -} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java deleted file mode 100644 index bde377465..000000000 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/it_temporary_folder_name_until_I_came_up_a_suitable/TableProviderByVolodden.java +++ /dev/null @@ -1,204 +0,0 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.it_temporary_folder_name_until_I_came_up_a_suitable; - -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.*; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.main.ErrorFunctions; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.ColumnFormatException; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class TableProviderByVolodden implements TableProvider { - - private String dbPath; - private Set tables; - - - private final String regExpToSplitJSON = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; - - public TableProviderByVolodden(String dir) throws Exception { - dbPath = FileUtils.toAbsolutePath(dir); - if (!FileUtils.exists(dbPath)) { - FileUtils.createDirectory(dbPath); - } - tables = readOldTables(Paths.get(dbPath)); - } - - @Override - public Table getTable(String name) throws IllegalArgumentException { - if (!FileUtils.exists(dbPath, name)) { - ErrorFunctions.notExists("get table", name); - } - Table dbTable; - try { - dbTable = new TableByVolodden(FileUtils.get(dbPath, name).toString()); - } catch (Exception exception) { - throw new RuntimeException(exception); - } - return dbTable; - } - - @Override - public Table createTable(String name, List> columnTypes) throws IOException { - if (name == null) { - ErrorFunctions.nameIsNull("create", name); - } - Table dbTable = null; - if (FileUtils.exists(dbPath, name)) { - if (!FileUtils.isDirectory(dbPath, name)) { - ErrorFunctions.tableNameIsFile("create", name); - } - } else { - boolean exists = false; - try { - exists = FileUtils.createDirectory(dbPath, name); - } catch (Exception exception) { - throw new RuntimeException(exception); - } - if (exists) { - try { - dbTable = new TableByVolodden(Paths.get(dbPath, name).normalize().toFile().toString()); - tables.add(name); - } catch (Exception exception) { - exception.printStackTrace(); - } - } else { - ErrorFunctions.notMkdir("create", name); - } - } - return dbTable; - } - - @Override - public void removeTable(String name) throws IOException { - if (!FileUtils.exists(dbPath, name)) { - throw new IllegalStateException("[" + name + "] not exists"); - } - if (!FileUtils.getParentName(dbPath, name).equals(FileUtils.getFileName(dbPath))) { - ErrorFunctions.notExists("drop", name); - } - if (!FileUtils.isDirectory(dbPath)) { - ErrorFunctions.notDirectory("drop", name); - } - - try { - recursiveDrop(FileUtils.get(dbPath)); - tables.remove(name); - } catch (Exception exception) { - throw new RuntimeException(exception); - } - } - - @Override - public Storeable deserialize(Table table, String value) throws ParseException { - if (!value.startsWith("[")) { - throw new ParseException("Can't deserialize <" + value + ">: argument doesn't start with \"[\".", 0); - } - if (!value.endsWith("]")) { - throw new ParseException("Can't deserialize <" + value + ">: argument doesn't end with \"]\".", - value.length() - 1); - } - value = value.substring(1, value.length() - 1); - String[] parsedValues = value.split(regExpToSplitJSON); - Storeable answer = createFor(table); - int i = 0; - try { - for (i = 0; i < parsedValues.length; ++i) { - answer.setColumnAt(i, JSONUtils.stringToOneElementOfStoreable(table.getColumnType(i), parsedValues[i])); - } - } catch (ColumnFormatException e) { - throw new ParseException(e.getMessage(), i); - } catch (IndexOutOfBoundsException e) { - throw new ParseException(e.getMessage(), i); - } - if (i < table.getColumnsCount()) { - throw new ParseException("Too few elements.", i); - } - return answer; - } - - @Override - public String serialize(Table table, Storeable value) throws ColumnFormatException { - return JSONUtils.storeableToString(table, value); - } - - @Override - public Storeable createFor(Table table) { - return new StoreableByVolodden(table); - } - - @Override - public Storeable createFor(Table table, List values) throws ColumnFormatException, IndexOutOfBoundsException { - return new StoreableByVolodden(table, values); - } - - @Override - public List getTableNames() { - List result = new ArrayList<>(); - for (String name : tables) { - result.add(name); - } - return result; - } - - private static void recursiveDrop(final Path pathToFile) throws Exception { - if (!pathToFile.toFile().exists()) { - return; - } - if (pathToFile.toFile().isFile()) { - if (!pathToFile.toFile().delete()) { - ErrorFunctions.smthWrong("drop"); - } - } - try { - if (pathToFile.toFile().isDirectory()) { - String[] names = pathToFile.toFile().list(); - if (names.length != 0) { - for (String name : names) { - if (FileUtils.isDirectory(pathToFile.toString(), name)) { - recursiveDrop(Paths.get(pathToFile.toString(), name).normalize()); - } else { - if (!FileUtils.delete(pathToFile.toString(), name)) { - ErrorFunctions.smthWrong("drop"); - } - } - } - } - if (!pathToFile.toFile().delete()) { - ErrorFunctions.smthWrong("drop"); - } - } - } catch (SecurityException secException) { - ErrorFunctions.security("drop", secException.getMessage()); - } - } - - private Set readOldTables(final Path path) throws Exception { - Set setOfNames = new HashSet(); - String[] names = path.toFile().list(); - try { - for (String name : names) { - if (FileUtils.isDirectory(path.toString(), name)) { - Table temp = new TableByVolodden(name); - temp.size(); - setOfNames.add(name); - } else { - Files.delete(Paths.get(dbPath, name)); - } - } - return setOfNames; - } catch (Exception exception) { - ErrorFunctions.smthWrong("read"); - return null; - } - } -} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java index 1d356a49e..33879b66b 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/Main.java @@ -1,20 +1,12 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProviderFactory; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderFactoryByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.CommandHandler; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.Interpreter; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderCreate; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderDrop; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandProviderUse; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableCommit; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableGet; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableList; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTablePut; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableRemove; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.CommandTableSize; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.commands.*; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProviderFactory; public class Main { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java index 96c88f0b0..b0ba713f2 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/main/StringInterpreterState.java @@ -1,8 +1,8 @@ package ru.fizteh.fivt.students.Volodin_Denis.Storeable.main; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.interpreter.InterpreterState; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; public class StringInterpreterState implements InterpreterState { private TableProvider tableProvider; diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java deleted file mode 100644 index 790c2994f..000000000 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/Table.java +++ /dev/null @@ -1,82 +0,0 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; - -import java.util.List; -/** - * @author Fedor Lavrentyev - * @author Dmitriy Komanov - */ -public interface Table { - - /** - * Возвращает название базы данных. - */ - String getName(); - - /** - * Получает значение по указанному ключу. - * - * @param key Ключ. - * @return Значение. Если не найдено, возвращает null. - * - * @throws IllegalArgumentException Если значение параметра key является null. - */ - String get(String key) throws IllegalArgumentException; - - /** - * Устанавливает значение по указанному ключу. - * - * @param key Ключ. - * @param value Значение. - * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было записано, - * возвращает null. - * - * @throws IllegalArgumentException Если значение параметров key или value является null. - */ - String put(String key, String value) throws IllegalArgumentException; - - /** - * Удаляет значение по указанному ключу. - * - * @param key Ключ. - * @return Значение. Если не найдено, возвращает null. - * - * @throws IllegalArgumentException Если значение параметра key является null. - */ - String remove(String key) throws IllegalArgumentException; - - /** - * Возвращает количество ключей в таблице. - * - * @return Количество ключей в таблице. - */ - int size(); - - /** - * Возвращает количество изменений в таблице. - * - * @return Количество изменений в таблице. - */ - int getNumberOfUncommittedChanges(); - - /** - * Выполняет фиксацию изменений. - * - * @return Количество сохранённых ключей. - */ - int commit(); - - /** - * Выполняет откат изменений с момента последней фиксации. - * - * @return Количество отменённых ключей. - */ - int rollback(); - - /** - * Выводит список ключей таблицы - * - * @return Список ключей. - */ - List list(); -} - diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java deleted file mode 100644 index fee5fb2d8..000000000 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; -/** - * @author Fedor Lavrentyev - * @author Dmitriy Komanov - */ -public interface TableProvider { - - /** - * Возвращает таблицу с указанным названием. - * - * @param name Название таблицы. - * @return Объект, представляющий таблицу. Если таблицы с указанным именем не существует, возвращает null. - * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. - */ - Table getTable(String name); - - /** - * Создаёт таблицу с указанным названием. - * - * @param name Название таблицы. - * @return Объект, представляющий таблицу. Если таблица уже существует, возвращает null. - * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. - */ - Table createTable(String name); - - /** - * Удаляет таблицу с указанным названием. - * - * @param name Название таблицы. - * @throws IllegalArgumentException Если название таблицы null или имеет недопустимое значение. - * @throws IllegalStateException Если таблицы с указанным названием не существует. - */ - void removeTable(String name); -} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java deleted file mode 100644 index 5823e3792..000000000 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/strings/TableProviderFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings; -/** - * Представляет интерфейс для создание экземпляров {@link TableProvider}. Предполагается, что реализация интерфейса - * фабрики будет иметь публичный конструктор без параметров. - * - * @author Fedor Lavrentyev - * @author Dmitriy Komanov - */ -public interface TableProviderFactory { - - /** - * Возвращает объект для работы с базой данных. - * - * @param dir Директория с файлами базы данных. - * @return Объект для работы с базой данных. - * @throws IllegalArgumentException Если значение директории null или имеет недопустимое значение. - */ - TableProvider create(String dir); -} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java index 021512baa..220823526 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java @@ -3,13 +3,20 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.JSONUtils; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.StoreableByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableByVolodden; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.List; import static org.junit.Assert.assertEquals; @@ -19,9 +26,11 @@ public class TableByVoloddenTest { public final String name = "test123321123322"; public final String end = ".." + File.separator + name; public final String key1 = "key1key1"; - public final String val1 = "val1val1"; - public final String val2 = "val2lav2"; - public final String val3 = "val3lav3"; + public final String val1 = "[val1val1]"; + public final String val2 = "[val2lav2]"; + public final String val3 = "[val3lav3]"; + public final List> list = new ArrayList>(); + public final String nameOfTypes = "signature.tsv"; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -29,15 +38,20 @@ public class TableByVoloddenTest { @Test public void testGetName() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(name, table.getName()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testGetNameIfTableExist() throws Exception { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(name, table.getName()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(temporaryFolder.toString(), ".." + File.separator, name) .toAbsolutePath().normalize()); } @@ -45,80 +59,108 @@ public void testGetNameIfTableExist() throws Exception { @Test public void testGet() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - assertEquals(null, table.get(key1)); + assertEquals(JSONUtils.storeableToString(table, null), JSONUtils.storeableToString(table, table.get(key1))); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testGetIfExists() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); - assertEquals(val1, table.get(key1)); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); + assertEquals(JSONUtils.storeableToString(table, val1St), JSONUtils.storeableToString(table, table.get(key1))); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testPut() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - assertEquals(null, table.put(key1, val1)); + Storeable val1St = new StoreableByVolodden(val1, list); + assertEquals(null, JSONUtils.storeableToString(table, table.put(key1, val1St))); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testPutIfExists() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); - assertEquals(val1, table.put(key1, val2)); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + table.put(key1, val1St); + assertEquals(JSONUtils.storeableToString(table, val1St), + JSONUtils.storeableToString(table, table.put(key1, val2St))); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testPutIfExistsInDataBase() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); table.commit(); - assertEquals(val1, table.put(key1, val1)); + assertEquals(JSONUtils.storeableToString(table, val1St), + JSONUtils.storeableToString(table, table.put(key1, val1St))); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testPutIfExistsInDataBaseEqual() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + table.put(key1, val1St); table.commit(); - table.put(key1, val2); - assertEquals(val2, table.put(key1, val1)); + table.put(key1, val2St); + assertEquals(JSONUtils.storeableToString(table, val2St), JSONUtils.storeableToString(table, table.put(key1, val1St))); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testPutIfExistsInDataBaseNotEqual() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + Storeable val3St = new StoreableByVolodden(val3, list); + table.put(key1, val1St); table.commit(); - table.put(key1, val2); - assertEquals(val2, table.put(key1, val3)); + table.put(key1, val2St); + assertEquals(JSONUtils.storeableToString(table, val2St), JSONUtils.storeableToString(table, table.put(key1, val3St))); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testRemove() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(null, table.remove(key1)); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @@ -126,129 +168,175 @@ public void testRemove() throws Exception { @Test public void testRemoveNull() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val2); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + table.put(key1, val2St); table.commit(); table.remove(key1); assertEquals(null, table.remove(key1)); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testRemoveIfExists() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); - assertEquals(val1, table.remove(key1)); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); + assertEquals(JSONUtils.storeableToString(table, val1St), JSONUtils.storeableToString(table, table.remove(key1))); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testSize() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(0, table.size()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testSizeWithUncommittedValues() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + list.set(0, String.class); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + table.put(key1, val1St); table.commit(); - table.put(key1, val2); + table.put(key1, val2St); assertEquals(1, table.size()); table.remove(key1); assertEquals(0, table.size()); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testGetNumberOfUncommittedChanges() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(0, table.getNumberOfUncommittedChanges()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testCommit() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(table.commit(), 0); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testRollback() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); assertEquals(0, table.rollback()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testList() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); List list = table.list(); assertEquals(0, list.size()); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testListWithValues() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); List list = table.list(); assertEquals(1, list.size()); assertEquals(key1, list.get(0)); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testListWithValuesInDataBase() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); table.commit(); List list = table.list(); assertEquals(1, list.size()); assertEquals(key1, list.get(0)); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testListWithValuesInDataBaseAndInDiff() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + Storeable val2St = new StoreableByVolodden(val2, list); + table.put(key1, val1St); table.commit(); - table.put(key1, val2); + table.put(key1, val2St); List list = table.list(); assertEquals(1, list.size()); assertEquals(key1, list.get(0)); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } @Test public void testReadFromDisk() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + create(); Table table = new TableByVolodden(name); - table.put(key1, val1); + Storeable val1St = new StoreableByVolodden(val1, list); + table.put(key1, val1St); table.commit(); Table table2 = new TableByVolodden(name); - assertEquals(val1, table2.get(key1)); + assertEquals(JSONUtils.storeableToString(table, val1St), JSONUtils.storeableToString(table, table2.get(key1))); table.remove(key1); table.commit(); + Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } + + public void create() throws IOException { + Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); + FileUtils.createDirectory(path.toString()); + File file = new File(FileUtils.get(path.toString(), nameOfTypes).toString()); + file.createNewFile(); + try (PrintWriter out = new PrintWriter(file)) { + out.print("string"); + } + list.add(String.class); + } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java index 57be01f05..617b11c28 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java @@ -3,14 +3,21 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.StoreableByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderByVolodden; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.Table; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.strings.TableProvider; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; +import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; import static org.junit.Assert.assertEquals; @@ -19,6 +26,8 @@ public class TableProviderByVoloddenTest { public final String name = "test123321123323"; public final String nameTable = "nameTable"; public final String end = ".." + File.separator + name; + public final List> list = new ArrayList>(); + public final String nameOfTypes = "signature.tsv"; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -39,8 +48,10 @@ public void testGetTableNotExists() throws Exception { public void testGetTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(name); - Table table = tableProvider.createTable(nameTable); - table.put("k", "v"); + create(); + Table table = tableProvider.createTable(nameTable, list); + Storeable val1St = new StoreableByVolodden("v", list); + table.put("k", val1St); table.commit(); table = tableProvider.getTable(nameTable); tableProvider.removeTable(nameTable); @@ -51,7 +62,8 @@ public void testGetTable() throws Exception { public void testCreateTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); - Table table = tableProvider.createTable(nameTable); + list.set(0, String.class); + Table table = tableProvider.createTable(nameTable, list); assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); @@ -62,7 +74,8 @@ public void testCreateTableIfExists() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); Files.createDirectory(Paths.get(path.toString(), nameTable)); - Table table = tableProvider.createTable(nameTable); + list.set(0, String.class); + Table table = tableProvider.createTable(nameTable, list); assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); @@ -72,12 +85,25 @@ public void testCreateTableIfExists() throws Exception { public void testRemoveTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); - Table table = tableProvider.createTable(nameTable); - table.put("k", "v"); + list.set(0, String.class); + Table table = tableProvider.createTable(nameTable, list); + Storeable val1St = new StoreableByVolodden("v", list); + table.put("k", val1St); table.commit(); tableProvider.removeTable(nameTable); assertEquals(false, Paths.get(path.toString(), nameTable).toFile().exists()); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); } + + public void create() throws IOException { + Path path = Paths.get(temporaryFolder.toString(), end, nameTable).toAbsolutePath().normalize(); + FileUtils.createDirectory(path.toString()); + File file = new File(FileUtils.get(path.toString(), nameOfTypes).toString()); + file.createNewFile(); + try (PrintWriter out = new PrintWriter(file)) { + out.print("string"); + } + list.add(String.class); + } } From 3029ad97698e95de390bd049c58d716abc41f53f Mon Sep 17 00:00:00 2001 From: volodden Date: Thu, 25 Dec 2014 07:30:00 +0300 Subject: [PATCH 11/13] Checkstyle. --- .../Volodin_Denis/Storeable/database/JSONUtils.java | 2 +- .../Storeable/database/StoreableByVolodden.java | 2 +- .../Storeable/interpreter/CommandHandler.java | 3 +-- .../interpreter/commands/CommandTableRemove.java | 2 +- .../Storeable/tests/TableByVoloddenTest.java | 9 ++++++--- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java index a08de9893..558f02fcc 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java @@ -107,4 +107,4 @@ public static Object stringToOneElementOfStoreable(Class type, String string) } return null; } -} \ No newline at end of file +} diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java index 62a1887cd..cabbfe1c0 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/StoreableByVolodden.java @@ -85,7 +85,7 @@ public StoreableByVolodden(String string, List> inputTypes) { if (string == null) { string = "[null]"; } - string = string.substring(1, string.length()-1); + string = string.substring(1, string.length() - 1); String[] array = string.split(", "); for (int i = 0; i < array.length; ++i) { if (array[i].equals("null")) { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java index 5201adec7..8c16186b9 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/CommandHandler.java @@ -28,8 +28,7 @@ public String getName() { private void checkQuantityOfArguments(final String[] args, final String commandName) throws Exception { if (((args.length != quantityOfArguments) && (quantityOfArguments != -1)) - || (args.length < 2) && (quantityOfArguments == -1)) - { + || (args.length < 2) && (quantityOfArguments == -1)) { ErrorFunctions.wrongQuantityOfArguments(commandName); } if (args.length > 1) { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java index ae4a00ee1..82a76c4b1 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/interpreter/commands/CommandTableRemove.java @@ -16,7 +16,7 @@ public CommandTableRemove() { @Override public CommandHandler create() { return new CommandHandler(name, quantityOfArguments, - (interpreterState,args) -> { + (interpreterState, args) -> { StringInterpreterState state = (StringInterpreterState) interpreterState; Table table = state.getTable(); try { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java index 220823526..8cbf48f49 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableByVoloddenTest.java @@ -129,7 +129,8 @@ public void testPutIfExistsInDataBaseEqual() throws Exception { table.put(key1, val1St); table.commit(); table.put(key1, val2St); - assertEquals(JSONUtils.storeableToString(table, val2St), JSONUtils.storeableToString(table, table.put(key1, val1St))); + assertEquals(JSONUtils.storeableToString(table, val2St), + JSONUtils.storeableToString(table, table.put(key1, val1St))); table.remove(key1); table.commit(); Files.delete(FileUtils.get(path.toString(), nameOfTypes)); @@ -147,7 +148,8 @@ public void testPutIfExistsInDataBaseNotEqual() throws Exception { table.put(key1, val1St); table.commit(); table.put(key1, val2St); - assertEquals(JSONUtils.storeableToString(table, val2St), JSONUtils.storeableToString(table, table.put(key1, val3St))); + assertEquals(JSONUtils.storeableToString(table, val2St), + JSONUtils.storeableToString(table, table.put(key1, val3St))); table.remove(key1); table.commit(); Files.delete(FileUtils.get(path.toString(), nameOfTypes)); @@ -188,7 +190,8 @@ public void testRemoveIfExists() throws Exception { Table table = new TableByVolodden(name); Storeable val1St = new StoreableByVolodden(val1, list); table.put(key1, val1St); - assertEquals(JSONUtils.storeableToString(table, val1St), JSONUtils.storeableToString(table, table.remove(key1))); + assertEquals(JSONUtils.storeableToString(table, val1St), + JSONUtils.storeableToString(table, table.remove(key1))); Files.delete(FileUtils.get(path.toString(), nameOfTypes)); Files.deleteIfExists(Paths.get(name)); } From c060b9377ad489604e81c121e326837847a12206 Mon Sep 17 00:00:00 2001 From: volodden Date: Thu, 25 Dec 2014 08:10:19 +0300 Subject: [PATCH 12/13] Final update. --- .../Storeable/database/JSONUtils.java | 25 ++++++++++++++++ .../Storeable/database/TableByVolodden.java | 19 +++++++++++- .../database/TableProviderByVolodden.java | 18 ++++++++++++ .../tests/TableProviderByVoloddenTest.java | 29 ++++++------------- 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java index 558f02fcc..c1737c1a6 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/JSONUtils.java @@ -107,4 +107,29 @@ public static Object stringToOneElementOfStoreable(Class type, String string) } return null; } + + public static String typeToString(Class type) { + if (type == Integer.class) { + return "int"; + } + if (type == Long.class) { + return "long"; + } + if (type == Byte.class) { + return "byte"; + } + if (type == Float.class) { + return "float"; + } + if (type == Double.class) { + return "double"; + } + if (type == Boolean.class) { + return "bool"; + } + if (type == String.class) { + return "string"; + } + throw new NoSuchElementException(); + } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java index 939da8310..5917a865f 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableByVolodden.java @@ -54,7 +54,24 @@ public FileMap(final String dbPath) throws Exception { readFromDisk(); readTypes(); } else { - throw new Exception("Table was not found"); + if (types == null) { + throw new Exception("Table was not found"); + } else { + FileUtils.createDirectory(databasePath); + File file = new File(FileUtils.get(databasePath, signatureFileName).toString()); + file.createNewFile(); + try (PrintWriter out = new PrintWriter(file)) { + int i = 0; + for (Class type : types) { + if (i++ != 0) { + out.print(" "); + } + out.print(JSONUtils.typeToString(type)); + } + } catch (Exception e) { + throw e; + } + } } } diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java index df6067c9b..8822394ee 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/database/TableProviderByVolodden.java @@ -6,7 +6,9 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Table; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; +import java.io.File; import java.io.IOException; +import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -22,6 +24,9 @@ public class TableProviderByVolodden implements TableProvider { private Set tables; + private final String signatureFileName = "signature.tsv"; + + private final String regExpToSplitJSON = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"; public TableProviderByVolodden(String dir) throws Exception { @@ -65,6 +70,19 @@ public Table createTable(String name, List> columnTypes) throws IOExcep } if (exists) { try { + File file = Paths.get(dbPath, name, signatureFileName).toFile(); + file.createNewFile(); + try (PrintWriter out = new PrintWriter(file)) { + int i = 0; + for (Class type : columnTypes) { + if (i++ != 0) { + out.print(" "); + } + out.print(JSONUtils.typeToString(type)); + } + } catch (Exception e) { + throw e; + } dbTable = new TableByVolodden(Paths.get(dbPath, name).normalize().toFile().toString()); tables.add(name); } catch (Exception exception) { diff --git a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java index 617b11c28..0c6b31b97 100644 --- a/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java +++ b/src/ru/fizteh/fivt/students/Volodin_Denis/Storeable/tests/TableProviderByVoloddenTest.java @@ -3,7 +3,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.FileUtils; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.StoreableByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.database.TableProviderByVolodden; import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.Storeable; @@ -11,8 +10,6 @@ import ru.fizteh.fivt.students.Volodin_Denis.Storeable.structured.TableProvider; import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -48,9 +45,9 @@ public void testGetTableNotExists() throws Exception { public void testGetTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(name); - create(); + list.add(String.class); Table table = tableProvider.createTable(nameTable, list); - Storeable val1St = new StoreableByVolodden("v", list); + Storeable val1St = new StoreableByVolodden("[v]", list); table.put("k", val1St); table.commit(); table = tableProvider.getTable(nameTable); @@ -62,9 +59,10 @@ public void testGetTable() throws Exception { public void testCreateTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); - list.set(0, String.class); + list.add(String.class); Table table = tableProvider.createTable(nameTable, list); assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable, nameOfTypes)); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); } @@ -74,9 +72,10 @@ public void testCreateTableIfExists() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); Files.createDirectory(Paths.get(path.toString(), nameTable)); - list.set(0, String.class); + list.add(String.class); Table table = tableProvider.createTable(nameTable, list); assertEquals(true, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable, nameOfTypes)); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); } @@ -85,25 +84,15 @@ public void testCreateTableIfExists() throws Exception { public void testRemoveTable() throws Exception { Path path = Paths.get(temporaryFolder.toString(), end).toAbsolutePath().normalize(); TableProvider tableProvider = new TableProviderByVolodden(path.toString()); - list.set(0, String.class); + list.add(String.class); Table table = tableProvider.createTable(nameTable, list); - Storeable val1St = new StoreableByVolodden("v", list); + Storeable val1St = new StoreableByVolodden("[v]", list); table.put("k", val1St); table.commit(); tableProvider.removeTable(nameTable); assertEquals(false, Paths.get(path.toString(), nameTable).toFile().exists()); + Files.deleteIfExists(Paths.get(path.toString(), nameTable, nameOfTypes)); Files.deleteIfExists(Paths.get(path.toString(), nameTable)); Files.deleteIfExists(path); } - - public void create() throws IOException { - Path path = Paths.get(temporaryFolder.toString(), end, nameTable).toAbsolutePath().normalize(); - FileUtils.createDirectory(path.toString()); - File file = new File(FileUtils.get(path.toString(), nameOfTypes).toString()); - file.createNewFile(); - try (PrintWriter out = new PrintWriter(file)) { - out.print("string"); - } - list.add(String.class); - } } From baeaeefdf6a9c4e5d49c8461f24ea79f05d03c9e Mon Sep 17 00:00:00 2001 From: volodden Date: Thu, 25 Dec 2014 08:10:48 +0300 Subject: [PATCH 13/13] Revert "???" This reverts commit ab326f374435c59822acf733a92acb2a69df01cb. --- .gitignore | 3 +-- .../telnet/RemoteTableProviderFactoryClass.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java diff --git a/.gitignore b/.gitignore index 6ec87e8d5..8256e2aa4 100644 --- a/.gitignore +++ b/.gitignore @@ -25,5 +25,4 @@ workbench.xmi .settings .checkstyle /MultiFileHashMap/nbproject/private/ -/MultiFileHashMap/build/ -src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java \ No newline at end of file +/MultiFileHashMap/build/ \ No newline at end of file diff --git a/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java new file mode 100644 index 000000000..9653fc720 --- /dev/null +++ b/src/ru/fizteh/fivt/students/gudkov394/telnet/RemoteTableProviderFactoryClass.java @@ -0,0 +1,13 @@ +package ru.fizteh.fivt.students.gudkov394.telnet; +import ru.fizteh.fivt.storage.structured.RemoteTableProvider; +import ru.fizteh.fivt.storage.structured.RemoteTableProviderFactory; + +import java.io.IOException; + +public class RemoteTableProviderFactoryClass implements RemoteTableProviderFactory { + + @Override + public RemoteTableProvider connect(String hostname, int port) throws IOException { + return null; + } +}