All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sequoiadb.base.DBCollection Maven / Gradle / Ivy

There is a newer version: 5.10
Show newest version
/**
 *      Copyright (C) 2012 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;
 * @brief SequoiaDB Driver for Java
 * @author Jacky Zhang
 */
package com.sequoiadb.base;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.mina.core.buffer.IoBuffer;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.types.ObjectId;
import org.bson.util.JSON;

import com.sequoiadb.base.SequoiadbConstants.Operation;
import com.sequoiadb.exception.BaseException;
import com.sequoiadb.net.IConnection;
import com.sequoiadb.util.Helper;
import com.sequoiadb.util.SDBMessageHelper;

/**
 * @class DBCollection
 * @brief Database operation interfaces of collection.
 */
public class DBCollection {
	private String name;
	private Sequoiadb sequoiadb;
	private CollectionSpace collectionSpace;
	private IConnection connection;
	private String csName;
	private String collectionFullName;
	private Set mainKeys;

	private IoBuffer insert_buffer;
	private static final int DEF_BUFFER_LENGTH = 64*1024;
	private static final int DEF_BULK_BUFFER_LENGTH = 2*1024*1024; 
	
	/**
	 * @memberof FLG_INSERT_CONTONDUP 0x00000001
	 * @brief this flags represent that bulkInsert will continue when
	 *        Duplicate key exist.(the duplicate record will be ignored)
	 */
	public final static int FLG_INSERT_CONTONDUP = 0x00000001;
	
	public IConnection getConnection() {
		return connection;
	}
	
	public void setConnection(IConnection connection) {
		this.connection = connection;
	}

	/**
	 * @fn String getName()
	 * @brief Return the name of current collection
	 * @return The collection name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @fn String getFullName()
	 * @brief Get the full name of specified collection in current collection
	 *        space
	 * @return The full name of specified collection
	 */
	public String getFullName() {
		return collectionFullName;
	}

	/**
	 * @fn String getCSName()
	 * @brief Get the full name of specified collection in current collection
	 *        space
	 * @return The full name of specified collection
	 */
	public String getCSName() {
		return csName;
	}

	/**
	 * @fn Sequoiadb getSequoiadb()
	 * @brief Return the Sequoiadb handle of current collection
	 * @return Sequoiadb object
	 */
	public Sequoiadb getSequoiadb() {
		return sequoiadb;
	}

	/**
	 * @fn CollectionSpace getCollectionSpace()
	 * @brief Return the Collection Space handle of current collection
	 * @return CollectionSpace object
	 */
	public CollectionSpace getCollectionSpace() {
		return collectionSpace;
	}

	/**
	 * @fn void setMainKeys(String[] keys)
	 * @brief Set the main keys used in save(). if no main keys are set, use the
	 * 		  default main key "_id". 
	 * @param keys
	 * 		  the main keys specified by user.
	 * @exception com.sequoiadb.Exception.BaseException when keys is null
	 * @note 
	 *        every time invokes the method,
	 *        it will remove the main keys set in last time 
	 */
	public void setMainKeys(String[] keys) throws BaseException {
		if (keys == null)
			throw new BaseException("SDB_INVALIDARG", (Object[])keys);
		// remove the main keys set in last time
		mainKeys.clear();
		// add the new main keys
		if (keys.length == 0)
			return;
		for(String k : keys)
			mainKeys.add(k);
	}
	
	/**
	 * @fn DBCollection(Sequoiadb sequoiadb, CollectionSpace cs, String name)
	 * @brief Constructor
	 * @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.connection = sequoiadb.getConnection();
		this.insert_buffer = null;
		this.mainKeys = new HashSet();
	}

	/**
	 * @fn Object insert(BSONObject insertor)
	 * @brief Insert a document into current collection, if the document
	 *        does not contain field "_id", it will be added.
	 * @param insertor
	 *            The Bson object of insertor, can't be null
	 * @return Object the value of the filed "_id"
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public Object insert(BSONObject insertor) throws BaseException {
		if (insertor == null)
			throw new BaseException("SDB_INVALIDARG");
		
		if (this.insert_buffer == null) {
			this.insert_buffer = IoBuffer.allocate(DEF_BUFFER_LENGTH);
			this.insert_buffer.setAutoExpand(true);
			if (sequoiadb.endianConvert) {
				insert_buffer.order(ByteOrder.LITTLE_ENDIAN);
			} else {
				insert_buffer.order(ByteOrder.BIG_ENDIAN);
			}
		} else {
			insert_buffer.clear();
		}
		
		Object tmp = insertor.get(SequoiadbConstants.OID);
		if (tmp == null) {
			ObjectId objId = ObjectId.get();
			insertor.put(SequoiadbConstants.OID, objId);
			tmp = objId;
		}
		
		int message_length = SDBMessageHelper.buildInsertRequest(insert_buffer, 
		        sequoiadb.getNextRequstID(), collectionFullName, insertor);

		connection.sendMessage(insert_buffer.array(), message_length);
		
		ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert);
		SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer);
		if ( rtnSDBMessage.getOperationCode() != Operation.OP_INSERT_RES) {
		    throw new BaseException("SDB_UNKNOWN_MESSAGE", 
		            rtnSDBMessage.getOperationCode());
		}
		int flags = rtnSDBMessage.getFlags();
		if (flags != 0) {
			throw new BaseException(flags, insertor.toString());
		}
		return tmp;
	}

	/**
	 * @fn Object insert(String insertor)
	 * @brief 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 Object the value of the filed "_id"
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public Object insert(String insertor) throws BaseException {
		BSONObject in = null;
		if (insertor != null)
			in = (BSONObject) JSON.parse(insertor);
		return insert(in);
	}

	/**
	 * @fn  void save(T type)
	 * @brief Insert an object into current collection
	 * @param type
	 *            The object of insertor, can't be null
	 * @exception com.sequoiadb.exception.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" 
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect. Because of current version is not support update shardingKey field.
	 * @see com.sequoiadb.base.DBCollection.setMainKeys
	 */
	public  void save(T type) throws BaseException
	{
		// transform java object to bson object
		BSONObject obj;
		try
		{
			obj = BasicBSONObject.typeToBson(type);
		}
		catch (Exception e)
		{
			throw new BaseException("SDB_INVALIDARG", type, 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(SequoiadbConstants.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(SequoiadbConstants.OID, id);
				// build rule
				modifer.put("$set", obj);
				upsert(matcher, modifer, null);
			}
		}
		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));
				else
					matcher.put(key, null);
			}
			// build rule
			modifer.put("$set", obj);
			upsert(matcher, modifer, null);
		}
	}
	
	/**
	 * @fn  void save(List type)
	 * @brief Insert an object into current collection
	 * @param type
	 *            The List instance of insertor, can't be null or empty
	 * @exception com.sequoiadb.exception.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 
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect. Because of current version is not support update shardingKey field.
	 * @see com.sequoiadb.base.DBCollection.setMainKeys
	 */
	public  void save(List type) throws BaseException {
		if (type == null || type.size() == 0)
			throw new BaseException("SDB_INVALIDARG", type);
		// 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()));
			}
		} catch (Exception e) {
			throw new BaseException("SDB_INVALIDARG", type, 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(SequoiadbConstants.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(SequoiadbConstants.OID, id);
					// build rule
					modifer.put("$set", obj);
					upsert(matcher, modifer, null);
				}
			}
		} 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));
					else
						matcher.put(key, null);
				}
				// build rule
				modifer.put("$set", obj);
				upsert(matcher, modifer, null);
			}
		}
	}
	
	/**
	 * @fn void bulkInsert(List insertor, int flag)
	 * @brief Insert a bulk of bson objects into current collection
	 * @param insertor
	 *            The Bson object of insertor list, can't be null
	 * @param flag  
	 *            available value is FLG_INSERT_CONTONDUP or 0.  
	 *            if flag = FLG_INSERT_CONTONDUP, bulkInsert will continue when Duplicate 
	 *            key exist.(the duplicate record will be ignored); 
     *            if flag = 0, bulkInsert will interrupt when Duplicate key exist.
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public void bulkInsert(List insertor, int flag)
			throws BaseException {

		if (flag != 0 && flag != FLG_INSERT_CONTONDUP)
			throw new BaseException("SDB_INVALIDARG");
		if (insertor == null || insertor.size() == 0)
			throw new BaseException("SDB_INVALIDARG");

		if (this.insert_buffer == null) {
			this.insert_buffer = IoBuffer.allocate(DEF_BULK_BUFFER_LENGTH);
			this.insert_buffer.setAutoExpand(true);
			if (sequoiadb.endianConvert) {
				insert_buffer.order(ByteOrder.LITTLE_ENDIAN);
			} else {
				insert_buffer.order(ByteOrder.BIG_ENDIAN);
			}
		} else {
			insert_buffer.clear();
		}

		int messageLength = SDBMessageHelper.buildBulkInsertRequest(
				insert_buffer, sequoiadb.getNextRequstID(), collectionFullName, 
				insertor, flag);

		connection.sendMessage(insert_buffer.array(), messageLength);
		
		ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert);
		SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer);
		if ( rtnSDBMessage.getOperationCode() != Operation.OP_INSERT_RES) {
            throw new BaseException("SDB_UNKNOWN_MESSAGE", 
                    rtnSDBMessage.getOperationCode());
        }
		int flags = rtnSDBMessage.getFlags();
		if (flags != 0)
			throw new BaseException(flags, insertor);
		// shrink the memory
		/*
		int capacity = insert_buffer.capacity();
		// if the capacity large then 16m, halves it
		if(capacity >= 8 * DEF_BULK_BUFFER_LENGTH) {
			insert_buffer.position(0);
			insert_buffer.limit(capacity/2);
		}
		else {
			insert_buffer.position(0);
			insert_buffer.limit(DEF_BULK_BUFFER_LENGTH);
		}
		insert_buffer.shrink();
		*/
	}

	/**
	 * @fn void delete(BSONObject matcher)
	 * @brief Delete the matching BSONObject of current collection
	 * @param matcher
	 *            The matching condition
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public void delete(BSONObject matcher) throws BaseException {
		delete(matcher, null);
	}

	/**
	 * @fn void delete(String matcher)
	 * @brief Delete the matching of current collection
	 * @param matcher
	 *            The matching condition
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public void delete(String matcher) throws BaseException {
		BSONObject ma = null;
		if (matcher != null)
			ma = (BSONObject) JSON.parse(matcher);
		delete(ma, null);
	}

	/**
	 * @fn void delete(String matcher, String hint)
	 * @brief Delete the matching bson's string of current collection
	 * @param matcher
	 *            The matching condition
	 * @param hint
	 *            Hint
	 * @exception com.sequoiadb.exception.BaseException
	 */
	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);
	}

	/**
	 * @fn void delete(BSONObject matcher, BSONObject hint)
	 * @brief Delete the matching BSONObject of current collection
	 * @param matcher
	 *            The matching condition
	 * @param hint
	 *            Hint
	 * @exception com.sequoiadb.exception.BaseException
	 */
	public void delete(BSONObject matcher, BSONObject hint)
			throws BaseException {
		BSONObject dummy = new BasicBSONObject();
		if (matcher == null)
			matcher = dummy;
		if (hint == null)
			hint = dummy;
		// Delete
		// long reqId = 0;
		SDBMessage sdbMessage = new SDBMessage();

		sdbMessage.setVersion(1);
		sdbMessage.setW((short) 0);
		sdbMessage.setPadding((short) 0);
		sdbMessage.setFlags(0);
		sdbMessage.setNodeID(SequoiadbConstants.ZERO_NODEID);
		// sdbMessage.setResponseTo(reqId);
		// reqId++;
		sdbMessage.setCollectionFullName(collectionFullName);
		sdbMessage.setRequestID(sequoiadb.getNextRequstID());
		sdbMessage.setMatcher(matcher);
		sdbMessage.setHint(hint);
		sdbMessage.setOperationCode(Operation.OP_DELETE);

		byte[] request = SDBMessageHelper.buildDeleteRequest(sdbMessage,
				sequoiadb.endianConvert);
		connection.sendMessage(request);
		
		ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert);
		SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer);
		SDBMessageHelper.checkMessage(sdbMessage, rtnSDBMessage);
		int flags = rtnSDBMessage.getFlags();
		if (flags != 0) {
			throw new BaseException(flags, matcher, hint);
		}
	}

	/**
	 * @fn void update(DBQuery query)
	 * @brief Update the document of current collection
	 * @param query
	 *            DBQuery with matching condition, updating rule and hint
	 * @exception com.sequoiadb.exception.BaseException
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect.
	 *       Because of current version is not support update shardingKey field.
	 */
	public void update(DBQuery query) throws BaseException {
		_update(0, query.getMatcher(), query.getModifier(), query.getHint());
	}

	/**
	 * @fn void update(BSONObject matcher, BSONObject modifier, BSONObject hint)
	 * @brief Update the BSONObject of current collection
	 * @param matcher
	 *            The matching condition
	 * @param modifier
	 *            The updating rule
	 * @param hint
	 *            Hint
	 * @exception com.sequoiadb.exception.BaseException
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect.
	 *       Because of current version is not support update shardingKey field.
	 */
	public void update(BSONObject matcher, BSONObject modifier, BSONObject hint)
			throws BaseException {
		_update(0, matcher, modifier, hint);
	}

	/**
	 * @fn void update(String matcher, String modifier, String hint)
	 * @brief Update the BSONObject of current collection
	 * @param matcher
	 *            The matching condition
	 * @param modifier
	 *            The updating rule
	 * @param hint
	 *            Hint
	 * @exception com.sequoiadb.exception.BaseException
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect.
	 *       Because of current version is not support update shardingKey field.
	 */
	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);
	}

	/**
	 * @fn void upsert(BSONObject matcher, BSONObject modifier, BSONObject hint)
	 * @brief Update the BSONObject of current collection, insert if no matching
	 * @param matcher
	 *            The matching condition
	 * @param modifier
	 *            The updating rule
	 * @param hint
	 *            Hint
	 * @exception com.sequoiadb.exception.BaseException
	 * @note when save include update shardingKey field, the shardingKey modify action is not take effect, but the other
	 *       field update is take effect.
	 *       Because of current version is not support update shardingKey field.
	 */
	public void upsert(BSONObject matcher, BSONObject modifier, BSONObject hint)
			throws BaseException {
		_update(SequoiadbConstants.FLG_UPDATE_UPSERT, matcher, modifier, hint);
	}
	
	/**
     * @fn DBCursor explain(BSONObject matcher, BSONObject selector,
            BSONObject orderBy, BSONObject hint, long skipRows, long returnRows,
            int flag, BSONObject options)
     * @brief Get explain 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
     *            the hint, automatically match the optimal hint if null
     * @param skipRows
     *            skip the first numToSkip documents, never skip if this parameter is 0
     * @param returnRows
     *            only return returnRows documents, return all if this parameter is -1
     * @param flag the flag is used to choose the way to query, the optional options are as below:
     *
    *
  • DBQuery.FLG_QUERY_STRINGOUT *
  • DBQuery.FLG_QUERY_FORCE_HINT *
  • DBQuery.FLG_QUERY_PARALLED *
  • DBQuery.FLG_QUERY_WITH_RETURNDATA *
  • DBQuery.FLG_QUERY_EXPLAIN *
* @param options The rules of query explain, the options are as below: *
    *
  • Run : Whether execute query explain or not, true for excuting query explain then get * the data and time information; false for not excuting query explain but get the * query explain information only. e.g. {Run:true} *
* @return a DBCursor instance of the result * @exception com.sequoiadb.exception.BaseException */ 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(SequoiadbConstants.FIELD_NAME_HINT, hint); } if ( null != options){ innerHint.put(SequoiadbConstants.FIELD_NAME_OPTIONS, options); } return query(matcher, selector, orderBy, innerHint, skipRows, returnRows, flag); } /** * @fn DBCursor query() * @brief Get all documents of current collection. * @return a DBCursor instance of the result * @exception com.sequoiadb.exception.BaseException */ public DBCursor query() throws BaseException { return query("", "", "", "", 0, -1); } /** * @fn DBCursor query(DBQuery matcher) * @brief 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 * @exception com.sequoiadb.exception.BaseException * @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()); } /** * @fn DBCursor query(BSONObject matcher, BSONObject selector, BSONObject * orderBy, BSONObject hint) * @brief 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 * the hint, automatically match the optimal hint if null * @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ public DBCursor query(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint) throws BaseException { return query(matcher, selector, orderBy, hint, 0, -1, 0); } /** * @fn DBCursor query(BSONObject matcher, BSONObject selector, BSONObject * orderBy, BSONObject hint, int flag) * @brief 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 * the hint, automatically match the optimal hint if null * @param flag * the flag is used to choose the way to query, the optional options are as below: *
    *
  • BDQuery.FLG_QUERY_STRINGOUT *
  • BDQuery.FLG_QUERY_FORCE_HINT *
  • BDQuery.FLG_QUERY_PARALLED *
* @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ public DBCursor query(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint, int flag) throws BaseException { return query(matcher, selector, orderBy, hint, 0, -1, flag); } /** * @fn DBCursor query(String matcher, String selector, String orderBy, String * hint) * @brief 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 * the hint, automatically match the optimal hint if null * @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ public DBCursor query(String matcher, String selector, String orderBy, String hint) throws BaseException { return query(matcher, selector, orderBy, hint, 0); } /** * @fn DBCursor query(String matcher, String selector, String orderBy, String * hint, int flag) * @brief 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 * the hint, automatically match the optimal hint if null * @param flag * the flag is used to choose the way to query, the optional options are as below: *
    *
  • BDQuery.FLG_QUERY_STRINGOUT *
  • BDQuery.FLG_QUERY_FORCE_HINT *
  • BDQuery.FLG_QUERY_PARALLED *
* @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ 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); } /** * @fn DBCursor query(String matcher, String selector, String orderBy, String hint, long skipRows, long returnRows) * @brief 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 * the hint, automatically match the optimal hint if null * @param skipRows * skip the first numToSkip documents, never skip if this parameter is 0 * @param returnRows * only return returnRows documents, return all if this parameter is -1 * @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ 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); } /** * @fn DBCursor query(BSONObject matcher, BSONObject selector, BSONObject * orderBy, BSONObject hint, long skipRows, long returnRows) * @brief 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 * the hint, automatically match the optimal hint if null * @param skipRows * skip the first numToSkip documents, never skip if this parameter is 0 * @param returnRows * only return returnRows documents, return all if this parameter is -1 * @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ 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); } /** * @fn DBCursor query(BSONObject matcher, BSONObject selector, * BSONObject orderBy, BSONObject hint, * long skipRows, long returnRows, * int flag) * @brief 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 * the hint, automatically match the optimal hint if null * @param skipRows * skip the first numToSkip documents, never skip if this parameter is 0 * @param returnRows * only return returnRows documents, return all if this parameter is -1 * @param flag the flag is used to choose the way to query, the optional options are as below: *
    *
  • DBQuery.FLG_QUERY_STRINGOUT *
  • DBQuery.FLG_QUERY_FORCE_HINT *
  • DBQuery.FLG_QUERY_PARALLED *
  • DBQuery.FLG_QUERY_WITH_RETURNDATA *
  • DBQuery.FLG_QUERY_EXPLAIN *
* @return a DBCursor instance of the result or null if no any matched document * @exception com.sequoiadb.exception.BaseException */ public DBCursor query(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint, long skipRows, long returnRows, int flag) throws BaseException { BSONObject dummy = new BasicBSONObject(); if (matcher == null) matcher = dummy; if (selector == null) selector = dummy; if (orderBy == null) orderBy = dummy; if (hint == null) hint = dummy; if (returnRows == 0) returnRows = -1; if ( returnRows == 1) { flag = flag | DBQuery.FLG_QUERY_WITH_RETURNDATA; } SDBMessage rtnSDBMessage = adminCommand(collectionFullName, matcher, selector, orderBy, hint, skipRows, returnRows, flag); DBCursor cursor = null; int flags = rtnSDBMessage.getFlags(); if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return null; } else { throw new BaseException(flags, matcher, selector, orderBy, hint, skipRows, returnRows); } } cursor = new DBCursor(rtnSDBMessage, this); return cursor; } /** * @fn BSONObject queryOne(BSONObject matcher, BSONObject selector, BSONObject * orderBy, BSONObject hint, int flag) * @brief Returns 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 * the hint, automatically match the optimal hint if null * @param flag the flag is used to choose the way to query, the optional options are as below: *
    *
  • BDQuery.FLG_QUERY_STRINGOUT *
  • BDQuery.FLG_QUERY_FORCE_HINT *
  • BDQuery.FLG_QUERY_PARALLED *
* @return the matched document or null if no such document * @exception com.sequoiadb.exception.BaseException */ public BSONObject queryOne(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint, int flag) throws BaseException { flag = flag | DBQuery.FLG_QUERY_WITH_RETURNDATA; DBCursor cursor = null; try { cursor = query(matcher, selector, orderBy, hint, 0, 1, flag); } catch (BaseException e) { throw e; } return cursor.getNext(); } /** * @fn BSONObject queryOne() * @brief Returns one document from current collection. * @return the document or null if no any document in current collection * @exception com.sequoiadb.exception.BaseException */ public BSONObject queryOne() throws BaseException { BSONObject empty = new BasicBSONObject(); return queryOne(empty, empty, empty, empty, 0); } /** * @fn DBCursor getIndexes() * @brief Get all the indexes of current collection * @return DBCursor of indexes * @exception com.sequoiadb.exception.BaseException */ public DBCursor getIndexes() throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.GET_INXES; BSONObject dummyObj = new BasicBSONObject(); BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); SDBMessage rtn = adminCommand(commandString, dummyObj, dummyObj, dummyObj, obj, -1, -1, 0); int flags = rtn.getFlags(); DBCursor cursor = null; if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return cursor; } else { throw new BaseException(flags); } } cursor = new DBCursor(rtn, sequoiadb); return cursor; } /** * @fn DBCursor getIndex(String name) * @brief 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 * @exception com.sequoiadb.exception.BaseException */ public DBCursor getIndex(String name) throws BaseException { if (name == null) return getIndexes(); String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.GET_INXES; BSONObject dummyObj = new BasicBSONObject(); BSONObject condition = new BasicBSONObject(); BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); condition.put(SequoiadbConstants.IXM_INDEXDEF + "." + SequoiadbConstants.IXM_NAME, name); SDBMessage rtn = adminCommand(commandString, condition, dummyObj, dummyObj, obj, -1, -1, 0); int flags = rtn.getFlags(); if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return null; } else { throw new BaseException(flags); } } return new DBCursor(rtn, this); } /** * @fn void createIndex(String name, BSONObject key, boolean isUnique, * boolean enforced) * @brief Create a index with name and key * @param name * The index name * @param key * The index key, like: {"key":1/-1}, ASC(1)/DESC(-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 * @exception com.sequoiadb.exception.BaseException */ public void createIndex(String name, BSONObject key, boolean isUnique, boolean enforced) throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CREATE_INX; BSONObject obj = new BasicBSONObject(); BSONObject dummyObj = new BasicBSONObject(); BSONObject createObj = new BasicBSONObject(); obj.put(SequoiadbConstants.IXM_KEY, key); obj.put(SequoiadbConstants.IXM_NAME, name); obj.put(SequoiadbConstants.IXM_UNIQUE, isUnique); obj.put(SequoiadbConstants.IXM_ENFORCED, enforced); createObj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); createObj.put(SequoiadbConstants.FIELD_INDEX, obj); SDBMessage rtn = adminCommand(commandString, createObj, dummyObj, dummyObj, dummyObj, -1, -1, 0); int flags = rtn.getFlags(); if (flags != 0) { throw new BaseException(flags, name, key, isUnique); } } /** * @fn void createIndex(String name, String key, boolean isUnique, boolean * enforced) * @brief Create a index with name and key * @param name * The index name * @param key * The index key, like: {"key":1/-1}, ASC(1)/DESC(-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 * @exception com.sequoiadb.exception.BaseException */ 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); } /** * @fn void dropIndex(String name) * @brief Remove the named index of current collection * @param name * The index name * @exception com.sequoiadb.exception.BaseException */ public void dropIndex(String name) throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.DROP_INX; BSONObject dummyObj = new BasicBSONObject(); BSONObject dropObj = new BasicBSONObject(); BSONObject index = new BasicBSONObject(); index.put("", name); dropObj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); dropObj.put(SequoiadbConstants.FIELD_INDEX, index); SDBMessage rtn = adminCommand(commandString, dropObj, dummyObj, dummyObj, dummyObj, -1, -1, 0); int flags = rtn.getFlags(); if (flags != 0) { throw new BaseException(flags, name); } } /** * @fn long getCount() * @brief Get the amount of documents in current collection. * @return the amount of matching documents * @exception com.sequoiadb.exception.BaseException */ public long getCount() throws BaseException { return getCount(""); } /** * @fn long getCount(String matcher) * @brief Get the amount of matching documnets in current collection. * @param matcher * the matching rule * @return the amount of matching documents * @exception com.sequoiadb.exception.BaseException */ public long getCount(String matcher) throws BaseException { BSONObject con = null; if (matcher != null) con = (BSONObject) JSON.parse(matcher); return getCount(con); } /** * @fn long getCount(BSONObject matcher) * @brief Get the amount of matching documents in current collection. * @param matcher * The matching rule * @return the amount of matching documents * @exception com.sequoiadb.exception.BaseException */ public long getCount(BSONObject matcher) throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.GET_COUNT; BSONObject dummyObj = new BasicBSONObject(); BSONObject newobj = new BasicBSONObject(); newobj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); SDBMessage rtnSDBMessage = adminCommand(commandString, matcher, dummyObj, dummyObj, newobj, -1, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) throw new BaseException(flags, matcher); List rtn = getMoreCommand(rtnSDBMessage); return Long.valueOf(rtn.get(0).get(SequoiadbConstants.FIELD_TOTAL) .toString()); } /** * @fn long getCount(BSONObject condition, BSONObject hint) * @brief Get the count of matching BSONObject in current collection * @param condition * The matching rule * @param hint * The hint, automatically match the optimal hint if null * @return The count of matching BSONObjects * @exception com.sequoiadb.exception.BaseException */ public long getCount(BSONObject condition, BSONObject hint) throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.GET_COUNT; BSONObject dummyObj = new BasicBSONObject(); BSONObject newobj = new BasicBSONObject(); newobj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); if (null != hint){ try{ newobj.put(SequoiadbConstants.FIELD_NAME_HINT, hint); }catch(Exception e){ throw new BaseException("SDB_SYS", e); } } SDBMessage rtnSDBMessage = adminCommand(commandString, condition, dummyObj, dummyObj, newobj, -1, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) throw new BaseException(flags, condition, hint); List rtn = getMoreCommand(rtnSDBMessage); return Long.valueOf(rtn.get(0).get(SequoiadbConstants.FIELD_TOTAL) .toString()); } /* * @fn void rename(String newName) * @brief rename the current collection by new name * @param newName * The new name of current DBCollection * @exception com.sequoiadb.exception.BaseException */ /* public void rename(String newName) throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.RENAME_COLLECTION; BSONObject dummyObj = new BasicBSONObject(); BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_NAME_COLLECTIONSPACE, csName); obj.put(SequoiadbConstants.FIELD_NAME_OLDNAME, this.name); obj.put(SequoiadbConstants.FIELD_NAME_NEWNAME, newName); SDBMessage rtnSDBMessage = adminCommand(commandString, obj, dummyObj, dummyObj, dummyObj, -1, -1); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { throw new BaseException(flags, newName); } this.name = newName; this.collectionFullName = csName + "." + this.name; }*/ /** * @fn void split(String sourceGroupName, String destGroupName, * BSONObject splitCondition, BSONObject splitEndCondition) * @brief 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 * eg:If we create a collection with the option {ShardingKey:{"age":1},ShardingType:"Hash",Partition:2^10}, * 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). * @exception com.sequoiadb.exception.BaseException */ public void split(String sourceGroupName, String destGroupName, BSONObject splitCondition, BSONObject splitEndCondition) throws BaseException { // check arguments if((null == sourceGroupName || sourceGroupName.equals("")) || (null == destGroupName || destGroupName.equals("")) || null == splitCondition){ throw new BaseException("SDB_INVALIDARG", sourceGroupName, destGroupName, splitCondition); } BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); obj.put(SequoiadbConstants.FIELD_NAME_SOURCE, sourceGroupName); obj.put(SequoiadbConstants.FIELD_NAME_TARGET, destGroupName); obj.put(SequoiadbConstants.FIELD_NAME_SPLITQUERY, splitCondition); if(null != splitEndCondition) obj.put(SequoiadbConstants.FIELD_NAME_SPLITENDQUERY, splitEndCondition); String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_SPLIT; BSONObject dummy = new BasicBSONObject(); SDBMessage rtnSDBMessage = adminCommand(commandString, obj, dummy, dummy, dummy, -1, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { throw new BaseException(flags, sourceGroupName, destGroupName, splitCondition, splitEndCondition); } } /** * @fn void split(String sourceGroupName, String destGroupName, double percent) * @brief 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] * @exception com.sequoiadb.exception.BaseException */ public void split(String sourceGroupName, String destGroupName, double percent) throws BaseException { // check arguments if((null == sourceGroupName || sourceGroupName.equals("")) || (null == destGroupName || destGroupName.equals("")) || (percent <= 0.0 || percent > 100.0)){ throw new BaseException("SDB_INVALIDARG", sourceGroupName, destGroupName, percent); } BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); obj.put(SequoiadbConstants.FIELD_NAME_SOURCE, sourceGroupName); obj.put(SequoiadbConstants.FIELD_NAME_TARGET, destGroupName); obj.put(SequoiadbConstants.FIELD_NAME_SPLITPERCENT, percent); String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_SPLIT; BSONObject dummy = new BasicBSONObject(); SDBMessage rtnSDBMessage = adminCommand(commandString, obj, dummy, dummy, dummy, -1, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { throw new BaseException(flags, sourceGroupName, destGroupName, percent); } } /** * @fn long splitAsync(String sourceGroupName, String destGroupName, * BSONObject splitCondition, BSONObject splitEndCondition) * @brief 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 * eg:If we create a collection with the option {ShardingKey:{"age":1},ShardingType:"Hash",Partition:2^10}, * we can fill {age:30} as the splitCondition, and fill {age:60} as the splitEndCondition. when split, * the targe 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 backgroup. * @exception com.sequoiadb.exception.BaseException * @see listTask, cancelTask */ public long splitAsync(String sourceGroupName, String destGroupName, BSONObject splitCondition, BSONObject splitEndCondition) throws BaseException { // check arguments if((null == sourceGroupName || sourceGroupName.equals("")) || (null == destGroupName || destGroupName.equals("")) || null == splitCondition){ throw new BaseException("SDB_INVALIDARG", sourceGroupName, destGroupName, splitCondition, splitEndCondition); } BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); obj.put(SequoiadbConstants.FIELD_NAME_SOURCE, sourceGroupName); obj.put(SequoiadbConstants.FIELD_NAME_TARGET, destGroupName); obj.put(SequoiadbConstants.FIELD_NAME_SPLITQUERY, splitCondition); if(null != splitEndCondition) obj.put(SequoiadbConstants.FIELD_NAME_SPLITENDQUERY, splitEndCondition); // async:true obj.put(SequoiadbConstants.FIELD_NAME_ASYNC, true); String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_SPLIT; BSONObject dummy = new BasicBSONObject(); SDBMessage rtnSDBMessage = adminCommand(commandString, obj, dummy, dummy, dummy, -1, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { throw new BaseException(flags, sourceGroupName, destGroupName, splitCondition, splitEndCondition); } // build cursor object to get result from database DBCursor cursor = new DBCursor(rtnSDBMessage, this); if (!cursor.hasNext()) throw new BaseException("SDB_CAT_TASK_NOTFOUND"); BSONObject result = cursor.getNext(); boolean flag = result.containsField(SequoiadbConstants.FIELD_NAME_TASKID); if (!flag) throw new BaseException("SDB_CAT_TASK_NOTFOUND"); long taskid = (Long)result.get(SequoiadbConstants.FIELD_NAME_TASKID); return taskid; } /** * @fn long splitAsync(String sourceGroupName, String destGroupName, double percent) * @brief 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 backgroup. * @exception com.sequoiadb.exception.BaseException */ public long splitAsync(String sourceGroupName, String destGroupName, double percent) throws BaseException { // check arguments if((null == sourceGroupName || sourceGroupName.equals("")) || (null == destGroupName || destGroupName.equals("")) || (percent <= 0.0 || percent > 100.0)){ throw new BaseException("SDB_INVALIDARG", sourceGroupName, destGroupName, percent); } BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); obj.put(SequoiadbConstants.FIELD_NAME_SOURCE, sourceGroupName); obj.put(SequoiadbConstants.FIELD_NAME_TARGET, destGroupName); obj.put(SequoiadbConstants.FIELD_NAME_SPLITPERCENT, percent); // async:true obj.put(SequoiadbConstants.FIELD_NAME_ASYNC, true); // command String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_SPLIT; BSONObject dummy = new BasicBSONObject(); SDBMessage rtnSDBMessage = adminCommand(commandString, obj, dummy, dummy, dummy, 0, -1, 0); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { throw new BaseException(flags, sourceGroupName, destGroupName, percent); } // build cursor object to get result from database DBCursor cursor = new DBCursor(rtnSDBMessage, this); if (!cursor.hasNext()) throw new BaseException("SDB_CAT_TASK_NOTFOUND"); BSONObject result = cursor.getNext(); boolean flag = result.containsField(SequoiadbConstants.FIELD_NAME_TASKID); if (!flag) throw new BaseException("SDB_CAT_TASK_NOTFOUND"); long taskid = (Long)result.get(SequoiadbConstants.FIELD_NAME_TASKID); return taskid; } /** * @fn DBCursor aggregate(List obj) * @brief Execute aggregate operation in current collection * @param obj * The Bson object of rule list, can't be null * @exception com.sequoiadb.exception.BaseException */ public DBCursor aggregate(List obj) throws BaseException { if (obj == null || obj.size() == 0) throw new BaseException("SDB_INVALIDARG"); if (this.insert_buffer == null) { this.insert_buffer = IoBuffer.allocate(DEF_BUFFER_LENGTH); this.insert_buffer.setAutoExpand(true); if (sequoiadb.endianConvert) { insert_buffer.order(ByteOrder.LITTLE_ENDIAN); } else { insert_buffer.order(ByteOrder.BIG_ENDIAN); } } else { insert_buffer.clear(); } int messageLength = SDBMessageHelper.buildAggrRequest(insert_buffer, sequoiadb.getNextRequstID(), collectionFullName, obj); connection.sendMessage(insert_buffer.array(), messageLength); ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert); SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer); if ( rtnSDBMessage.getOperationCode() != Operation.OP_AGGREGATE_RES) { throw new BaseException("SDB_UNKNOWN_MESSAGE", rtnSDBMessage.getOperationCode()); } DBCursor cursor = null; int flags = rtnSDBMessage.getFlags(); if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return cursor; } else { throw new BaseException(flags, obj); } } cursor = new DBCursor(rtnSDBMessage, this); return cursor; } /** * @fn DBCursor getQueryMeta(BSONObject query, BSONObject * orderBy, BSONObject hint, long skipRows, long returnRows) * @brief Get index blocks' or data blocks' infomation for concurrent query * @param query * The matching condition * @param orderBy * The ordered rule * @param hint * One of the indexs of current collection, * using default index to query if not provided * eg:{"":"ageIndex"} * @param skipRows * The rows to be skipped * @param returnRows * The rows to return * @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 datas * @exception com.sequoiadb.exception.BaseException * */ public DBCursor getQueryMeta(BSONObject query,BSONObject orderBy, BSONObject hint,long skipRows, long returnRows, int flag) throws BaseException { BSONObject dummy = new BasicBSONObject(); if (query == null) query = dummy; if (orderBy == null) orderBy = dummy; if (hint == null) hint = dummy; if (returnRows == 0) returnRows = -1; BSONObject hint1 = new BasicBSONObject(); hint1.put("Collection", this.collectionFullName); String command = SequoiadbConstants.ADMIN_PROMPT+SequoiadbConstants.GET_QUERYMETA; SDBMessage rtnSDBMessage = adminCommand(command, query, hint, orderBy, hint1, skipRows, returnRows, flag); DBCursor cursor = null; int flags = rtnSDBMessage.getFlags(); if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return cursor; } else { throw new BaseException(flags, query, hint, orderBy, hint1, skipRows, returnRows); } } cursor = new DBCursor(rtnSDBMessage, this); return cursor; } /** * @fn void attachCollection( String subClFullName,BSONObject options ) * @brief Attach the specified collection. * @param subClFullName * The full name of the subcollection * @param options * The low boudary and up boudary * eg: {"LowBound":{a:1},"UpBound":{a:100}} * @exception com.sequoiadb.exception.BaseException */ public void attachCollection( String subClFullName,BSONObject options ) throws BaseException { // check arguments if ( null == subClFullName || subClFullName.equals("") || null == options || null == collectionFullName || collectionFullName.equals("") ) { throw new BaseException("SDB_INVALIDARG", subClFullName, options, collectionFullName); } // command String command = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_ATTACH_CL; // build condition BSONObject newobj = new BasicBSONObject(); newobj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); newobj.put(SequoiadbConstants.FIELD_NAME_SUBCLNAME, subClFullName); for (String key : options.keySet()){ newobj.put(key, options.get(key)); } // build message/send/receive/extract SDBMessage rtnSDBMessage = adminCommand ( command, newobj, null, null, null, 0, -1, 0 ); int flags = rtnSDBMessage.getFlags(); if (0 != flags){ throw new BaseException(flags, subClFullName, options); } } /** * @fn void detachCollection( String subClFullName ) * @brief Dettach the specified collection. * @param subClFullName * The full name of the subcollection * @exception com.sequoiadb.exception.BaseException */ public void detachCollection( String subClFullName ) throws BaseException { // check arguments if ( null == subClFullName || subClFullName.equals("") || null == collectionFullName || collectionFullName.equals("") ) { throw new BaseException("SDB_INVALIDARG", subClFullName); } // command String command = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_DETACH_CL; // build condition BSONObject newobj = new BasicBSONObject(); newobj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); newobj.put(SequoiadbConstants.FIELD_NAME_SUBCLNAME, subClFullName); // build message/send/receive/extract SDBMessage rtnSDBMessage = adminCommand ( command, newobj, null, null, null, 0, -1, 0 ); int flags = rtnSDBMessage.getFlags(); if (0 != flags){ throw new BaseException(flags, subClFullName); } } /** * @fn void alterCollection ( BSONObject options ) * @brief Alter the attributes of current collection. * @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]. * e.g. {RepliSize:0, ShardingKey:{a:1}, ShardingType:"hash", Partition:1024} *
* @note Can't alter attributes about split in partition collection; After altering a collection to * be a partition collection, need to split this collection manually * @exception com.sequoiadb.exception.BaseException */ public void alterCollection( BSONObject options ) throws BaseException { // check arguments if ( null == options ) { throw new BaseException("SDB_INVALIDARG", options); } // command String command = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.CMD_NAME_ALTER_COLLECTION; // build condition BSONObject newobj = new BasicBSONObject(); newobj.put(SequoiadbConstants.FIELD_NAME_NAME, collectionFullName); newobj.put(SequoiadbConstants.FIELD_NAME_OPTIONS, options); // build message/send/receive/extract SDBMessage rtnSDBMessage = adminCommand ( command, newobj, null, null, null, 0, -1, 0 ); int flags = rtnSDBMessage.getFlags(); if (0 != flags){ throw new BaseException(flags, options); } } private SDBMessage adminCommand(String commandString, BSONObject query, BSONObject selector, BSONObject orderBy, BSONObject hint, long skipRows, long returnRows, int flag) throws BaseException { // Admin command request // int reqId = 0; SDBMessage sdbMessage = new SDBMessage(); BSONObject dummy = new BasicBSONObject(); if (query == null) query = dummy; if (selector == null) selector = dummy; if (orderBy == null) orderBy = dummy; if (hint == null) hint = dummy; sdbMessage.setCollectionFullName(commandString); sdbMessage.setVersion(1); sdbMessage.setW((short) 0); sdbMessage.setPadding((short) 0); sdbMessage.setFlags(flag); sdbMessage.setNodeID(SequoiadbConstants.ZERO_NODEID); // sdbMessage.setResponseTo(reqId); // reqId++; sdbMessage.setRequestID(sequoiadb.getNextRequstID()); sdbMessage.setSkipRowsCount(skipRows); sdbMessage.setReturnRowsCount(returnRows); sdbMessage.setMatcher(query); sdbMessage.setSelector(selector); sdbMessage.setOrderBy(orderBy); sdbMessage.setHint(hint); sdbMessage.setOperationCode(Operation.OP_QUERY); byte[] request = SDBMessageHelper.buildQueryRequest(sdbMessage, sequoiadb.endianConvert); connection.sendMessage(request); ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert); SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer); SDBMessageHelper.checkMessage(sdbMessage, rtnSDBMessage); return rtnSDBMessage; } private List getMoreCommand(SDBMessage rtnSDBMessage) throws BaseException { // GetMore request long reqId = rtnSDBMessage.getRequestID(); List contextIds = rtnSDBMessage.getContextIDList(); List fullList = new ArrayList(); boolean hasMore = true; while (hasMore) { SDBMessage sdbMessage = new SDBMessage(); sdbMessage.setNodeID(SequoiadbConstants.ZERO_NODEID); // sdbMessage.setResponseTo(reqId); // reqId++; sdbMessage.setContextIDList(contextIds); sdbMessage.setRequestID(reqId); sdbMessage.setNumReturned(-1); sdbMessage.setOperationCode(Operation.OP_GETMORE); byte[] request = SDBMessageHelper.buildGetMoreRequest(sdbMessage, sequoiadb.endianConvert); connection.sendMessage(request); ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert); rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer); SDBMessageHelper.checkMessage(sdbMessage, rtnSDBMessage); int flags = rtnSDBMessage.getFlags(); if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { hasMore = false; } else { throw new BaseException(flags); } } else { reqId = rtnSDBMessage.getRequestID(); List objList = rtnSDBMessage.getObjectList(); fullList.addAll(objList); } } return fullList; } private void _update(int flag, BSONObject matcher, BSONObject modifier, BSONObject hint) throws BaseException { BSONObject dummy = new BasicBSONObject(); if (matcher == null) matcher = dummy; if (modifier == null) modifier = dummy; if (hint == null) hint = dummy; SDBMessage sdbMessage = new SDBMessage(); sdbMessage.setVersion(1); sdbMessage.setW((short) 0); sdbMessage.setPadding((short) 0); sdbMessage.setFlags(flag); sdbMessage.setNodeID(SequoiadbConstants.ZERO_NODEID); sdbMessage.setCollectionFullName(collectionFullName); sdbMessage.setRequestID(sequoiadb.getNextRequstID()); sdbMessage.setMatcher(matcher); sdbMessage.setModifier(modifier); sdbMessage.setHint(hint); sdbMessage.setOperationCode(Operation.OP_UPDATE); byte[] request = SDBMessageHelper.buildUpdateRequest(sdbMessage, sequoiadb.endianConvert); connection.sendMessage(request); ByteBuffer byteBuffer = connection.receiveMessage(sequoiadb.endianConvert); SDBMessage rtnSDBMessage = SDBMessageHelper.msgExtractReply(byteBuffer); SDBMessageHelper.checkMessage(sdbMessage, rtnSDBMessage); int flags = rtnSDBMessage.getFlags(); if (flags != 0) throw new BaseException(flags, matcher, modifier, hint); } /** * @fn DBCursor listLobs() * @brief Get all of the lobs in current collection * @return DBCursor of lobs * @exception com.sequoiadb.exception.BaseException */ public DBCursor listLobs() throws BaseException { String commandString = SequoiadbConstants.ADMIN_PROMPT + SequoiadbConstants.LIST_LOBS; BSONObject dummyObj = new BasicBSONObject(); BSONObject obj = new BasicBSONObject(); obj.put(SequoiadbConstants.FIELD_COLLECTION, collectionFullName); SDBMessage rtn = adminCommand(commandString, obj, dummyObj, dummyObj, dummyObj, -1, -1, 0); int flags = rtn.getFlags(); DBCursor cursor = null; if (flags != 0) { if (flags == SequoiadbConstants.SDB_DMS_EOC) { return cursor; } else { throw new BaseException(flags); } } cursor = new DBCursor(rtn, sequoiadb); return cursor; } /** * @fn DBLob createLob() * @brief create a lob * @return DBLob object * @exception com.sequoiadb.exception.BaseException. */ public DBLob createLob() throws BaseException { return createLob( null ); } /** * @fn DBLob createLob( ObjectId id ) * @brief 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 * @exception com.sequoiadb.exception.BaseException. */ public DBLob createLob( ObjectId id ) throws BaseException { DBLobConcrete lob = new DBLobConcrete( this ); lob.open( id, DBLobConcrete.SDB_LOB_CREATEONLY ); return lob; } /** * @fn DBLob openLob( ObjectId id ) * @brief open an exist lob with id * @param id the lob's id. * @return DBLob object * @exception com.sequoiadb.exception.BaseException. */ public DBLob openLob( ObjectId id ) throws BaseException { DBLobConcrete lob = new DBLobConcrete( this ); lob.open( id, DBLobConcrete.SDB_LOB_READ ); return lob; } /** * @fn removeLob( ObjectId id ) * @brief remove an exist lob * @param id the lob's id. * @exception com.sequoiadb.exception.BaseException. */ public void removeLob( ObjectId lobID ) throws BaseException { BSONObject removeObj = new BasicBSONObject(); removeObj.put( SequoiadbConstants.FIELD_COLLECTION, collectionFullName ); removeObj.put( SequoiadbConstants.FIELD_NAME_LOB_OID, lobID ); byte[] request = SDBMessageHelper.generateRemoveLobRequest(removeObj, sequoiadb.getNextRequstID(), sequoiadb.endianConvert ); connection.sendMessage( request, request.length ); ByteBuffer res = connection.receiveMessage(sequoiadb.endianConvert); SDBMessage resMessage = SDBMessageHelper.msgExtractLobRemoveReply( res ); if ( resMessage.getOperationCode() != Operation.MSG_BS_LOB_REMOVE_RES) { throw new BaseException("SDB_UNKNOWN_MESSAGE", resMessage.getOperationCode()); } int flag = resMessage.getFlags(); if ( 0 != flag ) { throw new BaseException( flag, removeObj ); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy