jclass clazz = (*env)->GetObjectClass(env, obj);
jfieldID dbpID = (*env)->GetFieldID(env, clazz, "dbPointer", "J");
(*env)->SetLongField(env, obj, dbpID, (jlong)db);
-
- jfieldID pathID = (*env)->GetFieldID(env, clazz, "path", "Ljava/lang/String;");
- (*env)->SetObjectField(env, obj, pathID, db ? (*env)->NewStringUTF(env, db->metadb->hdb->path) : NULL);
};
static EJDB *get_ejdb_from_object(JNIEnv *env, jobject obj) {
jclass clazz = (*env)->GetObjectClass(env, obj);
jfieldID recordsFID = (*env)->GetFieldID(env, clazz, "records", "J");
- jfieldID cachedrecordsFID = (*env)->GetFieldID(env, clazz, "cachedrecords", "I");
+ jfieldID cachedrecordsFID = (*env)->GetFieldID(env, clazz, "cachedRecords", "I");
jfieldID largeFID = (*env)->GetFieldID(env, clazz, "large", "Z");
jfieldID compressedFID = (*env)->GetFieldID(env, clazz, "compressed", "Z");
(*env)->SetLongField(env, obj, rspID, (jlong)rs);
};
+static void update_coll_meta(JNIEnv *env, jobject obj, EJCOLL *coll) {
+ jclass clazz = (*env)->GetObjectClass(env, obj);
+ jfieldID existsID = (*env)->GetFieldID(env, clazz, "exists", "Z");
+ (*env)->SetBooleanField(env, obj, existsID, coll ? JNI_TRUE : JNI_FALSE);
+
+ jclass optionsClazz = (*env)->FindClass(env, "org/ejdb/driver/EJDBCollection$Options");
+ jfieldID optionsID = (*env)->GetFieldID(env, clazz, "options", "Lorg/ejdb/driver/EJDBCollection$Options;");
+ jobject jopts = (*env)->GetObjectField(env, obj, optionsID);
+
+ if (!jopts) {
+ jmethodID initOptions = (*env)->GetMethodID(env, optionsClazz, "<init>", "()V");
+ jopts = (*env)->NewObject(env, optionsClazz, initOptions);
+ (*env)->SetObjectField(env, obj, optionsID, jopts);
+ }
+
+ jfieldID bucketsID = (*env)->GetFieldID(env, optionsClazz, "buckets", "J");
+ jfieldID cachedID = (*env)->GetFieldID(env, optionsClazz, "cachedRecords", "I");
+ jfieldID largeID = (*env)->GetFieldID(env, optionsClazz, "large", "Z");
+ jfieldID compressedID = (*env)->GetFieldID(env, optionsClazz, "compressed", "Z");
+
+ (*env)->SetLongField(env, jopts, bucketsID, coll->tdb->hdb->bnum);
+ (*env)->SetIntField(env, jopts, cachedID, coll->tdb->hdb->rcnum);
+ (*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, "<init>", "()V");
+ jfieldID indexesID = (*env)->GetFieldID(env, clazz, "indexes", "Ljava/util/Collection;");
+
+ jclass arrayListClazz = (*env)->FindClass(env, "Ljava/util/ArrayList;");
+ jmethodID initArrayList = (*env)->GetMethodID(env, arrayListClazz, "<init>", "(I)V");
+ jmethodID addToList = (*env)->GetMethodID(env, arrayListClazz, "add", "(Ljava/lang/Object;)Z");
+
+ jfieldID fieldID = (*env)->GetFieldID(env, indexClazz, "field", "Ljava/lang/String;");
+ jfieldID nameID = (*env)->GetFieldID(env, indexClazz, "name", "Ljava/lang/String;");
+ jfieldID fileID = (*env)->GetFieldID(env, indexClazz, "file", "Ljava/lang/String;");
+ jfieldID typeID = (*env)->GetFieldID(env, indexClazz, "type", "Lorg/ejdb/driver/EJDBCollection$IndexType;");
+ jfieldID recordsID = (*env)->GetFieldID(env, indexClazz, "records", "I");
+
+ jobject indexes = (*env)->NewObject(env, arrayListClazz, initArrayList, coll->tdb->inum);
+
+ for (int j = 0; j < coll->tdb->inum; ++j) {
+ TDBIDX *idx = (coll->tdb->idxs + j);
+ assert(idx);
+ if (idx->type != TDBITLEXICAL && idx->type != TDBITDECIMAL && idx->type != TDBITTOKEN) {
+ continue;
+ }
+
+ jobject index = (*env)->NewObject(env, indexClazz, initIndex);
+
+ (*env)->SetObjectField(env, index, fieldID, (*env)->NewStringUTF(env, idx->name+1));
+ (*env)->SetObjectField(env, index, nameID, (*env)->NewStringUTF(env, idx->name));
+
+ jfieldID indexTypeID = NULL;
+ switch (idx->type) {
+ case TDBITLEXICAL:
+ indexTypeID = (*env)->GetStaticFieldID(env, indexTypeClazz, "Lexical", "Lorg/ejdb/driver/EJDBCollection$IndexType;");
+ break;
+ case TDBITDECIMAL:
+ indexTypeID = (*env)->GetStaticFieldID(env, indexTypeClazz, "Numeric", "Lorg/ejdb/driver/EJDBCollection$IndexType;");
+ break;
+ case TDBITTOKEN:
+ indexTypeID = (*env)->GetStaticFieldID(env, indexTypeClazz, "Token", "Lorg/ejdb/driver/EJDBCollection$IndexType;");
+ break;
+ }
+ if (indexTypeID) {
+ (*env)->SetObjectField(env, index, typeID, (*env)->GetStaticObjectField(env, indexTypeClazz, indexTypeID));
+ }
+
+ TCBDB *idb = (TCBDB*) idx->db;
+ if (idb) {
+ (*env)->SetIntField(env, index, recordsID, idb->rnum);
+ (*env)->SetObjectField(env, index, fileID, (*env)->NewStringUTF(env, idb->hdb->path));
+ }
+
+ (*env)->CallBooleanMethod(env, indexes, addToList, index);
+ }
+
+ (*env)->SetObjectField(env, obj, indexesID, indexes);
+};
+
/*
* Class: org_ejdb_driver_EJDB
* Method: open
}
set_ejdb_to_object(env, obj, db);
+ Java_org_ejdb_driver_EJDB_updateMeta(env, obj);
return;
};
}
set_ejdb_to_object(env, obj, NULL);
+ Java_org_ejdb_driver_EJDB_updateMeta(env, obj);
};
/*
};
/*
+ * Class: org_ejdb_driver_EJDB
+ * Method: updateMeta
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_ejdb_driver_EJDB_updateMeta (JNIEnv *env, jobject obj) {
+ jclass clazz = (*env)->GetObjectClass(env, obj);
+ EJDB *db = get_ejdb_from_object(env, obj);
+
+ jfieldID pathID = (*env)->GetFieldID(env, clazz, "path", "Ljava/lang/String;");
+ (*env)->SetObjectField(env, obj, pathID, db ? (*env)->NewStringUTF(env, db->metadb->hdb->path) : NULL);
+
+ jfieldID collectionMapID = (*env)->GetFieldID(env, clazz, "collections", "Ljava/util/Map;");
+ jobject collmapold = (*env)->GetObjectField(env, obj, collectionMapID);
+ jclass mapClazz = (*env)->GetObjectClass(env, collmapold);
+ jmethodID getFromMap = (*env)->GetMethodID(env, mapClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
+
+ jclass hashMapClazz = (*env)->FindClass(env, "java/util/HashMap");
+ jmethodID initHashMap = (*env)->GetMethodID(env, hashMapClazz, "<init>", "(I)V");
+ jmethodID putIntoMap = (*env)->GetMethodID(env, hashMapClazz, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ jobject collmapnew = (*env)->NewObject(env, hashMapClazz, initHashMap, !db ? 0 : db->cdbsnum);
+
+ if (!db) {
+ (*env)->SetObjectField(env, obj, collectionMapID, collmapnew);
+ return;
+ }
+
+ TCLIST *colls = ejdbgetcolls(db);
+ if (!colls) {
+ set_ejdb_error(env, db);
+ return;
+ }
+
+ jclass collectionClazz = (*env)->FindClass(env, "org/ejdb/driver/EJDBCollection");
+ jmethodID initCollection = (*env)->GetMethodID(env, collectionClazz, "<init>", "(Lorg/ejdb/driver/EJDB;Ljava/lang/String;)V");
+
+ for (int i = 0; i < TCLISTNUM(colls); ++i) {
+ EJCOLL *coll = (EJCOLL*) TCLISTVALPTR(colls, i);
+
+ jstring cname = (*env)->NewStringUTF(env, coll->cname);//, coll->cnamesz);
+
+ jobject cobj = (*env)->CallObjectMethod(env, collmapold, getFromMap, cname);
+ if (!cobj) {
+ cobj = (*env)->NewObject(env, collectionClazz, initCollection, obj, cname);
+ }
+
+ update_coll_meta(env, cobj, coll);
+
+ (*env)->CallObjectMethod(env, collmapnew, putIntoMap, cname, cobj);
+ }
+
+ (*env)->SetObjectField(env, obj, collectionMapID, collmapnew);
+};
+
+/*
* Class: org_ejdb_driver_EJDBCollection
* Method: ensureExists
* Signature: (Lorg/ejdb/driver/EJDBCollection$Options;)V
}
};
-
/*
* Class: org_ejdb_driver_EJDBCollection
* Method: drop
/*
* Class: org_ejdb_driver_EJDBCollection
+ * Method: updateMeta
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_ejdb_driver_EJDBCollection_updateMeta (JNIEnv *env, jobject obj) {
+ EJDB *db = get_ejdb_from_object(env, obj);
+ if (!ejdbisopen(db)) {
+ set_error(env, 0, "EJDB not opened");
+ return;
+ }
+
+ jstring colname = get_coll_name(env, obj);
+
+ const char *cname = (*env)->GetStringUTFChars(env, colname, NULL);
+ EJCOLL * coll = ejdbgetcoll(db, cname);
+ (*env)->ReleaseStringUTFChars(env, colname, cname);
+
+ update_coll_meta(env, obj, coll);
+};
+
+/*
+ * Class: org_ejdb_driver_EJDBCollection
* Method: load
* Signature: (Lorg/bson/types/ObjectId;)Lorg/bson/BSONObject;
*/
import org.bson.types.ObjectId;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
/**
*/
public class EJDBCollection {
- // Index modes, index types.
- public final static int JBIDXDROP = 1 << 0; /**< Drop index. */
- public final static int JBIDXDROPALL = 1 << 1; /**< Drop index for all types. */
- public final static int JBIDXOP = 1 << 2; /**< Optimize index. */
- public final static int JBIDXREBLD = 1 << 3; /**< Rebuild index. */
- public final static int JBIDXNUM = 1 << 4; /**< Number index. */
- public final static int JBIDXSTR = 1 << 5; /**< String index.*/
- public final static int JBIDXARR = 1 << 6; /**< Array token index. */
- public final static int JBIDXISTR = 1 << 7; /**< Case insensitive string index */
-
+ /**
+ * Drop index.
+ */
+ public final static int JBIDXDROP = 1 << 0;
+ /**
+ * Drop index for all types.
+ */
+ public final static int JBIDXDROPALL = 1 << 1;
+ /**
+ * Optimize index.
+ */
+ public final static int JBIDXOP = 1 << 2;
+ /**
+ * Rebuild index.
+ */
+ public final static int JBIDXREBLD = 1 << 3;
+ /**
+ * Number index.
+ */
+ public final static int JBIDXNUM = 1 << 4;
+ /**
+ * String index.
+ */
+ public final static int JBIDXSTR = 1 << 5;
+ /**
+ * Array token index.
+ */
+ public final static int JBIDXARR = 1 << 6;
+ /**
+ * Case insensitive string index
+ */
+ public final static int JBIDXISTR = 1 << 7;
+
+ // transaction control options (inner use only)
protected final static int JBTXBEGIN = 1 << 0;
protected final static int JBTXCOMMIT = 1 << 1;
protected final static int JBTXROLLBACK = 1 << 2;
private EJDB db;
private String cname;
+ private boolean exists;
+ private Options options;
+ private Collection<Index> indexes;
EJDBCollection(EJDB db, String cname) {
this.db = db;
this.cname = cname;
}
- protected native boolean txControl(int mode);
+ public EJDB getDB() {
+ return db;
+ }
+
+ public String getName() {
+ return cname;
+ }
+
+ public boolean isExists() {
+ return exists;
+ }
+
+ public Options getOptions() {
+ return options;
+ }
+
+ public Collection<Index> getIndexes() {
+ return indexes;
+ }
public void ensureExists() {
this.ensureExists(null);
public native void sync();
+ public native void updateMeta();
+
public native BSONObject load(ObjectId oid);
public native ObjectId save(BSONObject object);
return this.txControl(JBTXSTATUS);
}
+ protected native boolean txControl(int mode);
+
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("EJDBCollection");
+ sb.append("{cname='").append(cname).append('\'');
+ sb.append(", options=").append(options);
+ sb.append(", indexes=").append(indexes);
+ sb.append('}');
+ return sb.toString();
+ }
+
public static class Options {
+ private long buckets;
private boolean compressed;
private boolean large;
private long records;
- private int cachedrecords;
+ private int cachedRecords;
public Options() {
}
- public Options(boolean compressed, boolean large, long records, int cachedrecords) {
+ public Options(boolean compressed, boolean large, long records, int cachedRecords) {
this.compressed = compressed;
this.large = large;
this.records = records;
- this.cachedrecords = cachedrecords;
+ this.cachedRecords = cachedRecords;
}
- public boolean isCompressed() {
- return compressed;
+ public long getBuckets() {
+ return buckets;
}
- public void setCompressed(boolean compressed) {
- this.compressed = compressed;
+ public boolean isCompressed() {
+ return compressed;
}
public boolean isLarge() {
return large;
}
- public void setLarge(boolean large) {
- this.large = large;
+ public int getCachedRecords() {
+ return cachedRecords;
}
- public long getRecords() {
- return records;
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Options");
+ sb.append("{buckets=").append(buckets);
+ sb.append(", compressed=").append(compressed);
+ sb.append(", large=").append(large);
+ sb.append(", cachedRecords=").append(cachedRecords);
+ sb.append('}');
+ return sb.toString();
}
+ }
- public void setRecords(long records) {
- this.records = records;
+ public static enum IndexType {
+ Lexical,
+ Numeric,
+ Token;
+ }
+
+ public static class Index {
+ private String name;
+ private String field;
+ private IndexType type;
+ private String file;
+ private int records;
+
+ public String getName() {
+ return name;
}
- public int getCachedrecords() {
- return cachedrecords;
+ public String getField() {
+ return field;
+ }
+
+ public IndexType getType() {
+ return type;
+ }
+
+ public String getFile() {
+ return file;
+ }
+
+ public int getRecords() {
+ return records;
}
- public void setCachedrecords(int cachedrecords) {
- this.cachedrecords = cachedrecords;
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Index");
+ sb.append("{name='").append(name).append('\'');
+ sb.append(", field='").append(field).append('\'');
+ sb.append(", type=").append(type);
+ if (file != null) {
+ sb.append(", file='").append(file).append('\'');
+ }
+ sb.append(", records=").append(records);
+ sb.append('}');
+ return sb.toString();
}
}
}