com.sequoiadb.base.DBCollection Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sequoiadb-driver Show documentation
Show all versions of sequoiadb-driver Show documentation
Java client driver for SequoiaDB
/*
* Copyright 2018 SequoiaDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sequoiadb.base;
import com.sequoiadb.exception.BaseException;
import com.sequoiadb.exception.SDBError;
import com.sequoiadb.message.request.*;
import com.sequoiadb.message.response.SdbReply;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.types.BasicBSONList;
import org.bson.types.ObjectId;
import org.bson.util.JSON;
import java.util.*;
/**
* Collection of SequoiaDB.
*/
public class DBCollection {
private String name;
private Sequoiadb sequoiadb;
private CollectionSpace collectionSpace;
private String csName;
private String collectionFullName;
private Set mainKeys;
private boolean ensureOID;
/** The flag represent whether insert continue(no errors were reported)
* when hitting index key duplicate error
*/
public static final int FLG_INSERT_CONTONDUP = 0x00000001;
/** The flag represent whether insert return the "_id" field of the record for user */
public static final int FLG_INSERT_RETURN_OID = 0x00000002;
/**
* The flag represent whether insert becomes update when hitting index key duplicate error.
*/
public static final int FLG_INSERT_REPLACEONDUP = 0x00000004;
/**
* The sharding key in update rule is not filtered,
* when executing update or upsert.
*/
public static final int FLG_UPDATE_KEEP_SHARDINGKEY = 0x00008000;
/**
* Get the name of current collection.
*
* @return The collection name
*/
public String getName() {
return name;
}
/**
* Get the full name of specified collection in current collection space.
*
* @return The full name of specified collection
*/
public String getFullName() {
return collectionFullName;
}
/**
* Get the full name of specified collection in current collection space.
*
* @return The full name of specified collection.
*/
public String getCSName() {
return csName;
}
/**
* Get the Sequoiadb instance of current collection.
*
* @return Sequoiadb instance
*/
public Sequoiadb getSequoiadb() {
return sequoiadb;
}
/**
* Get the CollectionSpace instance of current collection.
*
* @return CollectionSpace instance
*/
public CollectionSpace getCollectionSpace() {
return collectionSpace;
}
/**
* Set the main keys used in save(). if no main keys are set, use the
* default main key "_id".
* Every time invokes this method, it will remove the main keys set in the last time.
*
* @param keys the main keys specified by user. the main key should exist in the
* object
* @throws BaseException when keys is null
*/
public void setMainKeys(String[] keys) throws BaseException {
if (keys == null)
throw new BaseException(SDBError.SDB_INVALIDARG, "keys is null");
// remove the main keys set in the last time
mainKeys.clear();
// add the new main keys
if (keys.length == 0) {
return;
}
for (String k : keys) {
mainKeys.add(k);
}
}
/**
* @param sequoiadb Sequoiadb object
* @param cs CollectionSpace object
* @param name Collection name
*/
DBCollection(Sequoiadb sequoiadb, CollectionSpace cs, String name) {
this.name = name;
this.sequoiadb = sequoiadb;
this.collectionSpace = cs;
this.csName = cs.getName();
this.collectionFullName = csName + "." + name;
this.mainKeys = new HashSet();
this.ensureOID = true;
}
/**
* Insert a document into current collection.
*
* @param insertor The bson object to be inserted, can't be null.
* @param flags The flag to control the behavior of inserting. The
* value of flags default to be 0, and it can choose
* the follow values:
*
* - 0: default value.
* - FLG_INSERT_CONTONDUP: if the record hit index key duplicate error,
* database will skip them and go on inserting.
* - FLG_INSERT_RETURN_OID: return the value of "_id" field in the record.
* - FLG_INSERT_REPLACEONDUP: if the record hit index key duplicate
* error, database will replace the existing
* record by the inserting new record.
*
* @return The result of inserting, can be the follow values:
*
* - null: when there is no result to return.
* - bson which contains the "_id" field: when flag "FLG_INSERT_RETURN_OID" is set, return the
* value of "_id" field of the inserted record.
* e.g.: { "_id": { "$oid": "5c456e8eb17ab30cfbf1d5d1" } }
*
* @throws BaseException If error happens.
*/
public BSONObject insert(BSONObject insertor, int flags) throws BaseException {
BSONObject result = null;
if (insertor == null) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
// send to engine
InsertRequest request = new InsertRequest(collectionFullName, insertor, flags);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, insertor);
sequoiadb.upsertCache(collectionFullName);
// return result
if ((flags & FLG_INSERT_RETURN_OID) != 0)
{
Object oid = request.getOIDValue();
if (oid != null) {
result = new BasicBSONObject();
result.put(SdbConstants.OID, oid);
}
}
return result;
}
/**
* Insert a document into current collection, if the document
* does not contain field "_id", it will be added.
*
* @param insertor The insertor.
* @return the value of the filed "_id"
* @throws BaseException If error happens.
*/
public Object insert(BSONObject insertor) throws BaseException {
BSONObject result = insert(insertor, FLG_INSERT_RETURN_OID);
return result.get(SdbConstants.OID);
}
/**
* Insert a document into current collection, if the document
* does not contain field "_id", it will be added.
*
* @param insertor The string of insertor
* @return the value of the filed "_id"
* @throws BaseException If error happens.
*/
public Object insert(String insertor) throws BaseException {
BSONObject in = null;
if (insertor != null) {
in = (BSONObject) JSON.parse(insertor);
}
return insert(in);
}
/**
* Insert a bulk of bson objects into current collection.
*
* @param insertor The Bson object of insertor list, can't be null
* @param flags The flag to control the behavior of inserting. The
* value of flags default to be 0, and it can choose
* the follow values:
*
* - 0: default value.
* - FLG_INSERT_CONTONDUP: if the record hit index key duplicate error,
* database will skip them and go on inserting.
* - FLG_INSERT_RETURN_OID: return the value of "_id" field in the record.
* When set this flag, ensureOID() will be set to true.
* - FLG_INSERT_REPLACEONDUP: if the record hit index key duplicate
* error, database will replace the existing
* record by the inserting new record and them
* go on inserting.
*
* @return The result of inserting, can be the follow values:
*
* - null: when there is no result to return.
* - bson which contains the "_id" field:
* when flag "FLG_INSERT_RETURN_OID" is set, return all the
* values of "_id" field in a bson array.
* e.g.: { "_id": [ { "$oid": "5c456e8eb17ab30cfbf1d5d1" },
* { "$oid": "5c456e8eb17ab30cfbf1d5d2" } ] }
*
* @throws BaseException If error happens.
* @since 3.0.2
*/
public BSONObject insertRecords(List insertor, int flags) throws BaseException {
BSONObject result = null;
if (insertor == null || insertor.size() == 0) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
// try to ensure oid
if ((flags & FLG_INSERT_RETURN_OID) != 0) {
if (!isOIDEnsured()) {
ensureOID(true);
}
}
// build and send message
InsertRequest request = new InsertRequest(collectionFullName, insertor, flags, ensureOID);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response);
sequoiadb.upsertCache(collectionFullName);
// return result
if ((flags & FLG_INSERT_RETURN_OID) != 0)
{
Object oid = request.getOIDValue();
if (oid != null) {
result = new BasicBSONObject();
result.put(SdbConstants.OID, oid);
}
}
return result;
}
/**
* Insert a bulk of bson objects into current collection.
*
* @param insertor The Bson object of insertor list, can't be null
* @param flags The flag to control the behavior of inserting. The
* value of flags default to be 0, and it can choose
* the follow values:
*
* - 0: default value
* - FLG_INSERT_CONTONDUP: if the record hit index key duplicate error,
* database will skip them and go on inserting.
* - FLG_INSERT_REPLACEONDUP: if the record hit index key duplicate
* error, database will replace the existing
* record by the inserting new record and them
* go on inserting.
*
* @throws BaseException If error happens.
* @since 3.0.2
*/
public void insert(List insertor, int flags) throws BaseException {
if (flags != 0) {
flags = DBQuery.eraseSingleFlag(flags, FLG_INSERT_RETURN_OID);
}
insertRecords(insertor, flags);
}
/**
* Insert a bulk of bson objects into current collection.
*
* @param insertor The Bson object of insertor list, can't be null.
* insert will interrupt when Duplicate key exist.
* @throws BaseException If error happens.
* @since 2.9
*/
public void insert(List insertor) throws BaseException {
insert(insertor, 0);
}
/**
* Insert an object into current collection.
* When flag is set to 0, it won't work to update the ShardingKey field, but the other fields take effect.
*
* @param type The object of insertor, can't be null
* @param ignoreNullValue true:if type's inner value is null, it will not save to collection;
* @param flag the update flag, default to be 0. Please see the definition
* of follow flags for more detail.
*
* - DBCollection.FLG_UPDATE_KEEP_SHARDINGKEY
*
* @throws BaseException 1.when the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 2.when offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY"
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(T type, Boolean ignoreNullValue,
int flag) throws BaseException {
// transform java object to bson object
BSONObject obj;
try {
obj = BasicBSONObject.typeToBson(type, ignoreNullValue);
} catch (Exception e) {
throw new BaseException(SDBError.SDB_INVALIDARG, type.toString(), e);
}
BSONObject matcher = new BasicBSONObject();
BSONObject modifer = new BasicBSONObject();
// if user don't specify main keys, use default one "_id"
if (mainKeys.isEmpty()) {
Object id = obj.get(SdbConstants.OID);
if (id == null || (id instanceof ObjectId && ((ObjectId) id).isNew())) {
if (id != null && id instanceof ObjectId)
((ObjectId) id).notNew();
insert(obj);
} else {
// build condtion
matcher.put(SdbConstants.OID, id);
// build rule
modifer.put("$set", obj);
upsert(matcher, modifer, null, null, flag);
}
} else { // if user specify main keys, use these main keys
Iterator it = mainKeys.iterator();
// build condition
while (it.hasNext()) {
String key = it.next();
if (obj.containsField(key))
matcher.put(key, obj.get(key));
}
// build rule
if (!matcher.isEmpty()) {
modifer.put("$set", obj);
upsert(matcher, modifer, null, null, flag);
} else {
insert(obj);
}
}
}
/**
* Insert an object into current collection
* when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
* field update is take effect.
*
* @param type The object of insertor, can't be null
* @param ignoreNullValue true:if type's inner value is null, it will not save to collection;
* false:if type's inner value is null, it will save to collection too.
* @throws BaseException 1.when the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 2.when offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY"
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(T type, Boolean ignoreNullValue) throws BaseException {
save(type, ignoreNullValue, 0);
}
/**
* Insert an object into current collection.
* when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
* field update is take effect.
*
* @param type The object of insertor, can't be null
* @throws BaseException 1.when the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 2.when offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY"
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(T type) throws BaseException {
save(type, false);
}
/**
* Insert an object into current collection.
* When flag is set to 0, it won't work to update the ShardingKey field, but the other fields take effect.
*
* @param type The List instance of insertor, can't be null or empty
* @param ignoreNullValue true:if type's inner value is null, it will not save to collection;
* @param flag the update flag, default to be 0. Please see the definition
* of follow flags for more detail.
*
* - DBCollection.FLG_UPDATE_KEEP_SHARDINGKEY
*
* @throws BaseException 1.while the input argument is null or the List instance is empty
* 2.while the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 3.while offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY" when the "_id" field you
* want to update to had been existing in database
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(List type, Boolean ignoreNullValue,
int flag) throws BaseException {
if (type == null || type.size() == 0)
throw new BaseException(SDBError.SDB_INVALIDARG, "type is empty or null");
// transform java object to bson object
List objs = new ArrayList();
try {
Iterator it = type.iterator();
while (it != null && it.hasNext()) {
objs.add(BasicBSONObject.typeToBson(it.next(), ignoreNullValue));
}
} catch (Exception e) {
throw new BaseException(SDBError.SDB_INVALIDARG, type.toString(), e);
}
BSONObject matcher = new BasicBSONObject();
BSONObject modifer = new BasicBSONObject();
BSONObject obj = null;
Iterator ite = objs.iterator();
// if user don't specify main keys, use default one "_id"
if (mainKeys.isEmpty()) {
while (ite != null && ite.hasNext()) {
obj = ite.next();
Object id = obj.get(SdbConstants.OID);
if (id == null || (id instanceof ObjectId && ((ObjectId) id).isNew())) {
if (id != null && id instanceof ObjectId)
((ObjectId) id).notNew();
insert(obj);
} else {
// build condtion
matcher.put(SdbConstants.OID, id);
// build rule
modifer.put("$set", obj);
upsert(matcher, modifer, null, null, flag);
}
}
} else { // if user specify main keys, use these main keys
while (ite != null && ite.hasNext()) {
obj = ite.next();
Iterator i = mainKeys.iterator();
// build condition
while (i.hasNext()) {
String key = i.next();
if (obj.containsField(key))
matcher.put(key, obj.get(key));
}
if (!matcher.isEmpty()) {
// build rule
modifer.put("$set", obj);
upsert(matcher, modifer, null, null, flag);
} else {
insert(obj);
}
}
}
}
/**
* Insert an object into current collection.
* when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
* field update is take effect.
*
* @param type The List instance of insertor, can't be null or empty
* @param ignoreNullValue true:if type's inner value is null, it will not save to collection;
* false:if type's inner value is null, it will save to collection too.
* @throws BaseException 1.while the input argument is null or the List instance is empty
* 2.while the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 3.while offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY" when the "_id" field you
* want to update to had been existing in database
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(List type, Boolean ignoreNullValue) throws BaseException {
save(type, ignoreNullValue, 0);
}
/**
* Insert an object into current collection.
* when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
* field update is take effect.
*
* @param type The List instance of insertor, can't be null or empty
* @throws BaseException 1.while the input argument is null or the List instance is empty
* 2.while the type is not support, throw BaseException with the type "SDB_INVALIDARG"
* 3.while offer main keys by setMainKeys(), and try to update "_id" field,
* it may get a BaseException with the type of "SDB_IXM_DUP_KEY" when the "_id" field you
* want to update to had been existing in database
* @see com.sequoiadb.base.DBCollection#setMainKeys(String[])
*/
public /*! @cond x*/ /*! @endcond */ void save(List type) throws BaseException {
save(type, false);
}
/**
* Set whether ensure OID of record when bulk insert records to SequoiaDB.
*
* @param flag whether ensure OID of record
*/
public void ensureOID(boolean flag) {
ensureOID = flag;
}
/**
* @return True if ensure OID of record when bulk insert records to SequoiaDB and false if not.
*/
public boolean isOIDEnsured() {
return ensureOID;
}
/**
* Insert a bulk of bson objects into current collection.
*
* @param insertor The Bson object of insertor list, can't be null
* @param flags The flag to control the behavior of inserting. The
* value of flags default to be 0, and it can choose
* the follow values:
*
* - 0: default value
* - FLG_INSERT_CONTONDUP: if the record hit index key duplicate error,
* database will skip them and go on inserting.
* - FLG_INSERT_REPLACEONDUP: if the record hit index key duplicate
* error, database will replace the existing
* record by the inserting new record and them
* go on inserting.
*
* @throws BaseException If error happens.
* @deprecated use insert(List insertor, int flags) instead
*/
@Deprecated
public void bulkInsert(List insertor, int flags) throws BaseException {
insert(insertor, flags);
}
/**
* Delete the matching BSONObject of current collection.
*
* @param matcher The matching condition, delete all the documents if null
* @throws BaseException If error happens.
*/
public void delete(BSONObject matcher) throws BaseException {
delete(matcher, null);
}
/**
* Delete the matching of current collection.
*
* @param matcher The matching condition, delete all the documents if null
* @throws BaseException If error happens.
*/
public void delete(String matcher) throws BaseException {
BSONObject ma = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
delete(ma, null);
}
/**
* Delete the matching bson's string of current collection.
*
* @param matcher The matching condition, delete all the documents if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @throws BaseException If error happens.
*/
public void delete(String matcher, String hint) throws BaseException {
BSONObject ma = null;
BSONObject hi = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
if (hint != null) {
hi = (BSONObject) JSON.parse(hint);
}
delete(ma, hi);
}
/**
* Delete the matching BSONObject of current collection.
*
* @param matcher The matching condition, delete all the documents if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @throws BaseException If error happens.
*/
public void delete(BSONObject matcher, BSONObject hint)
throws BaseException {
DeleteRequest request = new DeleteRequest(collectionFullName, matcher, hint);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "matcher = " + matcher + ", hint = " + hint;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Update the document of current collection.
* It won't work to update the ShardingKey field, but the other fields take effect.
*
* @param query DBQuery with matching condition, updating rule and hint
* @throws BaseException If error happens.
*/
public void update(DBQuery query) throws BaseException {
_update(query.getFlag(), query.getMatcher(), query.getModifier(), query.getHint());
}
/**
* Update the BSONObject of current collection.
* It won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents if null
* @param modifier The updating rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @throws BaseException If error happens.
*/
public void update(BSONObject matcher, BSONObject modifier, BSONObject hint)
throws BaseException {
_update(0, matcher, modifier, hint);
}
/**
* Update the BSONObject of current collection.
* When flag is set to 0, it won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents if null
* @param modifier The updating rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param flag the update flag, default to be 0. Please see the definition
* of follow flags for more detail.
*
* - DBCollection.FLG_UPDATE_KEEP_SHARDINGKEY
*
* @throws BaseException If error happens.
*/
public void update(BSONObject matcher, BSONObject modifier, BSONObject hint,
int flag) throws BaseException {
_update(flag, matcher, modifier, hint);
}
/**
* Update the BSONObject of current collection.
* It won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents if null
* @param modifier The updating rule, can't be null or empty
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @throws BaseException If error happens.
*/
public void update(String matcher, String modifier, String hint)
throws BaseException {
BSONObject ma = null;
BSONObject mo = null;
BSONObject hi = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
if (modifier != null) {
mo = (BSONObject) JSON.parse(modifier);
}
if (hint != null) {
hi = (BSONObject) JSON.parse(hint);
}
_update(0, ma, mo, hi);
}
/**
* Update the BSONObject of current collection.
* When flag is set to 0, it won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents if null
* @param modifier The updating rule, can't be null or empty
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param flag the update flag, default to be 0. Please see the definition
* of follow flags for more detail.
*
* - DBCollection.FLG_UPDATE_KEEP_SHARDINGKEY
*
* @throws BaseException If error happens.
*/
public void update(String matcher, String modifier, String hint, int flag)
throws BaseException {
BSONObject ma = null;
BSONObject mo = null;
BSONObject hi = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
if (modifier != null) {
mo = (BSONObject) JSON.parse(modifier);
}
if (hint != null) {
hi = (BSONObject) JSON.parse(hint);
}
_update(flag, ma, mo, hi);
}
/**
* Update the BSONObject of current collection, insert if no matching.
* It won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents
* if null(that's to say, we match all the documents)
* @param modifier The updating rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @throws BaseException If error happens.
*/
public void upsert(BSONObject matcher, BSONObject modifier, BSONObject hint)
throws BaseException {
_update(SdbConstants.FLG_UPDATE_UPSERT, matcher, modifier, hint);
}
/**
* Update the BSONObject of current collection, insert if no matching.
* It won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents
* if null(that's to say, we match all the documents)
* @param modifier The updating rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param setOnInsert When "setOnInsert" is not a null or an empty object,
* it assigns the specified values to the fields when insert.
* @throws BaseException If error happens.
*/
public void upsert(BSONObject matcher, BSONObject modifier, BSONObject hint,
BSONObject setOnInsert) throws BaseException {
upsert(matcher, modifier, hint, setOnInsert, 0);
}
/**
* Update the BSONObject of current collection, insert if no matching.
* When flag is set to 0, it won't work to update the ShardingKey field, but the other fields take effect.
*
* @param matcher The matching condition, update all the documents
* if null(that's to say, we match all the documents)
* @param modifier The updating rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param setOnInsert When "setOnInsert" is not a null or an empty object,
* it assigns the specified values to the fields when insert.
* @param flag the upsert flag, default to be 0. Please see the definition
* of follow flags for more detail.
*
* - DBCollection.FLG_UPDATE_KEEP_SHARDINGKEY
*
* @throws BaseException If error happens.
*/
public void upsert(BSONObject matcher, BSONObject modifier, BSONObject hint,
BSONObject setOnInsert, int flag) throws BaseException {
BSONObject newHint;
if (setOnInsert != null) {
newHint = new BasicBSONObject();
if (hint != null) {
newHint.putAll(hint);
}
newHint.put(SdbConstants.FIELD_NAME_SET_ON_INSERT, setOnInsert);
} else {
newHint = hint;
}
flag |= SdbConstants.FLG_UPDATE_UPSERT;
_update(flag, matcher, modifier, newHint);
}
/**
* Explain query of current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @param flag the query flag, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
* @param options The rules of query explain, the options are as below:
*
* - Run : Whether execute query explain or not, true for executing query explain then get
* the data and time information; false for not executing query explain but get the
* query explain information only. e.g. {Run:true}
*
* @return a DBCursor instance of the result
* @throws BaseException If error happens.
*/
public DBCursor explain(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint, long skipRows, long returnRows,
int flag, BSONObject options) throws BaseException {
flag |= DBQuery.FLG_QUERY_EXPLAIN;
BSONObject innerHint = new BasicBSONObject();
if (null != hint) {
innerHint.put(SdbConstants.FIELD_NAME_HINT, hint);
}
if (null != options) {
innerHint.put(SdbConstants.FIELD_NAME_OPTIONS, options);
}
return _query(matcher, selector, orderBy, innerHint, skipRows,
returnRows, flag);
}
/**
* Get all documents of current collection.
*
* @return a DBCursor instance of the result
* @throws BaseException If error happens.
*/
public DBCursor query() throws BaseException {
return query("", "", "", "", 0, -1);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
* @see com.sequoiadb.base.DBQuery
*/
public DBCursor query(DBQuery matcher) throws BaseException {
if (matcher == null) {
return query();
}
return query(matcher.getMatcher(), matcher.getSelector(),
matcher.getOrderBy(), matcher.getHint(), matcher.getSkipRowsCount(),
matcher.getReturnRowsCount(), matcher.getFlag());
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint) throws BaseException {
return query(matcher, selector, orderBy, hint, 0, -1, 0);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param flag the query flag, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint, int flag) throws BaseException {
return query(matcher, selector, orderBy, hint, 0, -1, flag);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(String matcher, String selector, String orderBy,
String hint) throws BaseException {
return query(matcher, selector, orderBy, hint, 0);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param flag the query flag, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(String matcher, String selector, String orderBy,
String hint, int flag) throws BaseException {
BSONObject ma = null;
BSONObject se = null;
BSONObject or = null;
BSONObject hi = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
if (selector != null) {
se = (BSONObject) JSON.parse(selector);
}
if (orderBy != null && !orderBy.equals("")) {
or = (BSONObject) JSON.parse(orderBy);
}
if (hint != null) {
hi = (BSONObject) JSON.parse(hint);
}
return query(ma, se, or, hi, 0, -1, flag);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(String matcher, String selector, String orderBy,
String hint, long skipRows, long returnRows) throws BaseException {
BSONObject ma = null;
BSONObject se = null;
BSONObject or = null;
BSONObject hi = null;
if (matcher != null) {
ma = (BSONObject) JSON.parse(matcher);
}
if (selector != null) {
se = (BSONObject) JSON.parse(selector);
}
if (orderBy != null) {
or = (BSONObject) JSON.parse(orderBy);
}
if (hint != null) {
hi = (BSONObject) JSON.parse(hint);
}
return query(ma, se, or, hi, skipRows, returnRows, 0);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint, long skipRows, long returnRows) throws BaseException {
return query(matcher, selector, orderBy, hint, skipRows, returnRows, 0);
}
/**
* Get the matching documents in current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @param flags the query flags, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor query(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint,
long skipRows, long returnRows,
int flags) throws BaseException {
if (flags != 0) {
flags = DBQuery.eraseSingleFlag(flags, DBQuery.FLG_QUERY_EXPLAIN);
}
return _query(matcher, selector, orderBy, hint,skipRows, returnRows, flags);
}
private DBCursor _query(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint,
long skipRows, long returnRows,
int flags) throws BaseException {
int newFlags = DBQuery.regulateFlags(flags);
if (returnRows < 0) {
returnRows = -1;
}
if (returnRows == 1) {
newFlags |= DBQuery.FLG_QUERY_WITH_RETURNDATA;
}
QueryRequest request = new QueryRequest(collectionFullName,
matcher, selector, orderBy, hint,
skipRows, returnRows, newFlags);
SdbReply response = sequoiadb.requestAndResponse(request);
int flag = response.getFlag();
if (flag != 0) {
if (flag == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
String msg = "matcher = " + matcher +
", selector = " + selector +
", orderBy = " + orderBy +
", hint = " + hint +
", skipRows = " + skipRows +
", returnRows = " + returnRows;
sequoiadb.throwIfError(response, msg);
}
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
return cursor;
}
/**
* Get one matched document from current collection.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param flag the query flag, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @return the matched document or null if no such document
* @throws BaseException If error happens.
*/
public BSONObject queryOne(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint,
int flag) throws BaseException {
flag = flag | DBQuery.FLG_QUERY_WITH_RETURNDATA;
DBCursor cursor = query(matcher, selector, orderBy, hint, 0, 1, flag);
return cursor.getNext();
}
/**
* Get one document from current collection.
*
* @return the document or null if no any document in current collection
* @throws BaseException If error happens.
*/
public BSONObject queryOne() throws BaseException {
return queryOne(null, null, null, null, 0);
}
/**
* Get all the indexes of current collection
*
* @return DBCursor of indexes
* @throws BaseException If error happens.
*/
public DBCursor getIndexes() throws BaseException {
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
AdminRequest request = new AdminRequest(AdminCommand.GET_INDEXES, null, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
int flags = response.getFlag();
if (flags != 0) {
if (flags == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
sequoiadb.throwIfError(response);
}
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
return cursor;
}
private DBCursor _queryAndModify(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint, BSONObject update,
long skipRows, long returnRows, int flag,
boolean isUpdate, boolean returnNew)
throws BaseException {
BSONObject modify = new BasicBSONObject();
if (isUpdate) {
if (update == null || update.isEmpty()) {
throw new BaseException(SDBError.SDB_INVALIDARG, "update can't be empty");
}
modify.put(SdbConstants.FIELD_NAME_OP,
SdbConstants.FIELD_OP_VALUE_UPDATE);
modify.put(SdbConstants.FIELD_NAME_OP_UPDATE, update);
modify.put(SdbConstants.FIELD_NAME_RETURNNEW, returnNew);
} else {
modify.put(SdbConstants.FIELD_NAME_OP,
SdbConstants.FIELD_OP_VALUE_REMOVE);
modify.put(SdbConstants.FIELD_NAME_OP_REMOVE, true);
}
BSONObject newHint = new BasicBSONObject();
if (hint != null) {
newHint.putAll(hint);
}
newHint.put(SdbConstants.FIELD_NAME_MODIFY, modify);
flag |= DBQuery.FLG_QUERY_MODIFY;
return query(matcher, selector, orderBy, newHint,
skipRows, returnRows, flag);
}
/**
* Get the matching documents in current collection and update.
* In order to make the update take effect, user must travel
* the DBCursor returned by this function.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param update the update rule, can't be null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @param flag the query flags, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_KEEP_SHARDINGKEY_IN_UPDATE
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @param returnNew When true, returns the updated document rather than the original
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor queryAndUpdate(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint, BSONObject update,
long skipRows, long returnRows, int flag, boolean returnNew)
throws BaseException {
return _queryAndModify(matcher, selector, orderBy, hint, update,
skipRows, returnRows, flag, true, returnNew);
}
/**
* Get the matching documents in current collection and remove.
* In order to make the remove take effect, user must travel
* the DBCursor returned by this function.
*
* @param matcher the matching rule, return all the documents if null
* @param selector the selective rule, return the whole document if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows skip the first numToSkip documents, never skip if this parameter is 0
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @param flag the query flag, default to be 0. Please see the definition
* of follow flags for more detail. Usage:
* e.g. set ( DBQuery.FLG_QUERY_FORCE_HINT | DBQuery.FLG_QUERY_WITH_RETURNDATA ) to param flag
*
* - DBQuery.FLG_QUERY_STRINGOUT
*
- DBQuery.FLG_QUERY_FORCE_HINT
*
- DBQuery.FLG_QUERY_PARALLED
*
- DBQuery.FLG_QUERY_WITH_RETURNDATA
*
- DBQuery.FLG_QUERY_FOR_UPDATE
*
* @return a DBCursor instance of the result or null if no any matched document
* @throws BaseException If error happens.
*/
public DBCursor queryAndRemove(BSONObject matcher, BSONObject selector,
BSONObject orderBy, BSONObject hint,
long skipRows, long returnRows, int flag)
throws BaseException {
return _queryAndModify(matcher, selector, orderBy, hint, null,
skipRows, returnRows, flag, false, false);
}
/**
* Get all of or one of the indexes in current collection.
*
* @param name The index name, returns all of the indexes if this parameter
* is null
* @return DBCursor of indexes
* @throws BaseException If error happens.
* @deprecated use "getIndexInfo" or "getIndexes" API instead.
*/
public DBCursor getIndex(String name) throws BaseException {
if (name == null) {
return getIndexes();
}
BSONObject condition = new BasicBSONObject();
condition.put(SdbConstants.IXM_INDEXDEF + "."
+ SdbConstants.IXM_NAME, name);
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
AdminRequest request = new AdminRequest(AdminCommand.GET_INDEXES, condition, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
int flags = response.getFlag();
if (flags != 0) {
if (flags == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
sequoiadb.throwIfError(response);
}
}
sequoiadb.upsertCache(collectionFullName);
return new DBCursor(response, sequoiadb);
}
/**
* Get the information of specified index in current collection.
*
* @param name The index name.
* @return The information of the specified index.
* @throws BaseException If error happens or the specified index does not exist.
*/
public BSONObject getIndexInfo(String name) throws BaseException {
BSONObject retObj ;
if (name == null || name.isEmpty()) {
throw new BaseException(SDBError.SDB_INVALIDARG, "index name can not be null or empty");
}
BSONObject condition = new BasicBSONObject();
condition.put(SdbConstants.IXM_INDEXDEF + "." + SdbConstants.IXM_NAME, name);
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
AdminRequest request = new AdminRequest(AdminCommand.GET_INDEXES, condition, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
sequoiadb.throwIfError(response);
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
try {
if (cursor.hasNext()) {
retObj = cursor.getNext();
return retObj;
} else {
throw new BaseException(SDBError.SDB_IXM_NOTEXIST,
"the specified index[" + name + "] does not exist");
}
} finally {
cursor.close();
}
}
/**
* Test the specified index exist or not.
*
* @param name The index name.
* @return True for exist while false for not exist..
*/
public boolean isIndexExist(String name) {
if (name == null || name.isEmpty()) {
return false;
}
BSONObject indexObj;
try {
indexObj = getIndexInfo(name);
} catch (Exception e) {
return false;
}
if (indexObj != null)
{
return true;
}
return false;
}
/**
* Create a index with name and key.
*
* @param name The index name
* @param key The index keys in JSON format, like: "{\"a\":1, \"b\":-1}"
* @param isUnique Whether the index elements are unique or not
* @param enforced Whether the index is enforced unique This element is
* meaningful when isUnique is set to true
* @param sortBufferSize The size(MB) of sort buffer used when creating index,
* zero means don't use sort buffer
* @throws BaseException If error happens.
*/
public void createIndex(String name, BSONObject key, boolean isUnique,
boolean enforced, int sortBufferSize) throws BaseException {
if (sortBufferSize < 0) {
throw new BaseException(SDBError.SDB_INVALIDARG, "sortBufferSize less than 0");
}
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.IXM_KEY, key);
obj.put(SdbConstants.IXM_NAME, name);
obj.put(SdbConstants.IXM_UNIQUE, isUnique);
obj.put(SdbConstants.IXM_ENFORCED, enforced);
BSONObject createObj = new BasicBSONObject();
createObj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
createObj.put(SdbConstants.FIELD_INDEX, obj);
BSONObject hint = new BasicBSONObject();
hint.put(SdbConstants.IXM_FIELD_NAME_SORT_BUFFER_SIZE,
sortBufferSize);
AdminRequest request = new AdminRequest(AdminCommand.CREATE_INDEX, createObj, hint);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "name = " + name +
", key = " + key +
", isUnique = " + isUnique;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Create a index with name and key.
*
* @param name The index name
* @param key The index keys in JSON format, like: "{\"a\":1, \"b\":-1}"
* @param isUnique Whether the index elements are unique or not
* @param enforced Whether the index is enforced unique This element is
* meaningful when isUnique is set to true
* @param sortBufferSize The size(MB) of sort buffer used when creating index,
* zero means don't use sort buffer
* @throws BaseException If error happens.
*/
public void createIndex(String name, String key, boolean isUnique,
boolean enforced, int sortBufferSize) throws BaseException {
BSONObject k = null;
if (key != null) {
k = (BSONObject) JSON.parse(key);
}
createIndex(name, k, isUnique, enforced, sortBufferSize);
}
/**
* Create a index with name and key
*
* @param name The index name
* @param key The index keys in JSON format, like: "{\"a\":1, \"b\":-1}"
* @param isUnique Whether the index elements are unique or not
* @param enforced Whether the index is enforced unique This element is
* meaningful when isUnique is set to true
* @throws BaseException If error happens.
*/
public void createIndex(String name, BSONObject key, boolean isUnique,
boolean enforced) throws BaseException {
createIndex(name, key, isUnique, enforced,
SdbConstants.IXM_SORT_BUFFER_DEFAULT_SIZE);
}
/**
* Create a index with name and key.
*
* @param name The index name
* @param key The index keys in JSON format, like: "{\"a\":1, \"b\":-1}"
* @param isUnique Whether the index elements are unique or not
* @param enforced Whether the index is enforced unique This element is
* meaningful when isUnique is set to true
* @throws BaseException If error happens.
*/
public void createIndex(String name, String key, boolean isUnique,
boolean enforced) throws BaseException {
BSONObject k = null;
if (key != null) {
k = (BSONObject) JSON.parse(key);
}
createIndex(name, k, isUnique, enforced,
SdbConstants.IXM_SORT_BUFFER_DEFAULT_SIZE);
}
/**
* Remove the named index of current collection.
*
* @param name The index name
* @throws BaseException If error happens.
*/
public void dropIndex(String name) throws BaseException {
BSONObject index = new BasicBSONObject();
index.put("", name);
BSONObject dropObj = new BasicBSONObject();
dropObj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
dropObj.put(SdbConstants.FIELD_INDEX, index);
AdminRequest request = new AdminRequest(AdminCommand.DROP_INDEX, dropObj);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, name);
sequoiadb.upsertCache(collectionFullName);
}
/**
* Get the amount of documents in current collection.
*
* @return the amount of matching documents
* @throws BaseException If error happens.
*/
public long getCount() throws BaseException {
return getCount("");
}
/**
* Get the amount of matching documents in current collection.
*
* @param matcher the matching rule
* @return the amount of matching documents
* @throws BaseException If error happens.
*/
public long getCount(String matcher) throws BaseException {
BSONObject con = null;
if (matcher != null) {
con = (BSONObject) JSON.parse(matcher);
}
return getCount(con);
}
/**
* Get the amount of matching documents in current collection.
*
* @param matcher The matching rule, when condition is null, the return amount contains all the records.
* @return the amount of matching documents
* @throws BaseException If error happens.
*/
public long getCount(BSONObject matcher) throws BaseException {
return getCount(matcher, null);
}
/**
* Get the count of matching BSONObject in current collection.
*
* @param matcher The matching rule, when condition is null, the return amount contains all the records.
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @return The count of matching BSONObjects
* @throws BaseException If error happens.
*/
public long getCount(BSONObject matcher, BSONObject hint) throws BaseException {
BSONObject newHint = new BasicBSONObject();
newHint.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
if (null != hint) {
newHint.put(SdbConstants.FIELD_NAME_HINT, hint);
}
AdminRequest request = new AdminRequest(AdminCommand.GET_COUNT, matcher, newHint);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "condition = " + matcher +
", hint = " + hint;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
BSONObject object;
try {
object = cursor.getNext();
} finally {
cursor.close();
}
return (Long) object.get(SdbConstants.FIELD_TOTAL);
}
/**
* Split the specified collection from source group to target group by range.
*
* @param sourceGroupName the source group name
* @param destGroupName the destination group name
* @param splitCondition the split condition
* @param splitEndCondition the split end condition or null, only usable when "ShardingType" is "range".
* eg:If we create a collection with the option {ShardingKey:{"age":1},ShardingType:"range"},
* we can fill {age:30} as the splitCondition, and fill {age:60} as the splitEndCondition. when split,
* the target group will get the records whose age's hash value are in [30,60). If splitEndCondition is null,
* they are in [30,max).
* @throws BaseException If error happens.
*/
public void split(String sourceGroupName, String destGroupName,
BSONObject splitCondition, BSONObject splitEndCondition) throws BaseException {
if ((null == sourceGroupName || sourceGroupName.equals("")) ||
(null == destGroupName || destGroupName.equals("")) ||
null == splitCondition) {
throw new BaseException(SDBError.SDB_INVALIDARG, "null parameter");
}
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
obj.put(SdbConstants.FIELD_NAME_SOURCE, sourceGroupName);
obj.put(SdbConstants.FIELD_NAME_TARGET, destGroupName);
obj.put(SdbConstants.FIELD_NAME_SPLITQUERY, splitCondition);
if (null != splitEndCondition) {
obj.put(SdbConstants.FIELD_NAME_SPLITENDQUERY, splitEndCondition);
}
AdminRequest request = new AdminRequest(AdminCommand.SPLIT, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "sourceGroupName = " + sourceGroupName +
", destGroupName = " + destGroupName +
", splitCondition = " + splitCondition +
", splitEndCondition = " + splitEndCondition;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Split the specified collection from source group to target group by percent.
*
* @param sourceGroupName the source group name
* @param destGroupName the destination group name
* @param percent the split percent, Range:(0,100]
* @throws BaseException If error happens.
*/
public void split(String sourceGroupName, String destGroupName,
double percent) throws BaseException {
if ((null == sourceGroupName || sourceGroupName.equals("")) ||
(null == destGroupName || destGroupName.equals("")) ||
(percent <= 0.0 || percent > 100.0)) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
obj.put(SdbConstants.FIELD_NAME_SOURCE, sourceGroupName);
obj.put(SdbConstants.FIELD_NAME_TARGET, destGroupName);
obj.put(SdbConstants.FIELD_NAME_SPLITPERCENT, percent);
AdminRequest request = new AdminRequest(AdminCommand.SPLIT, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "sourceGroupName = " + sourceGroupName +
", destGroupName = " + destGroupName +
", percent = " + percent;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Split the specified collection from source group to target group by range asynchronously.
*
* @param sourceGroupName the source group name
* @param destGroupName the destination group name
* @param splitCondition the split condition
* @param splitEndCondition the split end condition or null, only usable when "ShardingType" is "range".
* eg:If we create a collection with the option {ShardingKey:{"age":1},ShardingType:"range"},
* we can fill {age:30} as the splitCondition, and fill {age:60} as the splitEndCondition. when split,
* the target group will get the records whose age's hash values are in [30,60). If splitEndCondition is null,
* they are in [30,max).
* @return return the task id, we can use the return id to manage the sharding which is run background.
* @throws BaseException If error happens.
* @see Sequoiadb#listTasks(BSONObject, BSONObject, BSONObject, BSONObject)
* @see Sequoiadb#cancelTask(long, boolean)
*/
public long splitAsync(String sourceGroupName,
String destGroupName,
BSONObject splitCondition,
BSONObject splitEndCondition) throws BaseException {
if ((null == sourceGroupName || sourceGroupName.equals("")) ||
(null == destGroupName || destGroupName.equals("")) ||
null == splitCondition) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
obj.put(SdbConstants.FIELD_NAME_ASYNC, true);
obj.put(SdbConstants.FIELD_NAME_SOURCE, sourceGroupName);
obj.put(SdbConstants.FIELD_NAME_TARGET, destGroupName);
obj.put(SdbConstants.FIELD_NAME_SPLITQUERY, splitCondition);
if (null != splitEndCondition) {
obj.put(SdbConstants.FIELD_NAME_SPLITENDQUERY, splitEndCondition);
}
AdminRequest request = new AdminRequest(AdminCommand.SPLIT, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "sourceGroupName = " + sourceGroupName +
", destGroupName = " + destGroupName +
", splitCondition = " + splitCondition +
", splitEndCondition = " + splitEndCondition;
sequoiadb.throwIfError(response, msg);
}
BSONObject result;
DBCursor cursor = new DBCursor(response, sequoiadb);
try {
if (!cursor.hasNext()) {
throw new BaseException(SDBError.SDB_CAT_TASK_NOTFOUND);
}
result = cursor.getNext();
} finally {
cursor.close();
}
boolean flag = result.containsField(SdbConstants.FIELD_NAME_TASKID);
if (!flag) {
throw new BaseException(SDBError.SDB_CAT_TASK_NOTFOUND);
}
sequoiadb.upsertCache(collectionFullName);
long taskid = (Long) result.get(SdbConstants.FIELD_NAME_TASKID);
return taskid;
}
/**
* Split the specified collection from source group to target group by percent asynchronously.
*
* @param sourceGroupName the source group name
* @param destGroupName the destination group name
* @param percent the split percent, Range:(0,100]
* @return return the task id, we can use the return id to manage the sharding which is run background.
* @throws BaseException If error happens.
*/
public long splitAsync(String sourceGroupName, String destGroupName,
double percent) throws BaseException {
if ((null == sourceGroupName || sourceGroupName.equals("")) ||
(null == destGroupName || destGroupName.equals("")) ||
(percent <= 0.0 || percent > 100.0)) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
obj.put(SdbConstants.FIELD_NAME_ASYNC, true);
obj.put(SdbConstants.FIELD_NAME_SOURCE, sourceGroupName);
obj.put(SdbConstants.FIELD_NAME_TARGET, destGroupName);
obj.put(SdbConstants.FIELD_NAME_SPLITPERCENT, percent);
AdminRequest request = new AdminRequest(AdminCommand.SPLIT, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "sourceGroupName = " + sourceGroupName +
", destGroupName = " + destGroupName +
", percent = " + percent;
sequoiadb.throwIfError(response, msg);
}
BSONObject result;
DBCursor cursor = new DBCursor(response, sequoiadb);
try {
if (!cursor.hasNext()) {
throw new BaseException(SDBError.SDB_CAT_TASK_NOTFOUND);
}
result = cursor.getNext();
} finally {
cursor.close();
}
boolean flag = result.containsField(SdbConstants.FIELD_NAME_TASKID);
if (!flag) {
throw new BaseException(SDBError.SDB_CAT_TASK_NOTFOUND);
}
sequoiadb.upsertCache(collectionFullName);
long taskid = (Long) result.get(SdbConstants.FIELD_NAME_TASKID);
return taskid;
}
/**
* Execute aggregate operation in current collection.
*
* @param objs The Bson object of rule list, can't be null
* @throws BaseException If error happens.
*/
public DBCursor aggregate(List objs)
throws BaseException {
if (objs == null || objs.size() == 0) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
AggregateRequest request = new AggregateRequest(collectionFullName, objs);
SdbReply response = sequoiadb.requestAndResponse(request);
int flags = response.getFlag();
if (flags != 0) {
if (flags == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
sequoiadb.throwIfError(response, objs);
}
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
return cursor;
}
/**
* Get index blocks' or data blocks' information for concurrent query.
*
* @param matcher the matching rule, return all the meta information if null
* @param orderBy the ordered rule, never sort if null
* @param hint Specified the index used to scan data. e.g. {"":"ageIndex"} means
* using index "ageIndex" to scan data(index scan);
* {"":null} means table scan. when hint is null,
* database automatically match the optimal index to scan data.
* @param skipRows The rows to be skipped
* @param returnRows return the specified amount of documents,
* when returnRows is 0, return nothing,
* when returnRows is -1, return all the documents
* @param flag The flag to use which form for record data
* 0: bson stream
* 1: binary data stream, form: col1|col2|col3
* @return DBCursor of data
* @throws BaseException If error happens.
*/
public DBCursor getQueryMeta(BSONObject matcher, BSONObject orderBy,
BSONObject hint, long skipRows,
long returnRows, int flag) throws BaseException {
BSONObject newHint = new BasicBSONObject();
newHint.put("Collection", this.collectionFullName);
if (null == hint || hint.isEmpty()) {
BSONObject empty = new BasicBSONObject();
newHint.put("Hint", empty);
} else {
newHint.put("Hint", hint);
}
QueryRequest request = new QueryRequest(AdminCommand.GET_QUERYMETA, matcher, null, orderBy, newHint,
skipRows, returnRows, flag);
SdbReply response = sequoiadb.requestAndResponse(request);
int flags = response.getFlag();
if (flags != 0) {
if (flags == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
String msg = "query = " + matcher +
", hint = " + hint +
", orderBy = " + orderBy +
", skipRows = " + skipRows +
", returnRows = " + returnRows;
sequoiadb.throwIfError(response, msg);
}
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
return cursor;
}
/**
* Attach the specified collection.
*
* @param subClFullName The full name of the sub-collection
* @param options The low boundary and up boundary
* eg: {"LowBound":{a:1},"UpBound":{a:100}}
* @throws BaseException If error happens.
*/
public void attachCollection(String subClFullName, BSONObject options) throws BaseException {
if (null == subClFullName || subClFullName.equals("") ||
null == options ||
null == collectionFullName || collectionFullName.equals("")) {
throw new BaseException(SDBError.SDB_INVALIDARG, "sub collection name or options is empty or null");
}
BSONObject newOptions = new BasicBSONObject();
newOptions.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
newOptions.put(SdbConstants.FIELD_NAME_SUBCLNAME, subClFullName);
newOptions.putAll(options);
AdminRequest request = new AdminRequest(AdminCommand.ATTACH_CL, newOptions);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "subCollectionName = " + subClFullName +
", options = " + options;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Detach the specified collection.
*
* @param subClFullName The full name of the sub-collection
* @throws BaseException If error happens.
*/
public void detachCollection(String subClFullName) throws BaseException {
if (null == subClFullName || subClFullName.equals("") ||
null == collectionFullName || collectionFullName.equals("")) {
throw new BaseException(SDBError.SDB_INVALIDARG, subClFullName);
}
BSONObject options = new BasicBSONObject();
options.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
options.put(SdbConstants.FIELD_NAME_SUBCLNAME, subClFullName);
AdminRequest request = new AdminRequest(AdminCommand.DETACH_CL, options);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, subClFullName);
sequoiadb.upsertCache(collectionFullName);
}
private void alterInternal(String taskName, BSONObject options, boolean allowNullArgs) throws BaseException {
if (null == options && !allowNullArgs) {
throw new BaseException(SDBError.SDB_INVALIDARG, "options is null");
}
BSONObject argumentObj = new BasicBSONObject();
argumentObj.put(SdbConstants.FIELD_NAME_NAME, taskName);
argumentObj.put(SdbConstants.FIELD_NAME_ARGS, options);
BSONObject alterObject = new BasicBSONObject();
alterObject.put(SdbConstants.FIELD_NAME_ALTER, argumentObj);
alterCollection(alterObject);
}
/**
* Alter the attributes of current collection.
* Can't alter attributes about split in partition collection; After altering a collection to
* be a partition collection, need to split this collection manually.
*
* @param options The options for altering current collection are as below:
*
* - ReplSize : Assign how many replica nodes need to be synchronized when a write request(insert, update, etc) is executed
*
- ShardingKey : Assign the sharding key
*
- ShardingType : Assign the sharding type
*
- Partition : When the ShardingType is "hash", need to assign Partition, it's the bucket number for hash, the range is [2^3,2^20].
*
- CompressionType : The compression type of data, could be "snappy" or "lzw"
*
- EnsureShardingIndex : Assign to true to build sharding index
*
- StrictDataMode : Using strict date mode in numeric operations or not
* e.g. {RepliSize:0, ShardingKey:{a:1}, ShardingType:"hash", Partition:1024}
*
- AutoIncrement : Assign attributes of an autoincrement field or batch autoincrement fields.
* e.g. {AutoIncrement:{Field:"a",MaxValue:2000}},{AutoIncrement:[{Field:"a",MaxValue:2000},{Field:"a",MaxValue:4000}]}
*
* @throws BaseException If error happens.
*/
public void alterCollection(BSONObject options) throws BaseException {
if (null == options) {
throw new BaseException(SDBError.SDB_INVALIDARG, "options is null");
}
BSONObject newObj = new BasicBSONObject();
if (!options.containsField(SdbConstants.FIELD_NAME_ALTER)) {
newObj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
newObj.put(SdbConstants.FIELD_NAME_OPTIONS, options);
} else {
Object tmpAlter = options.get(SdbConstants.FIELD_NAME_ALTER);
if (tmpAlter instanceof BasicBSONObject ||
tmpAlter instanceof BasicBSONList) {
newObj.put(SdbConstants.FIELD_NAME_ALTER, tmpAlter);
} else {
throw new BaseException(SDBError.SDB_INVALIDARG, options.toString());
}
newObj.put(SdbConstants.FIELD_NAME_ALTER_TYPE,
SdbConstants.SDB_ALTER_CL);
newObj.put(SdbConstants.FIELD_NAME_VERSION,
SdbConstants.SDB_ALTER_VERSION);
newObj.put(SdbConstants.FIELD_NAME_NAME, collectionFullName);
if (options.containsField(SdbConstants.FIELD_NAME_OPTIONS)) {
Object tmpOptions = options.get(SdbConstants.FIELD_NAME_OPTIONS);
if (tmpOptions instanceof BasicBSONObject) {
newObj.put(SdbConstants.FIELD_NAME_OPTIONS, tmpOptions);
} else {
throw new BaseException(SDBError.SDB_INVALIDARG, options.toString());
}
}
}
AdminRequest request = new AdminRequest(AdminCommand.ALTER_COLLECTION, newObj);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, options);
sequoiadb.upsertCache(collectionFullName);
}
/**
* Create auto-increment for current collection.
*
* @param options The options for creating auto-increment are as below:
*
* - Field : Auto-increment field name
*
- Increment : The interval between consecutive values
*
- StartValue : The first value for auto-increment
*
- MinValue : The minimum value
*
- MaxValue : The maximum value
*
- CacheSize : The number of values that are cached in catalog node
*
- AcquireSize : The number of values that are acquired by coord node
*
- Cycled : Whether generate the next value after reaching the maximum or minimum
*
- Generated : Whether generate value if the field has already exist. It can be "default", "always" or "strict".
*
- default : Generate the value by default if field is not exist. It is default value either.
*
- always : Always Generate the value, ignore the existent field.
*
- strict : Like 'default' behavior, but additionally check the type of field. If not number, return error.
* e.g. {Field:"ID", StartValue:100, Generated:"always"}
*
* @throws BaseException If error happens.
*/
public void createAutoIncrement(BSONObject options) {
if (options == null || options.isEmpty()) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
List optionsList = new ArrayList();
optionsList.add(options);
createAutoIncrement(optionsList);
}
/**
* Create one or more auto-increment for current collection.
*
* @param options The options of the auto-increment(s)
* @throws BaseException If error happens.
*/
public void createAutoIncrement(List options) {
if (options == null || options.size() == 0) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject(SdbConstants.FIELD_NAME_AUTOINCREMENT, options);
alterInternal(SdbConstants.SDB_ALTER_CL_CRT_AUTOINC_FLD, obj, false);
}
/**
* Drop auto-increment of current collection.
*
* @param fieldName The auto-increment field name
* @throws BaseException If error happens.
*/
public void dropAutoIncrement(String fieldName) {
if (fieldName == null || fieldName.length() == 0) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject(SdbConstants.FIELD_NAME_AUTOINC_FIELD, fieldName);
alterInternal(SdbConstants.SDB_ALTER_CL_DROP_AUTOINC_FLD, obj, false);
}
/**
* Drop one or more auto-increment of current collection.
*
* @param fieldNames The auto-increment field name(s)
* @throws BaseException If error happens.
*/
public void dropAutoIncrement(List fieldNames) {
if (fieldNames == null || fieldNames.size() == 0) {
throw new BaseException(SDBError.SDB_INVALIDARG);
}
BSONObject obj = new BasicBSONObject(SdbConstants.FIELD_NAME_AUTOINC_FIELD, fieldNames);
alterInternal(SdbConstants.SDB_ALTER_CL_DROP_AUTOINC_FLD, obj, false);
}
/**
* Create the id index.
*
* @param options can be empty or specify option. e.g. {SortBufferSize:64}
* @throws BaseException If error happens.
*/
public void createIdIndex(BSONObject options) throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_CRT_ID_INDEX, options, true);
}
/**
* Drop the id index.
*
* @throws BaseException If error happens.
*/
public void dropIdIndex() throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_DROP_ID_INDEX, null, true);
}
/**
* Alter the attributes of current collection to enable sharding
*
* @param options The options for altering current collection are as below:
*
* - ShardingKey : Assign the sharding key
*
- ShardingType : Assign the sharding type
*
- Partition : When the ShardingType is "hash", need to assign Partition, it's the bucket number for hash, the range is [2^3,2^20].
*
- EnsureShardingIndex : Assign to true to build sharding index
*
* @throws BaseException If error happens.
*/
public void enableSharding(BSONObject options) throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_ENABLE_SHARDING, options, false);
}
/**
* Alter the attributes of current collection to disable sharding
*
* @throws BaseException If error happens.
*/
public void disableSharding() throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_DISABLE_SHARDING, null, true);
}
/**
* Alter the attributes of current collection to enable compression
*
* @param options The options for altering current collection are as below:
*
* - CompressionType : The compression type of data, could be "snappy" or "lzw"
*
* @throws BaseException If error happens.
*/
public void enableCompression(BSONObject options) throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_ENABLE_COMPRESSION, options, true);
}
/**
* Alter the attributes of current collection to disable compression
*
* @throws BaseException If error happens.
*/
public void disableCompression() throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_DISABLE_COMPRESSION, null, true);
}
/**
* Alter the attributes of current collection
* Can't alter attributes about split in partition collection; After altering a collection to
* be a partition collection, need to split this collection manually.
*
* @param options The options for altering current collection are as below:
*
* - ReplSize : Assign how many replica nodes need to be synchronized when a write request(insert, update, etc) is executed
*
- ShardingKey : Assign the sharding key
*
- ShardingType : Assign the sharding type
*
- Partition : When the ShardingType is "hash", need to assign Partition, it's the bucket number for hash, the range is [2^3,2^20].
*
- CompressionType : The compression type of data, could be "snappy" or "lzw"
*
- EnsureShardingIndex : Assign to true to build sharding index
*
- StrictDataMode : Using strict date mode in numeric operations or not
* e.g. {RepliSize:0, ShardingKey:{a:1}, ShardingType:"hash", Partition:1024}
*
- AutoIncrement : Assign attributes of an autoincrement field or batch autoincrement fields.
* e.g. {AutoIncrement:{Field:"a",MaxValue:2000}},
* {AutoIncrement:[{Field:"a",MaxValue:2000},{Field:"a",MaxValue:4000}]}
*
* @throws BaseException If error happens.
*/
public void setAttributes(BSONObject options) throws BaseException {
alterInternal(SdbConstants.SDB_ALTER_SET_ATTRIBUTES, options, false);
}
private void _update(int flag, BSONObject matcher, BSONObject modifier,
BSONObject hint) throws BaseException {
UpdateRequest request = new UpdateRequest(collectionFullName, matcher, modifier, hint, flag);
SdbReply response = sequoiadb.requestAndResponse(request);
if (response.getFlag() != 0) {
String msg = "matcher = " + matcher +
", modifier = " + modifier +
", hint = " + hint;
sequoiadb.throwIfError(response, msg);
}
sequoiadb.upsertCache(collectionFullName);
}
/**
* Get all of the lobs in current collection.
*
* @return DBCursor of lobs
* @throws BaseException If error happens.
*/
public DBCursor listLobs() throws BaseException {
BSONObject obj = new BasicBSONObject();
obj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
AdminRequest request = new AdminRequest(AdminCommand.LIST_LOBS, obj);
SdbReply response = sequoiadb.requestAndResponse(request);
int flag = response.getFlag();
if (flag != 0) {
if (flag == SDBError.SDB_DMS_EOC.getErrorCode()) {
return null;
} else {
sequoiadb.throwIfError(response);
}
}
sequoiadb.upsertCache(collectionFullName);
DBCursor cursor = new DBCursor(response, sequoiadb);
return cursor;
}
/**
* Create a lob.
*
* @return DBLob object
* @throws BaseException If error happens..
*/
public DBLob createLob() throws BaseException {
return createLob(null);
}
/**
* Create a lob with a given id.
*
* @param id the lob's id. if id is null, it will be generated in
* this function
* @return DBLob object
* @throws BaseException If error happens..
*/
public DBLob createLob(ObjectId id) throws BaseException {
DBLobImpl lob = new DBLobImpl(this);
lob.open(id, DBLobImpl.SDB_LOB_CREATEONLY);
// upsert cache
sequoiadb.upsertCache(collectionFullName);
return lob;
}
/**
* Open an existing lob with id.
*
* @param id the lob's id.
* @param mode open mode:
* DBLob.SDB_LOB_READ for reading,
* DBLob.SDB_LOB_WRITE for writing.
* @return DBLob object
* @throws BaseException If error happens..
*/
public DBLob openLob(ObjectId id, int mode) throws BaseException {
if (mode != DBLob.SDB_LOB_READ && mode != DBLob.SDB_LOB_WRITE) {
throw new BaseException(SDBError.SDB_INVALIDARG, "mode is unsupported: " + mode);
}
DBLobImpl lob = new DBLobImpl(this);
lob.open(id, mode);
// upsert cache
sequoiadb.upsertCache(collectionFullName);
return lob;
}
/**
* Open an existing lob with id.
*
* @param id the lob's id.
* @return DBLob object
* @throws BaseException If error happens.
*/
public DBLob openLob(ObjectId id) throws BaseException {
return openLob(id, DBLob.SDB_LOB_READ);
}
/**
* Remove an existing lob.
*
* @param lobId the lob's id.
* @throws BaseException If error happens..
*/
public void removeLob(ObjectId lobId) throws BaseException {
BSONObject removeObj = new BasicBSONObject();
removeObj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
removeObj.put(DBLobImpl.FIELD_NAME_LOB_OID, lobId);
LobRemoveRequest request = new LobRemoveRequest(removeObj);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, removeObj);
sequoiadb.upsertCache(collectionFullName);
}
/**
* Truncate an existing lob.
*
* @param lobId the lob's id.
* @param length the truncate length
* @throws BaseException If error happens.
*/
public void truncateLob(ObjectId lobId, long length) throws BaseException {
if (length < 0) {
throw new BaseException(SDBError.SDB_INVALIDARG, "Invalid length");
}
BSONObject truncateObj = new BasicBSONObject();
truncateObj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
truncateObj.put(DBLobImpl.FIELD_NAME_LOB_OID, lobId);
truncateObj.put(DBLobImpl.FIELD_NAME_LOB_LENGTH, length);
LobTruncateRequest request = new LobTruncateRequest(truncateObj);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, truncateObj);
sequoiadb.upsertCache(collectionFullName);
}
/**
* Truncate the collection.
*
* @throws BaseException If error happens.
*/
public void truncate() throws BaseException {
BSONObject options = new BasicBSONObject();
options.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
AdminRequest request = new AdminRequest(AdminCommand.TRUNCATE, options);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, options);
sequoiadb.upsertCache(collectionFullName);
}
/**
* Pop records from the collection.
*
* @param options the pop option for the operation, including a record LogicalID,
* and an optional Direction: 1 for forward pop and -1 for backward
* pop
* @throws BaseException If error happens.
*/
public void pop(BSONObject options) throws BaseException {
if (options == null) {
throw new BaseException(SDBError.SDB_INVALIDARG, "options is null");
}
BSONObject newObj = new BasicBSONObject();
newObj.put(SdbConstants.FIELD_COLLECTION, collectionFullName);
Object lidObj = options.get(SdbConstants.FIELD_NAME_LOGICALID);
if (lidObj instanceof Integer || lidObj instanceof Long) {
newObj.put(SdbConstants.FIELD_NAME_LOGICALID, lidObj);
} else {
throw new BaseException(SDBError.SDB_INVALIDARG, options.toString());
}
Object directObj = options.get(SdbConstants.FIELD_NAME_DIRECTION);
if (directObj == null) {
newObj.put(SdbConstants.FIELD_NAME_DIRECTION, 1);
} else if (directObj instanceof Integer) {
newObj.put(SdbConstants.FIELD_NAME_DIRECTION, directObj);
} else {
throw new BaseException(SDBError.SDB_INVALIDARG, options.toString());
}
AdminRequest request = new AdminRequest(AdminCommand.POP, newObj);
SdbReply response = sequoiadb.requestAndResponse(request);
sequoiadb.throwIfError(response, newObj);
sequoiadb.upsertCache(collectionFullName);
}
}