From ffac4190b97d4e180929efa7cb63425342ee3161 Mon Sep 17 00:00:00 2001 From: Vyacheslav Tyutyunkov Date: Thu, 21 Mar 2013 17:17:05 +0700 Subject: [PATCH] #21 --- jejdb/src/cpp/jejdb.c | 1 - jejdb/src/java/org/ejdb/Test.java | 1 - jejdb/src/java/org/ejdb/Test2.java | 10 +- jejdb/src/java/org/ejdb/driver/EJDB.java | 131 +++++++++++++-- jejdb/src/java/org/ejdb/driver/EJDBCollection.java | 182 +++++++++++++++++++-- jejdb/src/java/org/ejdb/driver/EJDBQuery.java | 37 +++-- jejdb/src/java/org/ejdb/driver/EJDBResultSet.java | 21 ++- 7 files changed, 331 insertions(+), 52 deletions(-) diff --git a/jejdb/src/cpp/jejdb.c b/jejdb/src/cpp/jejdb.c index d420685..358620d 100755 --- a/jejdb/src/cpp/jejdb.c +++ b/jejdb/src/cpp/jejdb.c @@ -165,7 +165,6 @@ static void update_coll_meta(JNIEnv *env, jobject obj, EJCOLL *coll) { (*env)->SetBooleanField(env, jopts, largeID, coll->tdb->opts & TDBTLARGE ? JNI_TRUE : JNI_FALSE); (*env)->SetBooleanField(env, jopts, compressedID, coll->tdb->opts & TDBTDEFLATE ? JNI_TRUE : JNI_FALSE); - // TODO: indexes jclass indexClazz = (*env)->FindClass(env, "org/ejdb/driver/EJDBCollection$Index"); jclass indexTypeClazz = (*env)->FindClass(env, "org/ejdb/driver/EJDBCollection$IndexType"); jmethodID initIndex = (*env)->GetMethodID(env, indexClazz, "", "()V"); diff --git a/jejdb/src/java/org/ejdb/Test.java b/jejdb/src/java/org/ejdb/Test.java index f0a47cb..4c598cf 100644 --- a/jejdb/src/java/org/ejdb/Test.java +++ b/jejdb/src/java/org/ejdb/Test.java @@ -6,7 +6,6 @@ import org.bson.types.BasicBSONList; import org.bson.types.ObjectId; import org.ejdb.driver.EJDB; import org.ejdb.driver.EJDBCollection; -import org.ejdb.driver.EJDBDriver; import org.ejdb.driver.EJDBQuery; import java.io.IOException; diff --git a/jejdb/src/java/org/ejdb/Test2.java b/jejdb/src/java/org/ejdb/Test2.java index be6e0ce..ffe16e8 100644 --- a/jejdb/src/java/org/ejdb/Test2.java +++ b/jejdb/src/java/org/ejdb/Test2.java @@ -1,7 +1,5 @@ package org.ejdb; -import com.sun.org.apache.xpath.internal.SourceTree; - import org.bson.BSONObject; import org.bson.BasicBSONObject; import org.ejdb.driver.EJDB; @@ -9,6 +7,7 @@ import org.ejdb.driver.EJDBCollection; import org.ejdb.driver.EJDBQuery; import org.ejdb.driver.EJDBResultSet; +import java.io.IOException; import java.util.Random; /** @@ -21,7 +20,7 @@ public class Test2 { public static final int TEST_COUNT = 15; public static final Random random = new Random(System.currentTimeMillis()); - public static void main(String[] args) { + public static void main(String[] args) throws IOException { EJDB db = new EJDB(); try { @@ -30,6 +29,8 @@ public class Test2 { EJDBCollection test = db.getCollection("test"); + System.out.println(test); + test.setIndex("random", EJDBCollection.JBIDXNUM); test.updateMeta(); @@ -79,7 +80,6 @@ public class Test2 { System.out.println(r); } rs.close(); - } finally { db.close(); } @@ -93,7 +93,7 @@ public class Test2 { bsonObject.put("name", "Object#" + INDEX); bsonObject.put("time", System.currentTimeMillis()); bsonObject.put("index", INDEX); - bsonObject.put("random", random.nextLong()); + bsonObject.put("random", (random.nextBoolean() ? -1 : 1) * random.nextInt(65536)); bsonObject.put("randomBoolean", random.nextBoolean()); bsonObject.put("randomDouble", random.nextDouble()); bsonObject.put("smallRandom", random.nextInt(10)); diff --git a/jejdb/src/java/org/ejdb/driver/EJDB.java b/jejdb/src/java/org/ejdb/driver/EJDB.java index 70b509a..176138e 100644 --- a/jejdb/src/java/org/ejdb/driver/EJDB.java +++ b/jejdb/src/java/org/ejdb/driver/EJDB.java @@ -63,56 +63,151 @@ public class EJDB { collections = new HashMap(); } + /** + * @return EJDB path + */ public String getPath() { return path; } - public void open(String path) { + /** + * Open database using default open mode. + *

+ * Default open mode: JBOWRITER | JBOCREAT | JBOTSYNC + * + * @param path EJDB path + * @throws EJDBException + */ + public void open(String path) throws EJDBException { this.open(path, JBO_DEFAULT); } - public native void open(String path, int mode); + /** + * Open database. + *

+ * Default open mode: JBOWRITER | JBOCREAT | JBOTSYNC + * + * @param path EJDB path + * @param mode Open mode + * @throws EJDBException + */ + public native void open(String path, int mode) throws EJDBException; + /** + * Check if database in opened state. + */ public native boolean isOpen(); - public native void close(); + /** + * Close database. + * If database was not opened it does nothing. + * + * @throws EJDBException + */ + public native void close() throws EJDBException; - public native void sync(); + /** + * Synchronize entire EJDB database and all its collections with storage. + * + * @throws EJDBException + */ + public native void sync() throws EJDBException; - public native void updateMeta(); + /** + * Update description of EJDB database and its collections. + * + * @throws EJDBException + */ + public native void updateMeta() throws EJDBException; - public EJDBCollection ensureCollection(String cname) { + /** + * Automatically creates new collection if it does't exists with using default collection options + * + * @param cname Collection name + * @throws EJDBException + * @see org.ejdb.driver.EJDBCollection#ensureExists() + */ + public EJDBCollection ensureCollection(String cname) throws EJDBException { return this.ensureCollection(cname, null); } - public EJDBCollection ensureCollection(String cname, EJDBCollection.Options opts) { + /** + * Automatically creates new collection if it does't exists. + * Collection options `opts` are applied only for newly created collection. + * For existing collections `opts` takes no effect. + * + * @param cname Collection name + * @param opts Collection options + * @throws EJDBException + * @see EJDBCollection#ensureExists(org.ejdb.driver.EJDBCollection.Options) + */ + public EJDBCollection ensureCollection(String cname, EJDBCollection.Options opts) throws EJDBException { EJDBCollection collection = getCollection(cname); collection.ensureExists(opts); return collection; } - public void dropCollection(String cname) { + /** + * Drop collection by name. + * + * @param cname Collection name + * @throws EJDBException + * @see org.ejdb.driver.EJDBCollection#drop() + */ + public void dropCollection(String cname) throws EJDBException { this.dropCollection(cname, false); } - public void dropCollection(String cname, boolean prune) { + /** + * Drop collection. + * + * @param cname Collection name + * @param prune If true the collection data will erased from disk. + * @throws EJDBException + * @see org.ejdb.driver.EJDBCollection#drop(boolean) + */ + public void dropCollection(String cname, boolean prune) throws EJDBException { getCollection(cname).drop(prune); } - public EJDBCollection getCollection(String cname) { + /** + * Returns collection object (without automatical creation) + * + * @param cname Collection name + * @return collection object + * @throws EJDBException + * @see EJDB#getCollection(String, boolean, org.ejdb.driver.EJDBCollection.Options) + */ + public EJDBCollection getCollection(String cname) throws EJDBException { return this.getCollection(cname, false); } - public EJDBCollection getCollection(String cname, boolean ecreate) { + /** + * Returns collection object + * + * @param cname Collection name + * @param ecreate Automatically collection creation flag + * @return collection object + * @throws EJDBException + * @see EJDB#getCollection(String, boolean, org.ejdb.driver.EJDBCollection.Options) + */ + public EJDBCollection getCollection(String cname, boolean ecreate) throws EJDBException { return this.getCollection(cname, ecreate, null); } - public EJDBCollection getCollection(String cname, boolean ecreate, EJDBCollection.Options opts) { + /** + * Returns collection object + * + * @param cname Collection name + * @param ecreate Automatically collection creation flag + * @param opts Collection options + * @return collection object + * @throws EJDBException + */ + public EJDBCollection getCollection(String cname, boolean ecreate, EJDBCollection.Options opts) throws EJDBException { if (!this.isOpen()) { - // todo: check isOpen - throw new RuntimeException("EJDB not opened"); -// throw new EJDBException(0, "EJDB not opened"); + throw new EJDBException(0, "EJDB not opened"); } EJDBCollection collection = collections.containsKey(cname) ? collections.get(cname) : new EJDBCollection(this, cname); @@ -124,10 +219,16 @@ public class EJDB { return collection; } + /** + * Returns names of existed collections + */ public Collection getCollectionNames() { return collections.keySet(); } + /** + * Returns collection objects for all existed collections + */ public Collection getCollections() { return collections.values(); } diff --git a/jejdb/src/java/org/ejdb/driver/EJDBCollection.java b/jejdb/src/java/org/ejdb/driver/EJDBCollection.java index 7d8b76c..449ce58 100644 --- a/jejdb/src/java/org/ejdb/driver/EJDBCollection.java +++ b/jejdb/src/java/org/ejdb/driver/EJDBCollection.java @@ -63,47 +63,131 @@ public class EJDBCollection { this.cname = cname; } + /** + * @return EJDB object + */ public EJDB getDB() { return db; } + /** + * @return collection name + */ public String getName() { return cname; } + /** + * @return collection exists status + */ public boolean isExists() { return exists; } + /** + * @return collection options {@link Options} + */ public Options getOptions() { return options; } + /** + * @return indexes info + */ public Collection getIndexes() { return indexes; } - public void ensureExists() { + /** + * Automatically creates new collection if it does't exists with using default collection options. + * @see EJDBCollection#ensureExists(org.ejdb.driver.EJDBCollection.Options) + * + * @throws EJDBException + */ + public void ensureExists() throws EJDBException { this.ensureExists(null); } - public native void ensureExists(Options opts); + /** + * Automatically creates new collection if it does't exists. + * Collection options `opts` are applied only for newly created collection. + * For existing collections `opts` takes no effect. + * + * @param opts Collection options. + * @throws EJDBException + */ + public native void ensureExists(Options opts) throws EJDBException; - public void drop() { + /** + * Drop collection. + * + * @throws EJDBException + */ + public void drop() throws EJDBException { this.drop(false); } - public native void drop(boolean prune); + /** + * Drop collection. + * + * @param prune If true the collection data will erased from disk. + * @throws EJDBException + */ + public native void drop(boolean prune) throws EJDBException; - public native void sync(); + /** + * Synchronize entire collection with storage. + * + * @throws EJDBException + */ + public native void sync() throws EJDBException; - public native void updateMeta(); + /** + * Update collection metainformation from storage + * + * @throws EJDBException + */ + public native void updateMeta() throws EJDBException; - public native BSONObject load(ObjectId oid); + /** + * Loads BSON object identified by OID from the collection. + * + * @param oid Object identifier (OID) + * @throws EJDBException + */ + public native BSONObject load(ObjectId oid) throws EJDBException; - public native ObjectId save(BSONObject object); + /** + * Save/update specified BSON object in the collection. + *

+ * Object has unique identifier (OID) placed in the `_id` property. + * If a saved object does not have `_id` it will be autogenerated. + * To identify and update object it should contains `_id` property. + *

+ * NOTE: Field names of passed BSON objects may not contain `$` and `.` characters, + * error condition will be fired in this case. + * + * @param object BSON object to save + * @return OID of saved object + * @throws EJDBException + */ + public native ObjectId save(BSONObject object) throws EJDBException; - public List save(List objects) { + /** + * Save/update specified BSON objects in the collection. + *

+ * Each persistent object has unique identifier (OID) placed in the `_id` property. + * If a saved object does not have `_id` it will be autogenerated. + * To identify and update object it should contains `_id` property. + *

+ * NOTE: Field names of passed BSON objects may not contain `$` and `.` characters, + * error condition will be fired in this case. + * + * @param objects array of JSON objects to save + * @return OIDs of saved objects + * @throws EJDBException + */ + public List save(List objects) throws EJDBException { List result = new ArrayList(objects.size()); for (BSONObject object : objects) { @@ -113,44 +197,93 @@ public class EJDBCollection { return result; } - public native void remove(ObjectId oid); + /** + * Remove BSON object from collection by OID + * + * @param oid OID of removed object + * @throws EJDBException + */ + public native void remove(ObjectId oid) throws EJDBException; - public native void setIndex(String path, int flags); + /** + * @param path BSON field path + * @param flags + * @throws EJDBException + */ + public native void setIndex(String path, int flags) throws EJDBException; + /** + * @see EJDBCollection#createQuery(org.bson.BSONObject, org.bson.BSONObject[], org.bson.BSONObject) + */ public EJDBQuery createQuery(BSONObject query) { return new EJDBQuery(this, query, null, null); } + /** + * @see EJDBCollection#createQuery(org.bson.BSONObject, org.bson.BSONObject[], org.bson.BSONObject) + */ public EJDBQuery createQuery(BSONObject query, BSONObject[] qors) { return new EJDBQuery(this, query, qors, null); } + /** + * @see EJDBCollection#createQuery(org.bson.BSONObject, org.bson.BSONObject[], org.bson.BSONObject) + */ public EJDBQuery createQuery(BSONObject query, BSONObject hints) { return new EJDBQuery(this, query, null, hints); } + /** + * Create EJDB query + *

+ * EJDB queries inspired by MongoDB (mongodb.org) and follows same philosophy. + * + * @param query Main BSON query object + * @param qors Array of additional OR query objects (joined with OR predicate). + * @param hints BSON object with query hints. + * @return + */ public EJDBQuery createQuery(BSONObject query, BSONObject[] qors, BSONObject hints) { return new EJDBQuery(this, query, qors, hints); } - public void beginTransaction() { + /** + * Begin collection transaction. + * + * @throws EJDBException + */ + public void beginTransaction() throws EJDBException { this.txControl(JBTXBEGIN); } - public void commitTransaction() { + /** + * Commit collection transaction. + * + * @throws EJDBException + */ + public void commitTransaction() throws EJDBException { this.txControl(JBTXCOMMIT); } - public void rollbakcTransaction() { + /** + * Abort collection transaction. + * + * @throws EJDBException + */ + public void rollbackTransaction() throws EJDBException { this.txControl(JBTXROLLBACK); } - public boolean isTransactionActive() { + /** + * Get collection transaction status. + * + * @throws EJDBException + */ + public boolean isTransactionActive() throws EJDBException { return this.txControl(JBTXSTATUS); } - protected native boolean txControl(int mode); - + protected native boolean txControl(int mode) throws EJDBException; @Override public String toString() { @@ -163,6 +296,9 @@ public class EJDBCollection { return sb.toString(); } + /** + * Collection meta information (and creation options) + */ public static class Options { private long buckets; private boolean compressed; @@ -173,6 +309,12 @@ public class EJDBCollection { public Options() { } + /** + * @param compressed If true collection records will be compressed with DEFLATE compression. Default: false. + * @param large Specifies that the size of the database can be larger than 2GB. Default: false + * @param records Estimated number of records in this collection. Default: 65535. + * @param cachedRecords Max number of cached records in shared memory segment. Default: 0 + */ public Options(boolean compressed, boolean large, long records, int cachedRecords) { this.compressed = compressed; this.large = large; @@ -209,12 +351,18 @@ public class EJDBCollection { } } + /** + * Index types + */ public static enum IndexType { Lexical, Numeric, Token; } + /** + * Index meta information + */ public static class Index { private String name; private String field; diff --git a/jejdb/src/java/org/ejdb/driver/EJDBQuery.java b/jejdb/src/java/org/ejdb/driver/EJDBQuery.java index e12ba18..4900654 100644 --- a/jejdb/src/java/org/ejdb/driver/EJDBQuery.java +++ b/jejdb/src/java/org/ejdb/driver/EJDBQuery.java @@ -15,9 +15,8 @@ import java.util.Map; */ public class EJDBQuery { - // Query search mode flags - protected static final int JBQRYCOUNT = 1; /*< Query only count(*) */ - + /* Query only count(*) */ + protected static final int JBQRYCOUNT = 1; private EJDBCollection coll; private BSONObject query; @@ -35,16 +34,26 @@ public class EJDBQuery { this.hints = hints; } + /** + * Return main query object + * + * @return + */ public BSONObject getQueryObject() { return query; } - // TODO - public EJDBResultSet find() { + /** + * Execute query + */ + public EJDBResultSet find() throws EJDBException { return this.execute(hints, 0).getResultSet(); } - public BSONObject findOne() { + /** + * Same as {@link org.ejdb.driver.EJDBQuery#find()} but retrieves only one matching JSON object. + */ + public BSONObject findOne() throws EJDBException { Map hintsMap = hints != null ? hints.toMap() : new HashMap(); hintsMap.put("$max", 1); @@ -55,22 +64,30 @@ public class EJDBQuery { return result; } - public int update() { + /** + * Executes update query + * + * @return count of affected objects + */ + public int update() throws EJDBException { return this.execute(hints, JBQRYCOUNT).getCount(); } - public int count() { + /** + * Convenient count(*) operation + */ + public int count() throws EJDBException { return this.execute(hints, JBQRYCOUNT).getCount(); } - protected QResult execute(BSONObject hints, int flags) { + protected QResult execute(BSONObject hints, int flags) throws EJDBException { BSONObject[] qors = new BSONObject[this.qors.size()]; this.qors.toArray(qors); return this.execute(query, qors, hints, flags); } - protected native QResult execute(BSONObject query, BSONObject[] qors, BSONObject hints, int flags); + protected native QResult execute(BSONObject query, BSONObject[] qors, BSONObject hints, int flags) throws EJDBException; private static class QResult { private int count; diff --git a/jejdb/src/java/org/ejdb/driver/EJDBResultSet.java b/jejdb/src/java/org/ejdb/driver/EJDBResultSet.java index 1ec68ed..624d642 100644 --- a/jejdb/src/java/org/ejdb/driver/EJDBResultSet.java +++ b/jejdb/src/java/org/ejdb/driver/EJDBResultSet.java @@ -20,7 +20,14 @@ public class EJDBResultSet implements Iterable, Iterator this.position = 0; } - public native BSONObject get(int position); + /** + * Returns object by position + */ + public native BSONObject get(int position) throws EJDBException; + + /** + * Returns objects count in result set + */ public native int length(); public Iterator iterator() { @@ -36,14 +43,22 @@ public class EJDBResultSet implements Iterable, Iterator throw new NoSuchElementException(); } - return get(position++); + try { + return get(position++); + } catch (EJDBException e) { + // TODO: ? + throw new RuntimeException(e); + } } public void remove() { throw new UnsupportedOperationException(); } - public native void close(); + /** + * Close result set + */ + public native void close() throws EJDBException; @Override protected void finalize() throws Throwable { -- 2.7.4