Skip to content

Commit 94e6eba

Browse files
authored
version 3.0 [rewritten]
1 parent d6369bf commit 94e6eba

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed

CloremDB/build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
plugins {
2+
id 'java-library'
3+
}
4+
5+
java {
6+
sourceCompatibility = JavaVersion.VERSION_16
7+
targetCompatibility = JavaVersion.VERSION_16
8+
}
9+
10+
dependencies {
11+
implementation 'androidx.annotation:annotation:1.3.0'
12+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package db.clorabase.clorem;
2+
3+
import androidx.annotation.NonNull;
4+
5+
import java.io.File;
6+
import java.lang.management.ThreadInfo;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.concurrent.Callable;
10+
import java.util.function.Consumer;
11+
import java.util.function.Predicate;
12+
13+
import javax.naming.NoPermissionException;
14+
15+
/**
16+
* Clorem is a simple, easy to use, and fast database engine for java applications.
17+
* It is a no-sql database which can save POJO's directly. You can organise your data
18+
* in volumes. Each volume is like a SQL table which contains the objects as rows. You can create
19+
* as many volumes as you want. You can also create as many objects as you want in
20+
* each volume. The only limitation is that the objects implement the {@link CloremObject}
21+
*
22+
* All the methods are thread safe. You can use the database in a multi-threaded environment.
23+
*
24+
* @author author Rahil khan
25+
* @version 1.0
26+
* @since 1.0
27+
*/
28+
public class Clorem {
29+
private static Clorem INSTANCE;
30+
private static File databaseDir;
31+
32+
/**
33+
* This method returns the singleton instance of the Clorem database.
34+
* @param databaseDir The directory where the database will be stored on the disk. This directory must be writable.
35+
* @return The singleton instance of the Clorem database
36+
*/
37+
public static Clorem getInstance(File databaseDir) {
38+
if (INSTANCE == null){
39+
INSTANCE = new Clorem();
40+
if (databaseDir.canRead() && databaseDir.canWrite())
41+
Clorem.databaseDir = databaseDir;
42+
else
43+
throw new RuntimeException(new NoPermissionException("You do not have permission to read/write on this directory"));
44+
}
45+
return INSTANCE;
46+
}
47+
48+
/**
49+
* This method creates a new volume in the database.
50+
* @param name The name of the volume
51+
*/
52+
public void createVolume(@NonNull String name){
53+
new File(databaseDir,name).mkdir();
54+
}
55+
56+
/**
57+
* This method deletes a volume from the database. All the objects in the volume will be deleted.
58+
* @param name The name of the volume
59+
*/
60+
public void deleteVolume(@NonNull String name){
61+
var volume = new File(databaseDir,name);
62+
var files = volume.listFiles();
63+
for (File file : files) {
64+
file.delete();
65+
}
66+
volume.delete();
67+
}
68+
69+
/**
70+
* Put an object in the database. The object must implement the {@link CloremObject} interface.
71+
* @param object The object to be saved
72+
* @param <T> The type of the object
73+
*/
74+
public synchronized <T extends CloremObject> void put(@NonNull T object){
75+
var volume = new File(databaseDir,object.getVolume());
76+
if (!volume.exists() && !volume.mkdir())
77+
throw new RuntimeException("The volume could not be created. You might not have permission to create a directory");
78+
else
79+
CloremUtils.writeObject(object,new File(volume,object.getKey()));
80+
}
81+
82+
/**
83+
* Get an object from the database.
84+
* @param key The key of the object
85+
* @param volume The volume in which the object is stored
86+
* @return The object
87+
*/
88+
public synchronized Object get(@NonNull String key,@NonNull String volume){
89+
var volumeDir = new File(databaseDir,volume);
90+
var obj = new File(volumeDir,key);
91+
if (volumeDir.isDirectory() && obj.exists())
92+
return CloremUtils.readObject(obj);
93+
else
94+
throw new IllegalArgumentException("The volume or the object does not exist");
95+
}
96+
97+
/**
98+
* Update an object in the database. Only use this method when you want to update whole object.
99+
* If you want to update only a few fields of the object, use the {@link #update(String, String, Class, Consumer)} method.
100+
* The object id must be the same as the object id of the object in the database.
101+
* @param object The object to be updated
102+
* @param <T> The type of the object
103+
*/
104+
public synchronized <T extends CloremObject> void update(@NonNull T object){
105+
var volume = new File(databaseDir,object.getVolume());
106+
var file = new File(volume,object.getKey());
107+
if (volume.isDirectory() && file.exists()){
108+
CloremUtils.writeObject(object,file);
109+
} else
110+
throw new IllegalArgumentException("The volume or the object does not exist");
111+
}
112+
113+
/**
114+
* Update an object in the database. This method is used to update only required fields of the object.
115+
* @param key The key of the object
116+
* @param volume The volume in which the object is stored
117+
* @param clazz The class of the object
118+
* @param transition The transition function which will be used to update the object
119+
* @param <T> The type of the object
120+
*/
121+
public synchronized <T extends CloremObject> void update(@NonNull String key, @NonNull String volume,@NonNull Class<T> clazz,@NonNull Consumer<T> transition){
122+
var obj = clazz.cast(get(key,volume));
123+
transition.accept(obj);
124+
if (key.equals(obj.getKey()) && volume.equals(obj.getVolume()))
125+
update(obj);
126+
else {
127+
delete(key,volume);
128+
put(obj);
129+
}
130+
}
131+
132+
/**
133+
* Delete an object from the database.
134+
* @param key The key of the object
135+
* @param volume The volume in which the object is stored
136+
*/
137+
public synchronized void delete(@NonNull String key,@NonNull String volume){
138+
var volumeDir = new File(databaseDir,volume);
139+
var obj = new File(volumeDir,key);
140+
if (volumeDir.isDirectory() && obj.exists())
141+
obj.delete();
142+
else
143+
throw new IllegalArgumentException("The volume or the object does not exist");
144+
}
145+
146+
/**
147+
* Query the database. This method returns a list of objects which satisfy the condition.
148+
* @param volume The volume in which the objects are stored
149+
* @param clazz The class of the objects
150+
* @param condition The condition which the objects must satisfy. Returns true if the object is to be included in the list.
151+
* @param <T> The type of the objects
152+
* @return A list of objects which satisfy the condition
153+
*/
154+
public <T extends CloremObject> List<T> query(@NonNull String volume,@NonNull Class<T> clazz, @NonNull Predicate<T> condition){
155+
var files = new File(databaseDir,volume).listFiles();
156+
if (files == null)
157+
throw new RuntimeException("The volume does not exist");
158+
else {
159+
var list = new ArrayList<T>();
160+
for (File file : files) {
161+
var obj = get(file.getName(),volume);
162+
try {
163+
if (condition.test(clazz.cast(obj)))
164+
list.add(clazz.cast(obj));
165+
} catch (ClassCastException ignored){}
166+
}
167+
return list;
168+
}
169+
}
170+
171+
/**
172+
* List all the objects in a volume.
173+
* @param volume The volume in which the objects are stored
174+
* @return A list of objects
175+
*/
176+
public List<Object> listObjects(@NonNull String volume){
177+
return CloremUtils.listObjects(new File(databaseDir,volume));
178+
}
179+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package db.clorabase.clorem;
2+
3+
import java.io.Serializable;
4+
5+
/**
6+
* This interface is implemented by all the objects which are to be saved in the database.
7+
* The objects must implement this interface to be saved in the database.
8+
*
9+
* @author author Rahil khan
10+
* @version 1.0
11+
* @since 1.0
12+
*/
13+
public interface CloremObject extends Serializable {
14+
15+
String getKey();
16+
String getVolume();
17+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package db.clorabase.clorem;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.io.FileNotFoundException;
6+
import java.io.FileOutputStream;
7+
import java.io.IOException;
8+
import java.io.ObjectInputStream;
9+
import java.io.ObjectOutputStream;
10+
import java.io.UncheckedIOException;
11+
import java.util.Arrays;
12+
import java.util.List;
13+
14+
public class CloremUtils {
15+
16+
protected static void writeObject(Object object, File file){
17+
try {
18+
var os = new ObjectOutputStream(new FileOutputStream(file));
19+
os.writeObject(object);
20+
os.close();
21+
} catch (IOException e) {
22+
throw new UncheckedIOException(e);
23+
}
24+
25+
}
26+
27+
protected static Object readObject(File file){
28+
try {
29+
var in = new ObjectInputStream(new FileInputStream(file));
30+
var object = in.readObject();
31+
in.close();
32+
return object;
33+
} catch (IOException | ClassNotFoundException e) {
34+
throw new RuntimeException(e);
35+
}
36+
}
37+
38+
protected static List<Object> listObjects(File volume){
39+
var files = volume.listFiles();
40+
if (files == null)
41+
throw new RuntimeException("The volume does not exist");
42+
else {
43+
var objects = new Object[files.length];
44+
for (int i = 0; i < files.length; i++) {
45+
objects[i] = readObject(files[i]);
46+
}
47+
return Arrays.asList(objects);
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)