Implemented exists()

This commit is contained in:
Andrea Cavalli 2019-03-10 00:21:52 +01:00
parent 1def19d219
commit 2e9d989a6c
10 changed files with 303 additions and 114 deletions

34
pom.xml
View File

@ -27,9 +27,15 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>4.11</version> <version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -110,6 +116,28 @@
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version> <version>2.8.2</version>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>it.cavallium.strangedb.server.Server</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
</build> </build>

View File

@ -4,12 +4,14 @@ import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import it.cavallium.strangedb.database.IReferencesIO; import it.cavallium.strangedb.database.IReferencesIO;
import it.cavallium.strangedb.database.references.DatabaseReferencesMetadata; import it.cavallium.strangedb.database.references.DatabaseReferencesMetadata;
import org.json.*; import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static it.cavallium.strangedb.server.TreePath.stringToNode; import static it.cavallium.strangedb.server.TreePath.stringToNode;
@ -18,8 +20,10 @@ public class DatabaseNodesIO {
private final IReferencesIO referencesIO; private final IReferencesIO referencesIO;
private static final int isArrayMask = 0b10000000000000000000000000000000; private static final int isArrayMask = 0b10000000000000000000000000000000;
private static final int isValueMask = 0b01000000000000000000000000000000; private static final int isValueMask = 0b01000000000000000000000000000000;
private static final int isNumberMask = 0b11000000000000000000000000000000; private static final int isValueNumberMask = 0b00000000000000000000000000000001;
private static final int nodeCountMask = 0b01111111111111111111111111111111; private static final int isValueStringMask = 0b00000000000000000000000000000010;
private static final int isValueBooleanMask = 0b00000000000000000000000000000100;
private static final int nodeCountMask = 0b01111111111111111111111111111111;
private static final int arrayCountMask = 0b01111111111111111111111111111111; private static final int arrayCountMask = 0b01111111111111111111111111111111;
public DatabaseNodesIO(IReferencesIO referencesIO, DatabaseReferencesMetadata referencesMetadata) throws IOException { public DatabaseNodesIO(IReferencesIO referencesIO, DatabaseReferencesMetadata referencesMetadata) throws IOException {
@ -37,8 +41,12 @@ public class DatabaseNodesIO {
} }
public String get(TreePath path) throws IOException { public String get(TreePath path) throws IOException {
Node foundNode = getNode(path); try {
return toJson(foundNode); Node foundNode = getNode(path);
return toJson(foundNode);
} catch (NullPointerException ex) {
return "null";
}
} }
private String toJson(Node foundNode) throws IOException { private String toJson(Node foundNode) throws IOException {
@ -82,12 +90,7 @@ public class DatabaseNodesIO {
} }
case VALUE: { case VALUE: {
ValueNode valueNode = (ValueNode) foundNode; ValueNode valueNode = (ValueNode) foundNode;
sb.append(org.json.JSONObject.quote(loadValue(valueNode.getValueReference()))); sb.append(loadValue(valueNode));
break;
}
case NUMBER: {
NumberNode valueNode = (NumberNode) foundNode;
sb.append(loadNumber(valueNode.getNumberReference()));
break; break;
} }
} }
@ -98,16 +101,19 @@ public class DatabaseNodesIO {
referencesIO.writeToReference(reference, valueBytes.limit(), valueBytes); referencesIO.writeToReference(reference, valueBytes.limit(), valueBytes);
} }
private String loadValue(long reference) throws IOException { private String loadValue(ValueNode valueNode) throws IOException {
ByteBuffer buffer = referencesIO.readFromReference(reference); ByteBuffer buffer = referencesIO.readFromReference(valueNode.getReference());
return StandardCharsets.UTF_8.decode(buffer).toString(); ByteBuffer valueBuffer = referencesIO.readFromReference(valueNode.getValueReference());
} switch (valueNode.getValueType()) {
case STRING:
private void setNumber(long reference, double value) throws IOException { return JSONObject.quote(StandardCharsets.UTF_8.decode(valueBuffer).toString());
ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES); case NUMBER:
buffer.putDouble(value); return JSONObject.doubleToString(valueBuffer.getDouble());
buffer.flip(); case BOOLEAN:
referencesIO.writeToReference(reference, buffer.limit(), buffer); return valueBuffer.get() == 1 ? "true" : "false";
default:
throw new RuntimeException();
}
} }
private double loadNumber(long reference) throws IOException { private double loadNumber(long reference) throws IOException {
@ -149,7 +155,6 @@ public class DatabaseNodesIO {
classNode.setProperty(propertyName, valueReference); classNode.setProperty(propertyName, valueReference);
break; break;
} }
case NUMBER:
case VALUE: { case VALUE: {
throw new IOException("WTF you shouldn't be here!"); throw new IOException("WTF you shouldn't be here!");
} }
@ -171,6 +176,15 @@ public class DatabaseNodesIO {
case '{': case '{':
JSONObject obj = new JSONObject(value); JSONObject obj = new JSONObject(value);
return importJsonNode(obj, reference); return importJsonNode(obj, reference);
case 'u':
if (value.equals("undefined"))
return importJsonNode(value, reference);
case 'N':
if (value.equals("NaN"))
return importJsonNode(value, reference);
case 'n':
if (value.equals("null"))
return importJsonNode(value, reference);
case '"': case '"':
return importJsonNode(value.substring(1, value.length() - 1), reference); return importJsonNode(value.substring(1, value.length() - 1), reference);
case '0': case '0':
@ -185,6 +199,12 @@ public class DatabaseNodesIO {
case '9': case '9':
case '.': case '.':
return importJsonNode(Double.parseDouble(value), reference); return importJsonNode(Double.parseDouble(value), reference);
case 't':
if (value.equals("true"))
return importJsonNode(true, reference);
case 'f':
if (value.equals("false"))
return importJsonNode(false, reference);
default: default:
throw new IOException("Unrecognized input"); throw new IOException("Unrecognized input");
} }
@ -199,6 +219,9 @@ public class DatabaseNodesIO {
if (o instanceof ArrayList<?>) { if (o instanceof ArrayList<?>) {
o = new JSONArray((ArrayList<?>) o); o = new JSONArray((ArrayList<?>) o);
} }
if (o instanceof HashMap<?, ?>) {
o = new JSONObject((HashMap<?, ?>) o);
}
if (o instanceof JSONArray) { if (o instanceof JSONArray) {
JSONArray array = (JSONArray) o; JSONArray array = (JSONArray) o;
int length = array.length(); int length = array.length();
@ -217,12 +240,13 @@ public class DatabaseNodesIO {
for (Map.Entry<String, Object> entry : jsonProperties.entrySet()) { for (Map.Entry<String, Object> entry : jsonProperties.entrySet()) {
NodeProperty nodeProperty = new NodeProperty(stringToNode(entry.getKey()), importJsonNode(entry.getValue())); NodeProperty nodeProperty = new NodeProperty(stringToNode(entry.getKey()), importJsonNode(entry.getValue()));
properties[i] = nodeProperty; properties[i] = nodeProperty;
i++;
} }
Node node = createNewNodeNode(properties, reference); Node node = createNewNodeNode(properties, reference);
setNode(node); setNode(node);
return node.getReference(); return node.getReference();
} else if (o instanceof String) { } else if (o instanceof String) {
Node node = createNewValueNode((String) o, reference); Node node = createNewValueNode(o, ValueType.STRING, reference);
setNode(node); setNode(node);
return node.getReference(); return node.getReference();
} else if (o instanceof Double || o instanceof Float || o instanceof Integer || o instanceof Long) { } else if (o instanceof Double || o instanceof Float || o instanceof Integer || o instanceof Long) {
@ -233,12 +257,14 @@ public class DatabaseNodesIO {
number = (Long) o; number = (Long) o;
} else if (o instanceof Float) { } else if (o instanceof Float) {
number = (Float) o; number = (Float) o;
} else if (o instanceof Double) {
number = (Double) o;
} else { } else {
throw new RuntimeException(); number = (Double) o;
} }
Node node = createNewNumberNode(number+0, reference); Node node = createNewValueNode(number, ValueType.NUMBER, reference);
setNode(node);
return node.getReference();
} else if (o instanceof Boolean) {
Node node = createNewValueNode(o, ValueType.BOOLEAN, reference);
setNode(node); setNode(node);
return node.getReference(); return node.getReference();
} else { } else {
@ -252,6 +278,7 @@ public class DatabaseNodesIO {
public boolean exists(TreePath path) throws IOException { public boolean exists(TreePath path) throws IOException {
TreePathWalker pathWalker = new TreePathWalker(path); TreePathWalker pathWalker = new TreePathWalker(path);
pathWalker.walkToRoot();
Node node = loadNode(0); Node node = loadNode(0);
while (pathWalker.hasNext()) { while (pathWalker.hasNext()) {
TreePath nodePath = pathWalker.next(); TreePath nodePath = pathWalker.next();
@ -260,7 +287,7 @@ public class DatabaseNodesIO {
return false; return false;
} }
int offset = nodePath.getArrayOffset(); int offset = nodePath.getArrayOffset();
if (!((ArrayNode)node).hasItem(offset)) { if (!((ArrayNode) node).hasItem(offset)) {
return false; return false;
} }
long nodeReference = ((ArrayNode) node).getItem(offset); long nodeReference = ((ArrayNode) node).getItem(offset);
@ -280,6 +307,52 @@ public class DatabaseNodesIO {
return node != null; return node != null;
} }
public int size(CharSequence path) throws IOException {
return size(TreePath.get(path));
}
public int size(TreePath path) throws IOException {
TreePathWalker pathWalker = new TreePathWalker(path);
pathWalker.walkToRoot();
Node node = loadNode(0);
while (pathWalker.hasNext()) {
TreePath nodePath = pathWalker.next();
if (nodePath.isArrayOffset()) {
if (node.getType() != NodeType.ARRAY) {
throw new NullPointerException("Node not found");
}
int offset = nodePath.getArrayOffset();
if (!((ArrayNode) node).hasItem(offset)) {
throw new NullPointerException("Node not found");
}
long nodeReference = ((ArrayNode) node).getItem(offset);
node = loadNode(nodeReference);
} else if (nodePath.isNodeProperty()) {
if (node.getType() == NodeType.ARRAY) {
throw new NullPointerException("Node not found");
}
byte[] propertyName = nodePath.getNodeValue();
if (!((ClassNode) node).hasProperty(propertyName)) {
throw new NullPointerException("Node not found");
}
long nodeReference = ((ClassNode) node).getProperty(propertyName);
node = loadNode(nodeReference);
}
}
if (node != null) {
switch (node.getType()) {
case ARRAY:
return ((ArrayNode) node).countItems();
case CLASS:
return ((ClassNode) node).countProperties();
default:
throw new NullPointerException("You can't get the size of this node!");
}
} else {
throw new NullPointerException("Node not found");
}
}
private Node getNode(TreePath path) throws IOException { private Node getNode(TreePath path) throws IOException {
TreePathWalker pathWalker = new TreePathWalker(path); TreePathWalker pathWalker = new TreePathWalker(path);
pathWalker.walkToRoot(); pathWalker.walkToRoot();
@ -320,27 +393,43 @@ public class DatabaseNodesIO {
return new ArrayNode(reference, items); return new ArrayNode(reference, items);
} }
private Node createNewValueNode() throws IOException { private Node createNewValueNode(ValueType type) throws IOException {
long reference = referencesIO.allocateReference(); long reference = referencesIO.allocateReference();
return new ValueNode(reference, referencesIO.allocateReference()); return new ValueNode(reference, referencesIO.allocateReference(), type);
} }
private Node createNewValueNode(String value) throws IOException { private Node createNewValueNode(String value) throws IOException {
return createNewValueNode(value, referencesIO.allocateReference()); return createNewValueNode(value, ValueType.STRING, referencesIO.allocateReference());
} }
private Node createNewValueNode(String value, long reference) throws IOException { private Node createNewValueNode(double value) throws IOException {
byte[] string = value.getBytes(StandardCharsets.UTF_8); return createNewValueNode(value, ValueType.NUMBER, referencesIO.allocateReference());
long dataReference = referencesIO.allocateReference(string.length, ByteBuffer.wrap(string));
return new ValueNode(reference, dataReference);
} }
private Node createNewNumberNode(double value, long reference) throws IOException { private Node createNewValueNode(Object value, ValueType valueType, long reference) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(Double.BYTES); ByteBuffer buffer = null;
buffer.putDouble(value); switch (valueType) {
buffer.flip(); case STRING:
long dataReference = referencesIO.allocateReference(buffer.limit(), buffer); buffer = StandardCharsets.UTF_8.encode((String) value);
return new NumberNode(reference, dataReference); break;
case NUMBER:
buffer = ByteBuffer.allocate(Double.BYTES);
buffer.putDouble((Double) value);
buffer.flip();
break;
case BOOLEAN:
buffer = ByteBuffer.allocate(Byte.BYTES);
buffer.put(((boolean) value) ? (byte) 1 : 0);
buffer.flip();
break;
default:
throw new RuntimeException();
}
long dataReference = -1;
if (buffer != null) {
dataReference = referencesIO.allocateReference(buffer.limit(), buffer);
}
return new ValueNode(reference, dataReference, valueType);
} }
private Node createNewNodeNode() throws IOException { private Node createNewNodeNode() throws IOException {
@ -383,15 +472,22 @@ public class DatabaseNodesIO {
buffer = ByteBuffer.wrap(dataOutput.toByteArray()); buffer = ByteBuffer.wrap(dataOutput.toByteArray());
break; break;
case VALUE: case VALUE:
ValueNode valueNode = (ValueNode) node;
buffer = ByteBuffer.allocate(Integer.BYTES + Long.BYTES); buffer = ByteBuffer.allocate(Integer.BYTES + Long.BYTES);
buffer.putInt(isValueMask); switch (valueNode.getValueType()) {
buffer.putLong(((ValueNode) node).getValueReference()); case STRING:
buffer.flip(); buffer.putInt(isValueMask | isValueStringMask);
break; break;
case NUMBER: case NUMBER:
buffer = ByteBuffer.allocate(Integer.BYTES + Long.BYTES); buffer.putInt(isValueMask | isValueNumberMask);
buffer.putInt(isNumberMask); break;
buffer.putLong(((NumberNode) node).getNumberReference()); case BOOLEAN:
buffer.putInt(isValueMask | isValueBooleanMask);
break;
default:
throw new RuntimeException();
}
buffer.putLong(valueNode.getValueReference());
buffer.flip(); buffer.flip();
break; break;
default: default:
@ -404,8 +500,7 @@ public class DatabaseNodesIO {
Node node; Node node;
ByteBuffer nodeData = referencesIO.readFromReference(reference); ByteBuffer nodeData = referencesIO.readFromReference(reference);
int propertiesCount = nodeData.getInt(); int propertiesCount = nodeData.getInt();
boolean isNumber = (propertiesCount & isNumberMask) == isNumberMask; boolean isArray = (propertiesCount & isArrayMask) != 0;
boolean isArray = !isNumber && (propertiesCount & isArrayMask) != 0;
if (isArray) { if (isArray) {
int arrayElementsCount = propertiesCount & arrayCountMask; int arrayElementsCount = propertiesCount & arrayCountMask;
long[] arrayElementsReferences = new long[arrayElementsCount]; long[] arrayElementsReferences = new long[arrayElementsCount];
@ -414,13 +509,18 @@ public class DatabaseNodesIO {
} }
node = new ArrayNode(reference, arrayElementsReferences); node = new ArrayNode(reference, arrayElementsReferences);
} else { } else {
boolean isValue = !isNumber && (propertiesCount & isValueMask) != 0; boolean isValue = (propertiesCount & isValueMask) != 0;
if (isValue) { if (isValue) {
long valueReference = nodeData.getLong(); long dataReference = nodeData.getLong();
node = new ValueNode(reference, valueReference); if ((propertiesCount & isValueStringMask) != 0) {
} else if (isNumber) { node = new ValueNode(reference, dataReference, ValueType.STRING);
long numberReference = nodeData.getLong(); } else if ((propertiesCount & isValueNumberMask) != 0) {
node = new NumberNode(reference, numberReference); node = new ValueNode(reference, dataReference, ValueType.NUMBER);
} else if ((propertiesCount & isValueBooleanMask) != 0) {
node = new ValueNode(reference, dataReference, ValueType.BOOLEAN);
} else {
throw new IOException();
}
} else { } else {
NodeProperty[] nodeProperties = new NodeProperty[propertiesCount & nodeCountMask]; NodeProperty[] nodeProperties = new NodeProperty[propertiesCount & nodeCountMask];
for (int i = 0; i < propertiesCount; i++) { for (int i = 0; i < propertiesCount; i++) {

View File

@ -24,4 +24,8 @@ public class DatabaseSimple extends DatabaseCore {
public boolean exists(CharSequence path) throws IOException { public boolean exists(CharSequence path) throws IOException {
return databaseNodesIO.exists(path); return databaseNodesIO.exists(path);
} }
public int size(CharSequence path) throws IOException {
return databaseNodesIO.size(path);
}
} }

View File

@ -3,6 +3,5 @@ package it.cavallium.strangedb.server;
public enum NodeType { public enum NodeType {
VALUE, VALUE,
CLASS, CLASS,
ARRAY, ARRAY
NUMBER;
} }

View File

@ -1,35 +0,0 @@
package it.cavallium.strangedb.server;
public class NumberNode implements Node {
private final long reference;
private long value;
public NumberNode(long reference, long value) {
this.reference = reference;
this.value = value;
}
public long getNumberReference() {
return value;
}
public void setValue(long value) {
this.value = value;
}
@Override
public NodeType getType() {
return NodeType.NUMBER;
}
@Override
public long getReference() {
return reference;
}
@Override
public Node copy() {
return new NumberNode(reference, value);
}
}

View File

@ -4,6 +4,7 @@ import com.sun.net.httpserver.HttpServer;
import it.cavallium.strangedb.server.http.ExistsHandler; import it.cavallium.strangedb.server.http.ExistsHandler;
import it.cavallium.strangedb.server.http.GetHandler; import it.cavallium.strangedb.server.http.GetHandler;
import it.cavallium.strangedb.server.http.SetHandler; import it.cavallium.strangedb.server.http.SetHandler;
import it.cavallium.strangedb.server.http.SizeHandler;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -19,6 +20,7 @@ public class Server {
server.createContext("/get", new GetHandler(this)); server.createContext("/get", new GetHandler(this));
server.createContext("/set", new SetHandler(this)); server.createContext("/set", new SetHandler(this));
server.createContext("/exists", new ExistsHandler(this)); server.createContext("/exists", new ExistsHandler(this));
server.createContext("/size", new SizeHandler(this));
server.setExecutor(null); server.setExecutor(null);
server.start(); server.start();
} }
@ -41,6 +43,10 @@ public class Server {
return database.exists(path); return database.exists(path);
} }
public int size(CharSequence path) throws IOException {
return database.size(path);
}
public String get(CharSequence path) throws IOException { public String get(CharSequence path) throws IOException {
return database.get(path); return database.get(path);
} }

View File

@ -5,11 +5,13 @@ import java.util.Arrays;
public class ValueNode implements Node { public class ValueNode implements Node {
private final long reference; private final long reference;
private final ValueType valueType;
private long value; private long value;
public ValueNode(long reference, long value) { public ValueNode(long reference, long value, ValueType valueType) {
this.reference = reference; this.reference = reference;
this.value = value; this.value = value;
this.valueType = valueType;
} }
public long getValueReference() { public long getValueReference() {
@ -25,6 +27,10 @@ public class ValueNode implements Node {
return NodeType.VALUE; return NodeType.VALUE;
} }
public ValueType getValueType() {
return valueType;
}
@Override @Override
public long getReference() { public long getReference() {
return reference; return reference;
@ -32,6 +38,6 @@ public class ValueNode implements Node {
@Override @Override
public Node copy() { public Node copy() {
return new ValueNode(reference, value); return new ValueNode(reference, value, valueType);
} }
} }

View File

@ -0,0 +1,7 @@
package it.cavallium.strangedb.server;
public enum ValueType {
STRING,
NUMBER,
BOOLEAN
}

View File

@ -0,0 +1,37 @@
package it.cavallium.strangedb.server.http;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import it.cavallium.strangedb.server.Server;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
public class SizeHandler implements HttpHandler {
private final Server server;
public SizeHandler(Server server) {
this.server = server;
}
@Override
public void handle(HttpExchange exchange) throws IOException {
String requestPath = exchange.getRequestURI().toString().split("/size/", 2)[1].replace('(', '[').replace(')', ']');
int responseCode = 500;
String response;
try {
response = "" + server.size(requestPath);
responseCode = 200;
} catch (Exception ex) {
ex.printStackTrace();
response = "Error";
}
byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);
exchange.sendResponseHeaders(responseCode, responseBytes.length);
OutputStream os = exchange.getResponseBody();
os.write(responseBytes);
os.close();
}
}

View File

@ -1,14 +1,15 @@
package it.cavallium.strangedb.server; package it.cavallium.strangedb.server;
import org.junit.After;
import org.junit.Before; import org.junit.jupiter.api.AfterEach;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import static junit.framework.Assert.*; import static org.junit.jupiter.api.Assertions.*;
public class GetSetExistsTest { public class GetSetExistsTest {
@ -17,7 +18,7 @@ public class GetSetExistsTest {
private Path path3; private Path path3;
private DatabaseSimple db; private DatabaseSimple db;
@Before @BeforeEach
public void setUp() throws Exception { public void setUp() throws Exception {
path1 = Files.createTempFile("db-tests-", ".db"); path1 = Files.createTempFile("db-tests-", ".db");
path2 = Files.createTempFile("db-tests-", ".db"); path2 = Files.createTempFile("db-tests-", ".db");
@ -32,22 +33,58 @@ public class GetSetExistsTest {
db.set("", "{}"); db.set("", "{}");
assertTrue(db.exists("")); assertTrue(db.exists(""));
assertEquals(db.get(""), "{}"); assertEquals(db.get(""), "{}");
db.set("brightness", "\"15\""); db.set("value", "{}");
db.set("value.int", "12");
db.set("value.number", "12.13");
db.set("value.null", "null");
db.set("value.boolean", "true");
db.set("value.undefined", "undefined");
db.set("value.string", "\"test\"");
db.set("value.array", "[1,2,3,4,5]");
db.set("value.object", "{a: 1, b: \"2\", c: [3], d: {}}");
} }
@Test @Test
public void shouldGetObject() throws IOException { public void shouldGetObject() throws IOException {
assertFalse(db.exists("brightness")); db.set("", "{\n" +
db.set("brightness", "\"15\""); "\t\"value\": {\n" +
assertTrue(db.exists("brightness")); "\t\t\"int\": 12,\n" +
assertEquals(db.get("brightness"), "\"15\""); "\t\t\"number\": 12.13," +
assertEquals(db.get(""), "{brightness:\"15\"}"); "nil: null,\n" +
db.set("brightness", "\"16\""); "\t\t\"boolean\": true,\n" +
assertEquals(db.get("brightness"), "\"16\""); "\t\t\"string\": \"test\",\n" +
assertEquals(db.get(""), "{brightness:\"16\"}"); "\t\t\"array\": [1,2,3,4],\n" +
"\t\t\"object\": {\n" +
"\t\t\t\"a\": 1,\n" +
"\t\t\t\"b\": \"2\",\n" +
"\t\t\t\"c\": [3],\n" +
"\t\t\t\"d\": {}\n" +
"\t\t}\n" +
"\t}\n" +
"}");
assertFalse(db.exists("random"));
assertTrue(db.exists("value"));
assertEquals("12", db.get("value.int"));
assertEquals("12.13", db.get("value.number"));
assertEquals("null", db.get("value.nil"));
assertEquals("true", db.get("value.boolean"));
assertEquals("\"test\"", db.get("value.string"));
assertEquals("[1,2,3,4]", db.get("value.array"));
assertEquals("1", db.get("value.object.a"));
assertEquals("\"2\"", db.get("value.object.b"));
assertEquals("[3]", db.get("value.object.c"));
assertEquals("{}", db.get("value.object.d"));
} }
@After @Test
public void shouldGetSize() throws IOException {
db.set("", "{array:[1,2,3,4,5], object: {a: 1, b: 2, c: 3}, string: \"test\"}");
assertEquals(5, db.size("array"));
assertEquals(3, db.size("object"));
assertThrows(NullPointerException.class, () -> db.size("test"));
}
@AfterEach
public void tearDown() throws Exception { public void tearDown() throws Exception {
db.close(); db.close();
Files.deleteIfExists(path1); Files.deleteIfExists(path1);