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

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

There is a newer version: 5.10
Show newest version
/*
 * 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.MsgOpCode;
import com.sequoiadb.message.ResultSet;
import com.sequoiadb.message.request.*;
import com.sequoiadb.message.response.CommonResponse;
import com.sequoiadb.message.response.SdbReply;
import com.sequoiadb.message.response.SdbResponse;
import com.sequoiadb.message.response.SysInfoResponse;
import com.sequoiadb.net.IConnection;
import com.sequoiadb.net.ServerAddress;
import com.sequoiadb.net.TCPConnection;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.types.BasicBSONList;
import org.bson.types.Code;
import org.bson.util.JSON;

import java.io.Closeable;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.*;

/**
 * The connection with SequoiaDB server.
 */
public class Sequoiadb implements Closeable {
    private InetSocketAddress socketAddress;
    private IConnection connection;
    private String userName;
    private String password;
    private ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
    private long requestId;
    private long lastUseTime;

    // cache cs/cl name
    private Map nameCache = new HashMap();
    private static boolean enableCache = true;
    private static long cacheInterval = 300 * 1000;
    private BSONObject attributeCache = null;

    private final static String DEFAULT_HOST = "127.0.0.1";
    private final static int DEFAULT_PORT = 11810;

    /**
     * specified the package size of the collections in current collection space to be 4K
     */
    public final static int SDB_PAGESIZE_4K = 4096;
    /**
     * specified the package size of the collections in current collection space to be 8K
     */
    public final static int SDB_PAGESIZE_8K = 8192;
    /**
     * specified the package size of the collections in current collection space to be 16K
     */
    public final static int SDB_PAGESIZE_16K = 16384;
    /**
     * specified the package size of the collections in current collection space to be 32K
     */
    public final static int SDB_PAGESIZE_32K = 32768;
    /**
     * specified the package size of the collections in current collection space to be 64K
     */
    public final static int SDB_PAGESIZE_64K = 65536;
    /**
     * 0 means using database's default pagesize, it 64k now
     */
    public final static int SDB_PAGESIZE_DEFAULT = 0;

    public final static int SDB_LIST_CONTEXTS = 0;
    public final static int SDB_LIST_CONTEXTS_CURRENT = 1;
    public final static int SDB_LIST_SESSIONS = 2;
    public final static int SDB_LIST_SESSIONS_CURRENT = 3;
    public final static int SDB_LIST_COLLECTIONS = 4;
    public final static int SDB_LIST_COLLECTIONSPACES = 5;
    public final static int SDB_LIST_STORAGEUNITS = 6;
    public final static int SDB_LIST_GROUPS = 7;
    public final static int SDB_LIST_STOREPROCEDURES = 8;
    public final static int SDB_LIST_DOMAINS = 9;
    public final static int SDB_LIST_TASKS = 10;
    public final static int SDB_LIST_TRANSACTIONS = 11;
    public final static int SDB_LIST_TRANSACTIONS_CURRENT = 12;
    public final static int SDB_LIST_SVCTASKS = 14;
    public final static int SDB_LIST_SEQUENCES = 15;
    public final static int SDB_LIST_USERS = 16;
    public final static int SDB_LIST_CL_IN_DOMAIN = 129;
    public final static int SDB_LIST_CS_IN_DOMAIN = 130;

    public final static int SDB_SNAP_CONTEXTS = 0;
    public final static int SDB_SNAP_CONTEXTS_CURRENT = 1;
    public final static int SDB_SNAP_SESSIONS = 2;
    public final static int SDB_SNAP_SESSIONS_CURRENT = 3;
    public final static int SDB_SNAP_COLLECTIONS = 4;
    public final static int SDB_SNAP_COLLECTIONSPACES = 5;
    public final static int SDB_SNAP_DATABASE = 6;
    public final static int SDB_SNAP_SYSTEM = 7;
    public final static int SDB_SNAP_CATALOG = 8;
    public final static int SDB_SNAP_TRANSACTIONS = 9;
    public final static int SDB_SNAP_TRANSACTIONS_CURRENT = 10;
    public final static int SDB_SNAP_ACCESSPLANS = 11;
    public final static int SDB_SNAP_HEALTH = 12;
    public final static int SDB_SNAP_CONFIGS = 13;
    public final static int SDB_SNAP_SVCTASKS = 14;
    public final static int SDB_SNAP_SEQUENCES = 15;


    public final static int FMP_FUNC_TYPE_INVALID = -1;
    public final static int FMP_FUNC_TYPE_JS = 0;
    public final static int FMP_FUNC_TYPE_C = 1;
    public final static int FMP_FUNC_TYPE_JAVA = 2;

    public final static String CATALOG_GROUP_NAME = "SYSCatalogGroup";

    void upsertCache(String name) {
        if (name == null)
            return;
        if (enableCache) {
            long current = System.currentTimeMillis();
            nameCache.put(name, current);
            String[] arr = name.split("\\.");
            if (arr.length > 1) {
                // extract cs name from cl full name and that
                // upsert cs name
                nameCache.put(arr[0], current);
            }
        }
    }

    void removeCache(String name) {
        if (name == null)
            return;
        String[] arr = name.split("\\.");
        if (arr.length == 1) {
            // when we come here, "name" is a cs name, so
            // we are going to remove the cache of the cs
            // and the cache of the cls

            // remove cs cache
            // name may be "foo.", it's a invalid name,
            // we don't want to remove anything,
            // so we use "name" but not "arr[0]" here
            nameCache.remove(name);
            Set keySet = nameCache.keySet();
            List list = new ArrayList();
            for (String str : keySet) {
                String[] nameArr = str.split("\\.");
                if (nameArr.length > 1 && nameArr[0].equals(name))
                    list.add(str);
            }
            if (list.size() != 0) {
                for (String str : list)
                    nameCache.remove(str);
            }
        } else {
            // we are going to remove the cache of the cl
            nameCache.remove(name);
        }
    }

    boolean fetchCache(String name) {
        if (enableCache) {
            if (nameCache.containsKey(name)) {
                long lastUpdatedTime = nameCache.get(name);
                if ((System.currentTimeMillis() - lastUpdatedTime) >= cacheInterval) {
                    nameCache.remove(name);
                    return false;
                } else {
                    return true;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * Initialize the configuration options for client.
     *
     * @param options the configuration options for client
     */
    public static void initClient(ClientOptions options) {
        enableCache = (options != null) ? options.getEnableCache() : true;
        cacheInterval = (options != null && options.getCacheInterval() >= 0) ? options.getCacheInterval() : 300 * 1000;
    }

    /**
     * Get address of the remote server.
     *
     * @return ServerAddress
     * @deprecated Use Sequoiadb.getHost() and Sequoiadb.getPort() instead.
     */
    @Deprecated
    public ServerAddress getServerAddress() {
        return new ServerAddress(socketAddress);
    }

    /**
     * @return Host name of SequoiaDB server.
     */
    public String getHost() {
        return socketAddress.getHostName();
    }

    /**
     * @return IP address of SequoiaDB server.
     */
    public String getIP() {
        return socketAddress.getAddress().getHostAddress();
    }

    /**
     * @return Service port of SequoiaDB server.
     */
    public int getPort() {
        return socketAddress.getPort();
    }

    /**
     * @return the node name of current coord node in format of "ip:port".
     */
    public String getNodeName() {
        return getIP() + ":" + getPort();
    }

    /**
     * @return the socket address of remote host.
     */
    public String getRemoteAddress() {
        if (connection == null) {
            return null;
        }
        return connection.getRemoteAddress();
    }

    /**
     * @return the socket address of localhost.
     */
    public String getLocalAddress() {
        if (connection == null) {
            return null;
        }
        return connection.getLocalAddress();
    }

    @Override
    public String toString() {
        return String.format("%s:%d", getHost(), getPort());
    }

    /**
     * Judge the endian of the physical computer
     *
     * @return Big-Endian is true while Little-Endian is false
     * @deprecated Use getByteOrder() instead.
     */
    @Deprecated
    public boolean isEndianConvert() {
        return byteOrder == ByteOrder.BIG_ENDIAN;
    }

    /**
     * @return ByteOrder of SequoiaDB server.
     * @since 2.9
     */
    public ByteOrder getByteOrder() {
        return byteOrder;
    }

    /**
     * @return The last used time of this connection.
     * @since 2.9
     */
    public long getLastUseTime() {
        return lastUseTime;
    }

    /**
     * Use server address "127.0.0.1:11810".
     *
     * @param username the user's name of the account
     * @param password the password of the account
     * @throws BaseException SDB_NETWORK means network error,
     *                       SDB_INVALIDARG means wrong address or the address don't map to the hosts table.
     * @deprecated do not use this Constructor, should provide server address explicitly
     */
    @Deprecated
    public Sequoiadb(String username, String password) throws BaseException {
        this(DEFAULT_HOST, DEFAULT_PORT, username, password, null);
    }

    /**
     * @param connString remote server address "Host:Port"
     * @param username   the user's name of the account
     * @param password   the password of the account
     * @throws BaseException SDB_NETWORK means network error,
     *                       SDB_INVALIDARG means wrong address or the address don't map to the hosts table
     */
    public Sequoiadb(String connString, String username, String password)
            throws BaseException {
        this(connString, username, password, (ConfigOptions) null);
    }

    /**
     * @param connString remote server address "Host:Port"
     * @param username   the user's name of the account
     * @param password   the password of the account
     * @param options    the options for connection
     * @throws BaseException SDB_NETWORK means network error,
     *                       SDB_INVALIDARG means wrong address or the address don't map to the hosts table.
     */
    public Sequoiadb(String connString, String username, String password,
                     ConfigOptions options) throws BaseException {
        init(connString, username, password, options);
    }

    /**
     * @deprecated Use com.sequoiadb.base.ConfigOptions instead of com.sequoiadb.net.ConfigOptions.
     */
    @Deprecated
    public Sequoiadb(String connString, String username, String password,
                     com.sequoiadb.net.ConfigOptions options) throws BaseException {
        this(connString, username, password, (ConfigOptions) options);
    }

    /**
     * Use a random valid address to connect to database.
     *
     * @param connStrings The array of the coord's address.
     * @param username    The user's name of the account.
     * @param password    The password of the account.
     * @param options     The options for connection.
     * @throws BaseException If error happens.
     */
    public Sequoiadb(List connStrings, String username, String password,
                     ConfigOptions options) throws BaseException {
        if (connStrings == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG, "connStrings is null");
        }

        List list = new ArrayList();
        for (String str : connStrings) {
            if (str != null && !str.isEmpty()) {
                list.add(str);
            }
        }

        if (0 == list.size()) {
            throw new BaseException(SDBError.SDB_INVALIDARG, "Address list has no valid address");
        }

        if (options == null) {
            options = new ConfigOptions();
        }

        Random random = new Random();
        while (list.size() > 0) {
            int index = random.nextInt(list.size());
            String str = list.get(index);
            try {
                init(str, username, password, options);
                return;
            } catch (BaseException e) {
                if (e.getErrorCode() == SDBError.SDB_AUTH_AUTHORITY_FORBIDDEN.getErrorCode()) {
                    throw e;
                }
                list.remove(index);
            }
        }

        throw new BaseException(SDBError.SDB_NET_CANNOT_CONNECT, "No valid address");
    }

    /**
     * @deprecated Use com.sequoiadb.base.ConfigOptions instead of com.sequoiadb.net.ConfigOptions.
     */
    @Deprecated
    public Sequoiadb(List connStrings, String username, String password,
                     com.sequoiadb.net.ConfigOptions options) throws BaseException {
        this(connStrings, username, password, (ConfigOptions) options);
    }

    /**
     * @param host     the address of coord
     * @param port     the port of coord
     * @param username the user's name of the account
     * @param password the password of the account
     * @throws BaseException SDB_NETWORK means network error,
     *                       SDB_INVALIDARG means wrong address or the address don't map to the hosts table.
     */
    public Sequoiadb(String host, int port, String username, String password)
            throws BaseException {
        this(host, port, username, password, null);
    }

    /**
     * @param host     the address of coord
     * @param port     the port of coord
     * @param username the user's name of the account
     * @param password the password of the account
     * @throws BaseException SDB_NETWORK means network error,
     *                       SDB_INVALIDARG means wrong address or the address don't map to the hosts table.
     */
    public Sequoiadb(String host, int port,
                     String username, String password,
                     ConfigOptions options) throws BaseException {
        init(host, port, username, password, options);
    }

    /**
     * @deprecated Use com.sequoiadb.base.ConfigOptions instead of com.sequoiadb.net.ConfigOptions.
     */
    @Deprecated
    public Sequoiadb(String host, int port,
                     String username, String password,
                     com.sequoiadb.net.ConfigOptions options) throws BaseException {
        this(host, port, username, password, (ConfigOptions) options);
    }

    private void init(String host, int port,
                      String username, String password,
                      ConfigOptions options) throws BaseException {
        if (host == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG, "host is null");
        }

        if (options == null) {
            options = new ConfigOptions();
        }

        socketAddress = new InetSocketAddress(host, port);
        connection = new TCPConnection(socketAddress, options);
        connection.connect();

        byteOrder = getSysInfo();
        authenticate(username, password);

        this.userName = username;
        this.password = password;
    }

    private void init(String connString, String username, String password,
                      ConfigOptions options) {
        if (connString == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG, "connString is null");
        }

        String host;
        int port;

        if (connString.indexOf(":") > 0) {
            String[] tmp = connString.split(":");
            if (tmp.length != 2) {
                throw new BaseException(SDBError.SDB_INVALIDARG,
                        String.format("Invalid connString: %s", connString));
            }
            host = tmp[0].trim();
            port = Integer.parseInt(tmp[1].trim());
        } else {
            throw new BaseException(SDBError.SDB_INVALIDARG,
                    String.format("Invalid connString: %s", connString));
        }

        init(host, port, username, password, options);
    }

    private void authenticate(String username, String password) {
        AuthRequest request = new AuthRequest(username, password, AuthRequest.AuthType.Verify);
        SdbReply response = requestAndResponse(request);

        try {
            throwIfError(response, "failed to authenticate " + userName);
        } catch (BaseException e) {
            close();
            throw e;
        }
    }

    /**
     * Create an user in current database.
     *
     * @param username The connection user name
     * @param password The connection password
     * @throws BaseException If error happens.
     */
    public void createUser(String username, String password) throws BaseException {
        if (username == null || username.length() == 0 || password == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG);
        }

        AuthRequest request = new AuthRequest(username, password, AuthRequest.AuthType.CreateUser);
        SdbReply response = requestAndResponse(request);
        throwIfError(response, username);
    }

    /**
     * Remove the specified user from current database.
     *
     * @param username The connection user name
     * @param password The connection password
     * @throws BaseException If error happens.
     */
    public void removeUser(String username, String password) throws BaseException {
        AuthRequest request = new AuthRequest(username, password, AuthRequest.AuthType.DeleteUser);
        SdbReply response = requestAndResponse(request);
        throwIfError(response, username);
    }

    /**
     * Disconnect from the server.
     *
     * @throws BaseException If error happens.
     * @deprecated Use close() instead.
     */
    @Deprecated
    public void disconnect() throws BaseException {
        close();
    }

    /**
     * Release the resource of the connection.
     *
     * @throws BaseException If error happens.
     * @since 2.2
     */
    public void releaseResource() throws BaseException {
        // let the receive buffer shrink to default value
        closeAllCursors();
        attributeCache = null;
    }

    /**
     * Whether the connection has been closed or not.
     *
     * @return return true when the connection has been closed
     * @since 2.2
     */
    public boolean isClosed() {
        if (connection == null) {
            return true;
        }
        return connection.isClosed();
    }

    /**
     * Send a test message to database to test whether the connection is valid or not.
     *
     * @return if the connection is valid, return true
     * @throws BaseException If error happens.
     */
    public boolean isValid() throws BaseException {
        // client not connect to database or client
        // disconnect from database
        if (isClosed()) {
            return false;
        }

        try {
            killContext();
        } catch (BaseException e) {
            return false;
        }
        return true;
    }

    /**
     * Change the connection options.
     *
     * @param options The connection options
     * @throws BaseException If error happens.
     * @deprecated Create a new Sequoiadb instance instead..
     */
    @Deprecated
    public void changeConnectionOptions(ConfigOptions options)
            throws BaseException {
        if (options == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG, "options is null");
        }
        close();
        init(getHost(), getPort(), userName, password, options);
    }

    /**
     * Create the named collection space with default SDB_PAGESIZE_64K.
     *
     * @param csName The collection space name
     * @return the newly created collection space object
     * @throws BaseException If error happens.
     */
    public CollectionSpace createCollectionSpace(String csName)
            throws BaseException {
        return createCollectionSpace(csName, SDB_PAGESIZE_DEFAULT);
    }

    /**
     * Create collection space.
     *
     * @param csName   The name of collection space
     * @param pageSize The Page Size as below:
     *                 
    *
  • SDB_PAGESIZE_4K *
  • SDB_PAGESIZE_8K *
  • SDB_PAGESIZE_16K *
  • SDB_PAGESIZE_32K *
  • SDB_PAGESIZE_64K *
  • SDB_PAGESIZE_DEFAULT *
* @return the newly created collection space object * @throws BaseException If error happens. */ public CollectionSpace createCollectionSpace(String csName, int pageSize) throws BaseException { BSONObject options = new BasicBSONObject(); options.put("PageSize", pageSize); return createCollectionSpace(csName, options); } /** * Create collection space. * * @param csName The name of collection space * @param options Contains configuration information for create collection space. The options are as below: *
    *
  • PageSize : Assign how large the page size is for the collection created in this collection space, default to be 64K *
  • Domain : Assign which domain does current collection space belong to, it will belongs to the system domain if not assign this option *
* @return the newly created collection space object * @throws BaseException If error happens. */ public CollectionSpace createCollectionSpace(String csName, BSONObject options) throws BaseException { if (csName == null || csName.length() == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, csName); } BSONObject obj = new BasicBSONObject(); obj.put(SdbConstants.FIELD_NAME_NAME, csName); if (null != options) { obj.putAll(options); } AdminRequest request = new AdminRequest(AdminCommand.CREATE_CS, obj); SdbReply response = requestAndResponse(request); throwIfError(response); upsertCache(csName); return new CollectionSpace(this, csName); } /** * Remove the named collection space. * * @param csName The collection space name * @throws BaseException If error happens. */ public void dropCollectionSpace(String csName) throws BaseException { if (csName == null || csName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "cs name can not be null or empty"); } BSONObject options = new BasicBSONObject(); options.put(SdbConstants.FIELD_NAME_NAME, csName); AdminRequest request = new AdminRequest(AdminCommand.DROP_CS, options); SdbReply response = requestAndResponse(request); throwIfError(response); removeCache(csName); } /** * @param csName The collection space name * @param options The control options:(Only take effect in coordinate nodes, can be null) *
    *
  • GroupID:int
  • *
  • GroupName:String
  • *
  • NodeID:int
  • *
  • HostName:String
  • *
  • svcname:String
  • *
  • ...
  • *
* @throws BaseException If error happens. * @since 2.8 */ public void loadCollectionSpace(String csName, BSONObject options) throws BaseException { if (csName == null || csName.length() == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, csName); } BSONObject newOptions = new BasicBSONObject(); newOptions.put(SdbConstants.FIELD_NAME_NAME, csName); if (options != null) { newOptions.putAll(options); } AdminRequest request = new AdminRequest(AdminCommand.LOAD_CS, newOptions); SdbReply response = requestAndResponse(request); throwIfError(response); upsertCache(csName); } /** * @param csName The collection space name * @param options The control options:(Only take effect in coordinate nodes, can be null) *
    *
  • GroupID:int
  • *
  • GroupName:String
  • *
  • NodeID:int
  • *
  • HostName:String
  • *
  • svcname:String
  • *
  • ...
  • *
* @throws BaseException If error happens. * @since 2.8 */ public void unloadCollectionSpace(String csName, BSONObject options) throws BaseException { if (csName == null || csName.length() == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, csName); } BSONObject newOptions = new BasicBSONObject(); newOptions.put(SdbConstants.FIELD_NAME_NAME, csName); if (options != null) { newOptions.putAll(options); } AdminRequest request = new AdminRequest(AdminCommand.UNLOAD_CS, newOptions); SdbReply response = requestAndResponse(request); throwIfError(response); removeCache(csName); } /** * @param oldName The old collection space name * @param newName The new collection space name * @throws BaseException If error happens. * @since 2.8 */ public void renameCollectionSpace(String oldName, String newName) throws BaseException { if (oldName == null || oldName.length() == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, "The old name of collection space is null or empty"); } if (newName == null || newName.length() == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, "The new name of collection space is null or empty"); } BSONObject matcher = new BasicBSONObject(); matcher.put(SdbConstants.FIELD_NAME_OLDNAME, oldName); matcher.put(SdbConstants.FIELD_NAME_NEWNAME, newName); AdminRequest request = new AdminRequest(AdminCommand.RENAME_CS, matcher); SdbReply response = requestAndResponse(request); throwIfError(response); removeCache(oldName); upsertCache(newName); } /** * Sync the database to disk. * * @param options The control options:(can be null) *
    *
  • * Deep:int * Flush with deep mode or not. 1 in default. * 0 for non-deep mode,1 for deep mode,-1 means use the configuration with server *
  • *
  • * Block:boolean * Flush with block mode or not. false in default. *
  • *
  • * CollectionSpace:String * Specify the collectionspace to sync. * If not set, will sync all the collection spaces and logs, * otherwise, will only sync the collection space specified. *
  • *
  • * Some of other options are as below:(only take effect in coordinate nodes, * please visit the official website to search "sync" or * "Location Elements" for more detail.) * GroupID:int, * GroupName:String, * NodeID:int, * HostName:String, * svcname:String * ... *
  • *
* @throws BaseException If error happens. * @since 2.8 */ public void sync(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.SYNC_DB, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Sync the whole database to disk. * * @throws BaseException If error happens. * @since 2.8 */ public void sync() throws BaseException { sync(null); } /** * Analyze collection or index to collect statistics information * * @param options The control options:(can be null) *
    *
  • * CollectionSpace: (String) Specify the collection space to be analyzed. *
  • *
  • * Collection: (String) Specify the collection to be analyzed. *
  • *
  • * Index: (String) Specify the index to be analyzed. *
  • *
  • * Mode: (Int32) Specify the analyze mode (default is 1): *
      *
    • Mode 1 will analyze with data samples.
    • *
    • Mode 2 will analyze with full data.
    • *
    • Mode 3 will generate default statistics.
    • *
    • Mode 4 will reload statistics into memory cache.
    • *
    • Mode 5 will clear statistics from memory cache.
    • *
    *
  • *
  • * Other options: Some of other options are as below:(only take effect in coordinate nodes, * please visit the official website to search "analyze" or "Location Elements" for more detail.) * GroupID:int, GroupName:String, NodeID:int, HostName:String, svcname:String, ... *
  • *
* @throws BaseException If error happens. * @since 2.9 */ public void analyze(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.ANALYZE, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Analyze all collections and indexes to collect statistics information * * @throws BaseException If error happens. * @since 2.9 */ public void analyze() throws BaseException { analyze(null); } /** * Get the named collection space. * If the collection space not exit, throw BaseException with errcode SDB_DMS_CS_NOTEXIST. * * @param csName The collection space name. * @return the object of the specified collection space, or an exception when the collection space does not exist. * @throws BaseException If error happens. */ public CollectionSpace getCollectionSpace(String csName) throws BaseException { if (csName == null || csName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "cs name can not be null or empty"); } // get cs object from cache if (fetchCache(csName)) { return new CollectionSpace(this, csName); } BSONObject options = new BasicBSONObject(); options.put(SdbConstants.FIELD_NAME_NAME, csName); AdminRequest request = new AdminRequest(AdminCommand.TEST_CS, options); SdbReply response = requestAndResponse(request); throwIfError(response, csName); upsertCache(csName); return new CollectionSpace(this, csName); } /** * Verify the existence of collection space. * * @param csName The collection space name. * @return True if existed or false if not existed. * @throws BaseException If error happens. */ public boolean isCollectionSpaceExist(String csName) throws BaseException { if (csName == null || csName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "cs name can not be null or empty"); } BSONObject options = new BasicBSONObject(); options.put(SdbConstants.FIELD_NAME_NAME, csName); AdminRequest request = new AdminRequest(AdminCommand.TEST_CS, options); SdbReply response = requestAndResponse(request); int flag = response.getFlag(); if (flag == 0) { upsertCache(csName); return true; } else if (flag == SDBError.SDB_DMS_CS_NOTEXIST.getErrorCode()) { removeCache(csName); return false; } else { throwIfError(response, csName); return false; // make compiler happy } } /** * Get all the collection spaces. * * @return Cursor of all collection space names. * @throws BaseException If error happens. */ public DBCursor listCollectionSpaces() throws BaseException { return getList(SDB_LIST_COLLECTIONSPACES, null, null, null); } /** * Get all the collection space names. * * @return A list of all collection space names * @throws BaseException If error happens. */ public ArrayList getCollectionSpaceNames() throws BaseException { DBCursor cursor = getList(SDB_LIST_COLLECTIONSPACES, null, null, null); if (cursor == null) { return null; } ArrayList colList = new ArrayList(); try { while (cursor.hasNext()) { colList.add(cursor.getNext().get("Name").toString()); } } finally { cursor.close(); } return colList; } /** * Get all the collections. * * @return Cursor of all collections * @throws BaseException If error happens. */ public DBCursor listCollections() throws BaseException { return getList(SDB_LIST_COLLECTIONS, null, null, null); } /** * Get all the collection names. * * @return A list of all collection names * @throws BaseException If error happens. */ public ArrayList getCollectionNames() throws BaseException { DBCursor cursor = getList(SDB_LIST_COLLECTIONS, null, null, null); if (cursor == null) { return null; } ArrayList colList = new ArrayList(); try { while (cursor.hasNext()) { colList.add(cursor.getNext().get("Name").toString()); } } finally { cursor.close(); } return colList; } /** * Get all the storage units. * * @return A list of all storage units * @throws BaseException If error happens. */ public ArrayList getStorageUnits() throws BaseException { DBCursor cursor = getList(SDB_LIST_STORAGEUNITS, null, null, null); if (cursor == null) { return null; } ArrayList colList = new ArrayList(); try { while (cursor.hasNext()) { colList.add(cursor.getNext().get("Name").toString()); } } finally { cursor.close(); } return colList; } /** * Reset the snapshot. * * @throws BaseException If error happens. */ public void resetSnapshot() throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.RESET_SNAPSHOT); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Reset the snapshot. * * @param options The control options:(can be null) *
    *
  • * Type: (String) Specify the snapshot type to be reset (default is "all"): *
      *
    • "sessions"
    • *
    • "sessions current"
    • *
    • "database"
    • *
    • "health"
    • *
    • "all"
    • *
    *
  • *
  • * SessionID: (Int32) Specify the session ID to be reset. *
  • *
  • * Other options: Some of other options are as below:(please visit the official website to * search "Location Elements" for more detail.) *
      *
    • GroupID:int,
    • *
    • GroupName:String,
    • *
    • NodeID:int,
    • *
    • HostName:String,
    • *
    • svcname:String,
    • *
    • ...
    • *
    *
  • *
* @throws BaseException If error happens. */ public void resetSnapshot(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.RESET_SNAPSHOT, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Get the information of specified type. * * @param listType The list type as below: *
*
Sequoiadb.SDB_LIST_CONTEXTS : Get all contexts list *
Sequoiadb.SDB_LIST_CONTEXTS_CURRENT : Get contexts list for the current session *
Sequoiadb.SDB_LIST_SESSIONS : Get all sessions list *
Sequoiadb.SDB_LIST_SESSIONS_CURRENT : Get the current session *
Sequoiadb.SDB_LIST_COLLECTIONS : Get all collections list *
Sequoiadb.SDB_LIST_COLLECTIONSPACES : Get all collection spaces list *
Sequoiadb.SDB_LIST_STORAGEUNITS : Get storage units list *
Sequoiadb.SDB_LIST_GROUPS : Get replica group list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_STOREPROCEDURES : Get stored procedure list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_DOMAINS : Get all the domains list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_TASKS : Get all the running split tasks ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_TRANSACTIONS : Get all the transactions information. *
Sequoiadb.SDB_LIST_TRANSACTIONS_CURRENT : Get the transactions information of current session. *
Sequoiadb.SDB_LIST_SVCTASKS : Get all the schedule task information *
Sequoiadb.SDB_LIST_SEQUENCES : Get the information of sequences *
Sequoiadb.SDB_LIST_USERS : Get all the user information. *
* @param query The matching rule, match 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 options provided for specific list type. Reserved. * @param skipRows Skip the first skipRows documents. * @param returnRows Only return returnRows documents. -1 means return all matched results. * @return The target information by cursor. * @throws BaseException If error happens. */ public DBCursor getList(int listType, BSONObject query, BSONObject selector, BSONObject orderBy, BSONObject hint, long skipRows, long returnRows) throws BaseException { String command = getListCommand(listType); AdminRequest request = new AdminRequest(command, query, selector, orderBy, hint, skipRows, returnRows); SdbReply response = requestAndResponse(request); int flags = response.getFlag(); if (flags != 0 && flags != SDBError.SDB_DMS_EOC.getErrorCode()) { String msg = "query = " + query + ", selector = " + selector + ", orderBy = " + orderBy; throwIfError(response, msg); } return new DBCursor(response, this); } /** * Get the information of specified type. * * @param listType The list type as below: *
*
Sequoiadb.SDB_LIST_CONTEXTS : Get all contexts list *
Sequoiadb.SDB_LIST_CONTEXTS_CURRENT : Get contexts list for the current session *
Sequoiadb.SDB_LIST_SESSIONS : Get all sessions list *
Sequoiadb.SDB_LIST_SESSIONS_CURRENT : Get the current session *
Sequoiadb.SDB_LIST_COLLECTIONS : Get all collections list *
Sequoiadb.SDB_LIST_COLLECTIONSPACES : Get all collection spaces list *
Sequoiadb.SDB_LIST_STORAGEUNITS : Get storage units list *
Sequoiadb.SDB_LIST_GROUPS : Get replica group list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_STOREPROCEDURES : Get stored procedure list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_DOMAINS : Get all the domains list ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_TASKS : Get all the running split tasks ( only applicable in sharding env ) *
Sequoiadb.SDB_LIST_TRANSACTIONS : Get all the transactions information. *
Sequoiadb.SDB_LIST_TRANSACTIONS_CURRENT : Get the transactions information of current session. *
Sequoiadb.SDB_LIST_SVCTASKS : Get all the schedule task information *
Sequoiadb.SDB_LIST_SEQUENCES : Get the information of sequences *
Sequoiadb.SDB_LIST_USERS : Get all the user information. *
* @param query The matching rule, match 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. * @return The target information by cursor. * @throws BaseException If error happens. */ public DBCursor getList(int listType, BSONObject query, BSONObject selector, BSONObject orderBy) throws BaseException { return getList(listType, query, selector, orderBy, null, 0, -1); } /** * Flush the options to configuration file. * * @param options The param of flush, pass {"Global":true} or {"Global":false} * In cluster environment, passing {"Global":true} will flush data's and catalog's configuration file, * while passing {"Global":false} will flush coord's configuration file * In stand-alone environment, both them have the same behaviour * @throws BaseException If error happens. */ public void flushConfigure(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.EXPORT_CONFIG, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Force the node to update configs online. * * @param configs The specific configuration parameters to update * @param options Options The control options:(Only take effect in coordinate nodes) * GroupID:INT32, * GroupName:String, * NodeID:INT32, * HostName:String, * svcname:String, * ... * @throws BaseException If error happens. */ public void updateConfig(BSONObject configs, BSONObject options) throws BaseException { BSONObject newObj = new BasicBSONObject(); newObj.putAll(options); newObj.put("Configs", configs); AdminRequest request = new AdminRequest(AdminCommand.UPDATE_CONFIG, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Force the node to delete configs online. * * @param configs The specific configuration parameters to delete * @param options Options The control options:(Only take effect in coordinate nodes) * GroupID:INT32, * GroupName:String, * NodeID:INT32, * HostName:String, * svcname:String, * ... * @throws BaseException If error happens. */ public void deleteConfig(BSONObject configs, BSONObject options) throws BaseException { BSONObject newObj = new BasicBSONObject(); newObj.putAll(options); newObj.put("Configs", configs); AdminRequest request = new AdminRequest(AdminCommand.DELETE_CONFIG, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Execute sql in database. * * @param sql the SQL command. * @throws BaseException If error happens. */ public void execUpdate(String sql) throws BaseException { if (sql == null || sql.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "sql can not be null or empty"); } SQLRequest request = new SQLRequest(sql); SdbReply response = requestAndResponse(request); throwIfError(response, sql); } /** * Execute sql in database. * * @param sql the SQL command * @return the DBCursor of the result * @throws BaseException If error happens. */ public DBCursor exec(String sql) throws BaseException { if (sql == null || sql.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "sql can not be null or empty"); } SQLRequest request = new SQLRequest(sql); SdbReply response = requestAndResponse(request); int flag = response.getFlag(); if (flag != 0) { if (flag == SDBError.SDB_DMS_EOC.getErrorCode()) { return null; } else { throwIfError(response, sql); } } return new DBCursor(response, this); } /** * Get snapshot of the database. * * @param snapType The snapshot types are as below: *
*
Sequoiadb.SDB_SNAP_CONTEXTS : Get all contexts' snapshot *
Sequoiadb.SDB_SNAP_CONTEXTS_CURRENT : Get the current context's snapshot *
Sequoiadb.SDB_SNAP_SESSIONS : Get all sessions' snapshot *
Sequoiadb.SDB_SNAP_SESSIONS_CURRENT : Get the current session's snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONS : Get the collections' snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONSPACES : Get the collection spaces' snapshot *
Sequoiadb.SDB_SNAP_DATABASE : Get database's snapshot *
Sequoiadb.SDB_SNAP_SYSTEM : Get system's snapshot *
Sequoiadb.SDB_SNAP_CATALOG : Get catalog's snapshot *
Sequoiadb.SDB_SNAP_TRANSACTIONS : Get the snapshot of all the transactions *
Sequoiadb.SDB_SNAP_TRANSACTIONS_CURRENT : Get the snapshot of current transactions *
Sequoiadb.SDB_SNAP_ACCESSPLANS : Get the snapshot of cached access plans *
Sequoiadb.SDB_SNAP_HEALTH : Get the snapshot of node health detection *
Sequoiadb.SDB_SNAP_CONFIGS : Get the snapshot of node configurations *
Sequoiadb.SDB_SNAP_SVCTASKS : Get all the information of schedule task * Sequoiadb.SDB_SNAP_SEQUENCES : Get the snapshot of the sequence *
* @param matcher the matching rule, match 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 * @return the DBCursor of the result * @throws BaseException If error happens. */ public DBCursor getSnapshot(int snapType, String matcher, String selector, String orderBy) throws BaseException { BSONObject ma = null; BSONObject se = null; BSONObject or = 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); } return getSnapshot(snapType, ma, se, or); } /** * Get snapshot of the database. * * @param snapType The snapshot types are as below: *
*
Sequoiadb.SDB_SNAP_CONTEXTS : Get all contexts' snapshot *
Sequoiadb.SDB_SNAP_CONTEXTS_CURRENT : Get the current context's snapshot *
Sequoiadb.SDB_SNAP_SESSIONS : Get all sessions' snapshot *
Sequoiadb.SDB_SNAP_SESSIONS_CURRENT : Get the current session's snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONS : Get the collections' snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONSPACES : Get the collection spaces' snapshot *
Sequoiadb.SDB_SNAP_DATABASE : Get database's snapshot *
Sequoiadb.SDB_SNAP_SYSTEM : Get system's snapshot *
Sequoiadb.SDB_SNAP_CATALOG : Get catalog's snapshot *
Sequoiadb.SDB_SNAP_TRANSACTIONS : Get snapshot of transactions in current session *
Sequoiadb.SDB_SNAP_TRANSACTIONS_CURRENT : Get snapshot of all the transactions *
SequoiaDB.SDB_SNAP_ACCESSPLANS : Get the snapshot of cached access plans *
Sequoiadb.SDB_SNAP_HEALTH : Get the snapshot of node health detection *
Sequoiadb.SDB_SNAP_CONFIGS : Get the snapshot of node configurations *
Sequoiadb.SDB_SNAP_SVCTASKS : Get all the information of schedule task * Sequoiadb.SDB_SNAP_SEQUENCES : Get the snapshot of the sequence *
* @param matcher the matching rule, match 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 * @return the DBCursor instance of the result * @throws BaseException If error happens. */ public DBCursor getSnapshot(int snapType, BSONObject matcher, BSONObject selector, BSONObject orderBy) throws BaseException { return getSnapshot(snapType, matcher, selector, orderBy, null, 0, -1); } /** * Get snapshot of the database. * * @param snapType The snapshot types are as below: *
*
Sequoiadb.SDB_SNAP_CONTEXTS : Get all contexts' snapshot *
Sequoiadb.SDB_SNAP_CONTEXTS_CURRENT : Get the current context's snapshot *
Sequoiadb.SDB_SNAP_SESSIONS : Get all sessions' snapshot *
Sequoiadb.SDB_SNAP_SESSIONS_CURRENT : Get the current session's snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONS : Get the collections' snapshot *
Sequoiadb.SDB_SNAP_COLLECTIONSPACES : Get the collection spaces' snapshot *
Sequoiadb.SDB_SNAP_DATABASE : Get database's snapshot *
Sequoiadb.SDB_SNAP_SYSTEM : Get system's snapshot *
Sequoiadb.SDB_SNAP_CATALOG : Get catalog's snapshot *
Sequoiadb.SDB_SNAP_TRANSACTIONS : Get snapshot of transactions in current session *
Sequoiadb.SDB_SNAP_TRANSACTIONS_CURRENT : Get snapshot of all the transactions *
SequoiaDB.SDB_SNAP_ACCESSPLANS : Get the snapshot of cached access plans *
Sequoiadb.SDB_SNAP_HEALTH : Get the snapshot of node health detection *
Sequoiadb.SDB_SNAP_CONFIGS : Get the snapshot of node configurations *
Sequoiadb.SDB_SNAP_SVCTASKS : Get all the information of schedule task * Sequoiadb.SDB_SNAP_SEQUENCES : Get the snapshot of the sequence *
* @param matcher the matching rule, match 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 rule, the options provided for specific snapshot type format:{ '$Options': { } } * @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 the DBCursor instance of the result * @throws BaseException If error happens. */ public DBCursor getSnapshot(int snapType, BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint, long skipRows, long returnRows) throws BaseException { String command = getSnapshotCommand(snapType); QueryRequest request = new QueryRequest(command, matcher, selector, orderBy, hint, skipRows, returnRows, 0); SdbReply response = 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; throwIfError(response, msg); } } return new DBCursor(response, this); } private String getSnapshotCommand(int snapType) { switch (snapType) { case SDB_SNAP_CONTEXTS: return AdminCommand.SNAP_CONTEXTS; case SDB_SNAP_CONTEXTS_CURRENT: return AdminCommand.SNAP_CONTEXTS_CURRENT; case SDB_SNAP_SESSIONS: return AdminCommand.SNAP_SESSIONS; case SDB_SNAP_SESSIONS_CURRENT: return AdminCommand.SNAP_SESSIONS_CURRENT; case SDB_SNAP_COLLECTIONS: return AdminCommand.SNAP_COLLECTIONS; case SDB_SNAP_COLLECTIONSPACES: return AdminCommand.SNAP_COLLECTIONSPACES; case SDB_SNAP_DATABASE: return AdminCommand.SNAP_DATABASE; case SDB_SNAP_SYSTEM: return AdminCommand.SNAP_SYSTEM; case SDB_SNAP_CATALOG: return AdminCommand.SNAP_CATALOG; case SDB_SNAP_TRANSACTIONS: return AdminCommand.SNAP_TRANSACTIONS; case SDB_SNAP_TRANSACTIONS_CURRENT: return AdminCommand.SNAP_TRANSACTIONS_CURRENT; case SDB_SNAP_ACCESSPLANS: return AdminCommand.SNAP_ACCESSPLANS; case SDB_SNAP_HEALTH: return AdminCommand.SNAP_HEALTH; case SDB_SNAP_CONFIGS: return AdminCommand.SNAP_CONFIGS; case SDB_SNAP_SEQUENCES: return AdminCommand.SNAP_SEQUENCES; default: throw new BaseException(SDBError.SDB_INVALIDARG, String.format("Invalid snapshot type: %d", snapType)); } } /** * Begin the transaction. * * @throws BaseException If error happens. */ public void beginTransaction() throws BaseException { TransactionRequest request = new TransactionRequest(TransactionRequest.TransactionType.Begin); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Commit the transaction. * * @throws BaseException If error happens. */ public void commit() throws BaseException { TransactionRequest request = new TransactionRequest(TransactionRequest.TransactionType.Commit); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Rollback the transaction. * * @throws BaseException If error happens. */ public void rollback() throws BaseException { TransactionRequest request = new TransactionRequest(TransactionRequest.TransactionType.Rollback); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Create a storage procedure. * * @param code The code of storage procedure * @throws BaseException If error happens. */ public void crtJSProcedure(String code) throws BaseException { if (null == code || code.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, code); } BSONObject options = new BasicBSONObject(); Code codeObj = new Code(code); options.put(SdbConstants.FIELD_NAME_FUNC, codeObj); options.put(SdbConstants.FMP_FUNC_TYPE, FMP_FUNC_TYPE_JS); AdminRequest request = new AdminRequest(AdminCommand.CREATE_PROCEDURE, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Remove a store procedure. * * @param name The name of store procedure to be removed * @throws BaseException If error happens. */ public void rmProcedure(String name) throws BaseException { if (null == name || name.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, name); } BSONObject options = new BasicBSONObject(); options.put(SdbConstants.FIELD_NAME_FUNC, name); AdminRequest request = new AdminRequest(AdminCommand.REMOVE_PROCEDURE, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * List the storage procedures. * * @param condition The condition of list eg: {"name":"sum"}. return all if null * @throws BaseException If error happens. */ public DBCursor listProcedures(BSONObject condition) throws BaseException { return getList(SDB_LIST_STOREPROCEDURES, condition, null, null); } /** * Eval javascript code. * * @param code The javascript code * @return The result of the eval operation, including the return value type, * the return data and the error message. If succeed to eval, error message is null, * and we can extract the eval result from the return cursor and return type, * if not, the return cursor and the return type are null, we can extract * the error message for more detail. * @throws BaseException If error happens. */ public Sequoiadb.SptEvalResult evalJS(String code) throws BaseException { if (code == null || code.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG); } SptEvalResult evalResult = new Sequoiadb.SptEvalResult(); BSONObject newObj = new BasicBSONObject(); Code codeObj = new Code(code); newObj.put(SdbConstants.FIELD_NAME_FUNC, codeObj); newObj.put(SdbConstants.FMP_FUNC_TYPE, FMP_FUNC_TYPE_JS); AdminRequest request = new AdminRequest(AdminCommand.EVAL, newObj); SdbReply response = requestAndResponse(request); int flag = response.getFlag(); // if something wrong with the eval operation, not throws exception here if (flag != 0) { if (response.getErrorObj() != null) { evalResult.errmsg = response.getErrorObj(); } return evalResult; } else { // get the return type of eval result if (response.getReturnedNum() > 0) { BSONObject obj = response.getResultSet().getNext(); int typeValue = (Integer) obj.get(SdbConstants.FIELD_NAME_RETYE); evalResult.returnType = Sequoiadb.SptReturnType.getTypeByValue(typeValue); } // set the return cursor evalResult.cursor = new DBCursor(response, this); return evalResult; } } /** * Backup database. * * @param options Contains a series of backup configuration infomations. * Backup the whole cluster if null. The "options" contains 5 options as below. * All the elements in options are optional. * eg: {"GroupName":["rgName1", "rgName2"], "Path":"/opt/sequoiadb/backup", * "Name":"backupName", "Description":description, "EnsureInc":true, "OverWrite":true} *
    *
  • GroupID : The id(s) of replica group(s) which to be backuped *
  • GroupName : The name(s) of replica group(s) which to be backuped *
  • Name : The name for the backup *
  • Path : The backup path, if not assign, use the backup path assigned in the configuration file, * the path support to use wildcard(%g/%G:group name, %h/%H:host name, %s/%S:service name). * e.g. {Path:"/opt/sequoiadb/backup/%g"} *
  • isSubDir : Whether the path specified by paramer "Path" is a subdirectory of * the path specified in the configuration file, default to be false *
  • Prefix : The prefix of name for the backup, default to be null. e.g. {Prefix:"%g_bk_"} *
  • EnableDateDir : Whether turn on the feature which will create subdirectory named to * current date like "YYYY-MM-DD" automatically, default to be false *
  • Description : The description for the backup *
  • EnsureInc : Whether turn on increment synchronization, default to be false *
  • OverWrite : Whether overwrite the old backup file with the same name, default to be false *
* @throws BaseException If error happens. * @deprecated Rename to "backup". */ public void backupOffline(BSONObject options) throws BaseException { backup(options); } /** * Backup database. * * @param options Contains a series of backup configuration infomations. * Backup the whole cluster if null. The "options" contains 5 options as below. * All the elements in options are optional. * eg: {"GroupName":["rgName1", "rgName2"], "Path":"/opt/sequoiadb/backup", * "Name":"backupName", "Description":description, "EnsureInc":true, "OverWrite":true} *
    *
  • GroupID : The id(s) of replica group(s) which to be backuped *
  • GroupName : The name(s) of replica group(s) which to be backuped *
  • Name : The name for the backup *
  • Path : The backup path, if not assign, use the backup path assigned in the configuration file, * the path support to use wildcard(%g/%G:group name, %h/%H:host name, %s/%S:service name). * e.g. {Path:"/opt/sequoiadb/backup/%g"} *
  • isSubDir : Whether the path specified by paramer "Path" is a subdirectory of * the path specified in the configuration file, default to be false *
  • Prefix : The prefix of name for the backup, default to be null. e.g. {Prefix:"%g_bk_"} *
  • EnableDateDir : Whether turn on the feature which will create subdirectory named to * current date like "YYYY-MM-DD" automatically, default to be false *
  • Description : The description for the backup *
  • EnsureInc : Whether turn on increment synchronization, default to be false *
  • OverWrite : Whether overwrite the old backup file with the same name, default to be false *
* @throws BaseException If error happens. */ public void backup(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.BACKUP_OFFLINE, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * List the backups. * * @param options Contains configuration information for listing backups, list all the backups in the default backup path if null. * The "options" contains several options as below. All the elements in options are optional. * eg: {"GroupName":["rgName1", "rgName2"], "Path":"/opt/sequoiadb/backup", "Name":"backupName"} *
    *
  • GroupID : Specified the group id of the backups, default to list all the backups of all the groups. *
  • GroupName : Specified the group name of the backups, default to list all the backups of all the groups. *
  • Path : Specified the path of the backups, default to use the backup path asigned in the configuration file. *
  • Name : Specified the name of backup, default to list all the backups. *
  • IsSubDir : Specified the "Path" is a subdirectory of the backup path asigned in the configuration file or not, default to be false. *
  • Prefix : Specified the prefix name of the backups, support for using wildcards("%g","%G","%h","%H","%s","%s"),such as: Prefix:"%g_bk_", default to not using wildcards. *
  • Detail : Display the detail of the backups or not, default to be false. *
* @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 * @return the DBCursor of the backup or null while having no backup information. * @throws BaseException If error happens. */ public DBCursor listBackup(BSONObject options, BSONObject matcher, BSONObject selector, BSONObject orderBy) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.LIST_BACKUP, matcher, selector, orderBy, options); SdbReply response = requestAndResponse(request); int flags = response.getFlag(); if (flags != 0) { if (flags == SDBError.SDB_DMS_EOC.getErrorCode()) { return null; } else { String msg = "matcher = " + matcher + ", selector = " + selector + ", orderBy = " + orderBy + ", options = " + options; throwIfError(response, msg); } } DBCursor cursor = new DBCursor(response, this); return cursor; } /** * Remove the backups. * * @param options Contains configuration information for removing backups, remove all the backups in the default backup path if null. * The "options" contains several options as below. All the elements in options are optional. * eg: {"GroupName":["rgName1", "rgName2"], "Path":"/opt/sequoiadb/backup", "Name":"backupName"} *
    *
  • GroupID : Specified the group id of the backups, default to list all the backups of all the groups. *
  • GroupName : Specified the group name of the backups, default to list all the backups of all the groups. *
  • Path : Specified the path of the backups, default to use the backup path asigned in the configuration file. *
  • Name : Specified the name of backup, default to list all the backups. *
  • IsSubDir : Specified the "Path" is a subdirectory of the backup path assigned in the configuration file or not, default to be false. *
  • Prefix : Specified the prefix name of the backups, support for using wildcards("%g","%G","%h","%H","%s","%s"),such as: Prefix:"%g_bk_", default to not using wildcards. *
  • Detail : Display the detail of the backups or not, default to be false. *
* @throws BaseException If error happens. */ public void removeBackup(BSONObject options) throws BaseException { AdminRequest request = new AdminRequest(AdminCommand.REMOVE_BACKUP, options); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * List the tasks. * * @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. * @throws BaseException If error happens. */ public DBCursor listTasks(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint) throws BaseException { return getList(SDB_LIST_TASKS, matcher, selector, orderBy); } /** * Wait the tasks to finish. * * @param taskIDs The array of task id * @throws BaseException If error happens. */ public void waitTasks(long[] taskIDs) throws BaseException { if (taskIDs == null || taskIDs.length == 0) { throw new BaseException(SDBError.SDB_INVALIDARG, "taskIDs is empty or null"); } // append argument:{ "TaskID": { "$in": [ 1, 2, 3 ] } } BSONObject newObj = new BasicBSONObject(); BSONObject subObj = new BasicBSONObject(); BSONObject list = new BasicBSONList(); for (int i = 0; i < taskIDs.length; i++) { list.put(Integer.toString(i), taskIDs[i]); } subObj.put("$in", list); newObj.put(SdbConstants.FIELD_NAME_TASKID, subObj); AdminRequest request = new AdminRequest(AdminCommand.WAIT_TASK, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Cancel the specified task. * * @param taskID The task id * @param isAsync The operation "cancel task" is async or not, * "true" for async, "false" for sync. Default sync. * @throws BaseException If error happens. */ public void cancelTask(long taskID, boolean isAsync) throws BaseException { if (taskID <= 0) { String msg = "taskID = " + taskID + ", isAsync = " + isAsync; throw new BaseException(SDBError.SDB_INVALIDARG, msg); } BSONObject newObj = new BasicBSONObject(); newObj.put(SdbConstants.FIELD_NAME_TASKID, taskID); newObj.put(SdbConstants.FIELD_NAME_ASYNC, isAsync); AdminRequest request = new AdminRequest(AdminCommand.CANCEL_TASK, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } private void clearSessionAttrCache() { attributeCache = null; } private BSONObject getSessionAttrCache() { return attributeCache; } private void setSessionAttrCache(BSONObject attribute) { attributeCache = attribute; } /** * Set the attributes of the current session. * * @param options The options for setting session attributes. Can not be * null. While it's a empty options, the local session attributes * cache will be cleanup. Please reference * {@see here} * for more detail. * @throws BaseException If error happens. */ public void setSessionAttr(BSONObject options) throws BaseException { if (options == null) { throw new BaseException(SDBError.SDB_INVALIDARG, "options can not be null"); } if (options.isEmpty()) { clearSessionAttrCache(); return; } BSONObject newObj = new BasicBSONObject(); newObj.putAll(options); if (options.containsField(SdbConstants.FIELD_NAME_PREFERED_INSTANCE)) { // Add old version of preferred instance Object value = options.get(SdbConstants.FIELD_NAME_PREFERED_INSTANCE); if (value instanceof String) { int v = PreferInstance.MASTER; if (value.equals("M") || value.equals("m")) { v = PreferInstance.MASTER; } else if (value.equals("S") || value.equals("s")) { v = PreferInstance.SLAVE; } else if (value.equals("A") || value.equals("a")) { v = PreferInstance.ANYONE; } else { throw new BaseException(SDBError.SDB_INVALIDARG, options.toString()); } newObj.put(SdbConstants.FIELD_NAME_PREFERED_INSTANCE, v); } else if (value instanceof Integer) { newObj.put(SdbConstants.FIELD_NAME_PREFERED_INSTANCE, value); } // Add new version of preferred instance newObj.put(SdbConstants.FIELD_NAME_PREFERED_INSTANCE_V1, value); } clearSessionAttrCache(); AdminRequest request = new AdminRequest(AdminCommand.SET_SESSION_ATTRIBUTE, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Get the attributes of the current session from the local cache if possible. * * @return the BSONObject of the session attribute. * @throws BaseException If error happens. * @since 2.8.5 */ public BSONObject getSessionAttr() throws BaseException { return getSessionAttr(true); } /** * Get the attributes of the current session. * * @param useCache use the local cache or not. * @return the BSONObject of the session attribute. * @throws BaseException If error happens. * @since 3.2 */ public BSONObject getSessionAttr(boolean useCache) throws BaseException { BSONObject result = null; if (useCache) { result = getSessionAttrCache(); if (result != null) { return result; } } AdminRequest request = new AdminRequest(AdminCommand.GET_SESSION_ATTRIBUTE); SdbReply response = requestAndResponse(request); throwIfError(response); ResultSet resultSet = response.getResultSet(); if (resultSet != null && resultSet.hasNext()) { result = resultSet.getNext(); if (result == null) { clearSessionAttrCache(); } else { setSessionAttrCache(result); } } else { clearSessionAttrCache(); } return result; } /** * Close all the cursors created in current connection, we can't use those cursors to get * data again. * * @throws BaseException If error happens. */ public void closeAllCursors() throws BaseException { if (isClosed()) { return; } InterruptRequest request = new InterruptRequest(); sendRequest(request); } /** * List all the replica group. * * @return information of all replica groups. * @throws BaseException If error happens. */ public DBCursor listReplicaGroups() throws BaseException { return getList(SDB_LIST_GROUPS, null, null, null); } /** * Verify the existence of domain. * * @param domainName the name of domain * @return True if existed or False if not existed * @throws BaseException If error happens. */ public boolean isDomainExist(String domainName) throws BaseException { if (null == domainName || domainName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, domainName); } BSONObject matcher = new BasicBSONObject(); matcher.put(SdbConstants.FIELD_NAME_NAME, domainName); DBCursor cursor = getList(SDB_LIST_DOMAINS, matcher, null, null); try { if (cursor != null && cursor.hasNext()) return true; else return false; } finally { if (cursor != null) { cursor.close(); } } } /** * Create a domain. * * @param domainName The name of the creating domain * @param options The options for the domain. The options are as below: *
    *
  • Groups : the list of the replica groups' names which the domain is going to contain. * eg: { "Groups": [ "group1", "group2", "group3" ] } * If this argument is not included, the domain will contain all replica groups in the cluster. *
  • AutoSplit : If this option is set to be true, while creating collection(ShardingType is "hash") in this domain, * the data of this collection will be split(hash split) into all the groups in this domain automatically. * However, it won't automatically split data into those groups which were add into this domain later. * eg: { "Groups": [ "group1", "group2", "group3" ], "AutoSplit: true" } *
* @return the newly created collection space object * @throws BaseException If error happens. */ public Domain createDomain(String domainName, BSONObject options) throws BaseException { if (domainName == null || domainName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "domain name is empty or null"); } BSONObject newObj = new BasicBSONObject(); newObj.put(SdbConstants.FIELD_NAME_NAME, domainName); if (null != options) { newObj.put(SdbConstants.FIELD_NAME_OPTIONS, options); } AdminRequest request = new AdminRequest(AdminCommand.CREATE_DOMAIN, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); return new Domain(this, domainName); } /** * Drop a domain. * * @param domainName the name of the domain * @throws BaseException If error happens. */ public void dropDomain(String domainName) throws BaseException { if (null == domainName || domainName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "domain name is empty or null"); } BSONObject newObj = new BasicBSONObject(); newObj.put(SdbConstants.FIELD_NAME_NAME, domainName); AdminRequest request = new AdminRequest(AdminCommand.DROP_DOMAIN, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Get the specified domain. * * @param domainName the name of the domain * @return the Domain instance * @throws BaseException If the domain not exit, throw BaseException with the error SDB_CAT_DOMAIN_NOT_EXIST. */ public Domain getDomain(String domainName) throws BaseException { if (isDomainExist(domainName)) { return new Domain(this, domainName); } else { throw new BaseException(SDBError.SDB_CAT_DOMAIN_NOT_EXIST, domainName); } } /** * List domains. * * @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. * @throws BaseException If error happens. */ public DBCursor listDomains(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint) throws BaseException { return getList(SDB_LIST_DOMAINS, matcher, selector, orderBy); } /** * Get all the replica groups' name. * * @return A list of all the replica groups' names. * @throws BaseException If error happens. */ public ArrayList getReplicaGroupNames() throws BaseException { DBCursor cursor = getList(SDB_LIST_GROUPS, null, null, null); if (cursor == null) { return null; } ArrayList colList = new ArrayList(); try { while (cursor.hasNext()) { colList.add(cursor.getNext().get("GroupName").toString()); } } finally { cursor.close(); } return colList; } /** * Get the information of the replica groups. * * @return A list of information of the replica groups. * @throws BaseException If error happens. */ public ArrayList getReplicaGroupsInfo() throws BaseException { DBCursor cursor = getList(SDB_LIST_GROUPS, null, null, null); if (cursor == null) { return null; } ArrayList colList = new ArrayList(); try { while (cursor.hasNext()) { colList.add(cursor.getNext().toString()); } } finally { cursor.close(); } return colList; } /** * whether the replica group exists in the database or not * * @param rgName replica group's name * @return true or false */ public boolean isRelicaGroupExist(String rgName) { BSONObject rg = getDetailByName(rgName); if (rg == null) { return false; } else { return true; } } /** * whether the replica group exists in the database or not * * @param rgId id of replica group * @return true or false */ public boolean isReplicaGroupExist(int rgId) { BSONObject rg = getDetailById(rgId); if (rg == null) { return false; } else { return true; } } /** * Get replica group by name. * * @param rgName replica group's name * @return A replica group object or null for not exit. * @throws BaseException If error happens. */ public ReplicaGroup getReplicaGroup(String rgName) throws BaseException { BSONObject rg = getDetailByName(rgName); if (rg == null) { throw new BaseException(SDBError.SDB_CLS_GRP_NOT_EXIST, String.format("Group with the name[%s] does not exist", rgName)); } return new ReplicaGroup(this, rgName); } /** * Get replica group by id. * * @param rgId replica group id * @return A replica group object or null for not exit. * @throws BaseException If error happens. */ public ReplicaGroup getReplicaGroup(int rgId) throws BaseException { BSONObject rg = getDetailById(rgId); if (rg == null) { throw new BaseException(SDBError.SDB_CLS_GRP_NOT_EXIST, String.format("Group with the name[%d] does not exist", rgId)); } return new ReplicaGroup(this, rgId); } /** * Create replica group by name. * * @param rgName replica group's name * @return A replica group object. * @throws BaseException If error happens. */ public ReplicaGroup createReplicaGroup(String rgName) throws BaseException { BSONObject rg = new BasicBSONObject(); rg.put(SdbConstants.FIELD_NAME_GROUPNAME, rgName); AdminRequest request = new AdminRequest(AdminCommand.CREATE_GROUP, rg); SdbReply response = requestAndResponse(request); throwIfError(response, rgName); return new ReplicaGroup(this, rgName); } /** * Remove replica group by name. * * @param rgName replica group's name * @throws BaseException If error happens. */ public void removeReplicaGroup(String rgName) throws BaseException { BSONObject rg = new BasicBSONObject(); rg.put(SdbConstants.FIELD_NAME_GROUPNAME, rgName); AdminRequest request = new AdminRequest(AdminCommand.REMOVE_GROUP, rg); SdbReply response = requestAndResponse(request); throwIfError(response, rgName); } private long getNextRequestId() { return requestId++; } /** * Active replica group by name. * * @param rgName replica group name * @throws BaseException If error happens. */ public void activateReplicaGroup(String rgName) throws BaseException { BSONObject rg = new BasicBSONObject(); rg.put(SdbConstants.FIELD_NAME_GROUPNAME, rgName); AdminRequest request = new AdminRequest(AdminCommand.ACTIVE_GROUP, rg); SdbReply response = requestAndResponse(request); throwIfError(response, rgName); } /** * Create the replica Catalog group with the given options. * * @param hostName The host name * @param port The port * @param dbPath The database path * @param options The configure options * @throws BaseException If error happens. */ public void createReplicaCataGroup(String hostName, int port, String dbPath, BSONObject options) { BSONObject obj = new BasicBSONObject(); obj.put(SdbConstants.FIELD_NAME_HOST, hostName); obj.put(SdbConstants.PMD_OPTION_SVCNAME, Integer.toString(port)); obj.put(SdbConstants.PMD_OPTION_DBPATH, dbPath); if (options != null) { for (String key : options.keySet()) { if (key.equals(SdbConstants.FIELD_NAME_HOST) || key.equals(SdbConstants.PMD_OPTION_SVCNAME) || key.equals(SdbConstants.PMD_OPTION_DBPATH)) { continue; } obj.put(key, options.get(key)); } } AdminRequest request = new AdminRequest(AdminCommand.CREATE_CATALOG_GROUP, obj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Create the replica Catalog group with the given options. * * @param hostName The host name * @param port The port * @param dbPath The database path * @param configure The configure options * @throws BaseException If error happens. * @deprecated Use "void createReplicaCataGroup(String hostName, int port, String dbPath, * final BSONObject options)" instead. */ public void createReplicaCataGroup(String hostName, int port, String dbPath, Map configure) { BSONObject obj = new BasicBSONObject(); if (configure != null) { for (String key : configure.keySet()) { obj.put(key, configure.get(key)); } } createReplicaCataGroup(hostName, port, dbPath, obj); } /** * Send message to server. * * @param message The message to send to server. */ public void msg(String message) { MessageRequest request = new MessageRequest(message); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Clear the cache of the nodes (data/coord node). * @param options The control options:(Only take effect in coordinate nodes). * About the parameter 'options', please reference to the official * website(www.sequoiadb.com) and then search "命令位置参数" * for more details. Some of its optional parameters are as bellow: * *
    *
  • Global(Bool) : execute this command in global or not. While 'options' is null, it's equals to {Glocal: true}. *
  • GroupID(INT32 or INT32 Array) : specified one or several groups by their group IDs. e.g. {GroupID:[1001, 1002]}. *
  • GroupName(String or String Array) : specified one or several groups by their group names. e.g. {GroupID:"group1"}. *
  • ... *
* @return void */ public void invalidateCache(BSONObject options) { AdminRequest request = new AdminRequest(AdminCommand.INVALIDATE_CACHE, options); SdbReply response = requestAndResponse(request); throwIfError(response); } private String getListCommand(int listType) { switch (listType) { case SDB_LIST_CONTEXTS: return AdminCommand.LIST_CONTEXTS; case SDB_LIST_CONTEXTS_CURRENT: return AdminCommand.LIST_CONTEXTS_CURRENT; case SDB_LIST_SESSIONS: return AdminCommand.LIST_SESSIONS; case SDB_LIST_SESSIONS_CURRENT: return AdminCommand.LIST_SESSIONS_CURRENT; case SDB_LIST_COLLECTIONS: return AdminCommand.LIST_COLLECTIONS; case SDB_LIST_COLLECTIONSPACES: return AdminCommand.LIST_COLLECTIONSPACES; case SDB_LIST_STORAGEUNITS: return AdminCommand.LIST_STORAGEUNITS; case SDB_LIST_GROUPS: return AdminCommand.LIST_GROUPS; case SDB_LIST_STOREPROCEDURES: return AdminCommand.LIST_PROCEDURES; case SDB_LIST_DOMAINS: return AdminCommand.LIST_DOMAINS; case SDB_LIST_TASKS: return AdminCommand.LIST_TASKS; case SDB_LIST_TRANSACTIONS: return AdminCommand.LIST_TRANSACTIONS; case SDB_LIST_TRANSACTIONS_CURRENT: return AdminCommand.LIST_TRANSACTIONS_CURRENT; case SDB_LIST_SVCTASKS: return AdminCommand.LIST_SVCTASKS; case SDB_LIST_SEQUENCES: return AdminCommand.LIST_SEQUENCES; case SDB_LIST_USERS: return AdminCommand.LIST_USERS; case SDB_LIST_CL_IN_DOMAIN: return AdminCommand.LIST_CL_IN_DOMAIN; case SDB_LIST_CS_IN_DOMAIN: return AdminCommand.LIST_CS_IN_DOMAIN; default: throw new BaseException(SDBError.SDB_INVALIDARG, String.format("Invalid list type: %d", listType)); } } String getUserName() { return userName; } String getPassword() { return password; } BSONObject getDetailByName(String name) throws BaseException { BSONObject condition = new BasicBSONObject(); condition.put(SdbConstants.FIELD_NAME_GROUPNAME, name); BSONObject result; DBCursor cursor = getList(Sequoiadb.SDB_LIST_GROUPS, condition, null, null); try { if (cursor == null || !cursor.hasNext()) { return null; } result = cursor.getNext(); } finally { if (cursor != null) { cursor.close(); } } return result; } BSONObject getDetailById(int id) throws BaseException { BSONObject condition = new BasicBSONObject(); condition.put(SdbConstants.FIELD_NAME_GROUPID, id); BSONObject result; DBCursor cursor = getList(Sequoiadb.SDB_LIST_GROUPS, condition, null, null); try { if (cursor == null || !cursor.hasNext()) { return null; } result = cursor.getNext(); } finally { if (cursor != null) { cursor.close(); } } return result; } private SysInfoResponse receiveSysInfoResponse() { SysInfoResponse response = new SysInfoResponse(); byte[] lengthBytes = connection.receive(response.length()); ByteBuffer buffer = ByteBuffer.wrap(lengthBytes); response.decode(buffer); return response; } private ByteBuffer receiveSdbResponse() { byte[] bytes; try { byte[] lengthBytes = connection.receive(4); int length = ByteBuffer.wrap(lengthBytes).order(byteOrder).getInt(); bytes = new byte[length]; System.arraycopy(lengthBytes, 0, bytes, 0, lengthBytes.length); connection.receive(bytes, 4, length - 4); } catch (Exception e) { connection.close(); throw new BaseException(SDBError.SDB_NETWORK, "Failed to receive message.", e); } ByteBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder); return buffer; } private void validateResponse(SdbRequest request, SdbResponse response) { if ((request.opCode() | MsgOpCode.RESP_MASK) != response.opCode()) { throw new BaseException(SDBError.SDB_UNKNOWN_MESSAGE, ("request=" + request.opCode() + " response=" + response.opCode())); } } private ByteBuffer encodeRequest(Request request) { ByteBuffer buffer = ByteBuffer.allocate(request.length()); buffer.order(byteOrder); request.setRequestId(getNextRequestId()); request.encode(buffer); return buffer; } private void sendRequest(Request request) { ByteBuffer buffer = encodeRequest(request); if (!isClosed()) { connection.send(buffer); } else { throw new BaseException(SDBError.SDB_NOT_CONNECTED); } } private T decodeResponse(ByteBuffer buffer, Class tClass) { T response; try { response = tClass.newInstance(); } catch (Exception e) { throw new BaseException(SDBError.SDB_INVALIDARG, e); } response.decode(buffer); return response; } private ByteBuffer sendAndReceive(ByteBuffer request) { if (!isClosed()) { connection.send(request); lastUseTime = System.currentTimeMillis(); return receiveSdbResponse(); } else { throw new BaseException(SDBError.SDB_NOT_CONNECTED); } } T requestAndResponse(SdbRequest request, Class tClass) { ByteBuffer out = encodeRequest(request); ByteBuffer in = sendAndReceive(out); T response = decodeResponse(in, tClass); validateResponse(request, response); return response; } SdbReply requestAndResponse(SdbRequest request) { return requestAndResponse(request, SdbReply.class); } private String getErrorDetail(BSONObject errorObj, Object errorMsg) { String detail = null; if (errorObj != null) { String serverDetail = (String) errorObj.get("detail"); if (serverDetail != null && !serverDetail.isEmpty()) { detail = serverDetail; } } if (errorMsg != null) { if (detail != null && !detail.isEmpty()) { detail += ", " + errorMsg.toString(); } else { detail = errorMsg.toString(); } } return detail; } // errorMsg Object to avoid unnecessary toString() invoke when no error happened void throwIfError(CommonResponse response, Object errorMsg) throws BaseException { if (response.getFlag() != 0) { String remoteAddress = "remote address[" + getNodeName() + "]"; BSONObject errorObj = response.getErrorObj(); String detail = getErrorDetail(errorObj, errorMsg); if (detail != null && !detail.isEmpty()) { throw new BaseException(response.getFlag(), remoteAddress + ", " + detail, errorObj); } else { throw new BaseException(response.getFlag(), remoteAddress, errorObj); } } } // dependent implementation but not invoke throwIfError(r,o) to avoid duplicate stack trace void throwIfError(CommonResponse response) throws BaseException { if (response.getFlag() != 0) { String remoteAddress = "remote address[" + getNodeName() + "]"; BSONObject errorObj = response.getErrorObj(); String detail = getErrorDetail(errorObj, null); if (detail != null && !detail.isEmpty()) { throw new BaseException(response.getFlag(), remoteAddress + ", " + detail, errorObj); } else { throw new BaseException(response.getFlag(), remoteAddress, errorObj); } } } private ByteOrder getSysInfo() { SysInfoRequest request = new SysInfoRequest(); sendRequest(request); SysInfoResponse response = receiveSysInfoResponse(); return response.byteOrder(); } private void killContext() { if (isClosed()) { throw new BaseException(SDBError.SDB_NOT_CONNECTED); } long[] contextIds = new long[]{-1}; KillContextRequest request = new KillContextRequest(contextIds); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Close the connection. * * @throws BaseException If error happens. */ @Override public void close() throws BaseException { if (isClosed()) { return; } try { releaseResource(); DisconnectRequest request = new DisconnectRequest(); sendRequest(request); } finally { connection.close(); } } /** * Class for executing stored procedure result. */ public static class SptEvalResult { private SptReturnType returnType; private BSONObject errmsg; private DBCursor cursor; public SptEvalResult() { returnType = null; errmsg = null; cursor = null; } /** * Set return type. */ public void setReturnType(SptReturnType returnType) { this.returnType = returnType; } /** * Get return type. */ public SptReturnType getReturnType() { return returnType; } /** * Set error type. */ public void setErrMsg(BSONObject errmsg) { this.errmsg = errmsg; } /** * Get error type. */ public BSONObject getErrMsg() { return errmsg; } /** * Set result cursor. */ public void setCursor(DBCursor cursor) { if (this.cursor != null) { this.cursor.close(); } this.cursor = cursor; } /** * Get result cursor. */ public DBCursor getCursor() { return cursor; } } public enum SptReturnType { TYPE_VOID(0), TYPE_STR(1), TYPE_NUMBER(2), TYPE_OBJ(3), TYPE_BOOL(4), TYPE_RECORDSET(5), TYPE_CS(6), TYPE_CL(7), TYPE_RG(8), TYPE_RN(9); private int typeValue; SptReturnType(int typeValue) { this.typeValue = typeValue; } public int getTypeValue() { return typeValue; } public static SptReturnType getTypeByValue(int typeValue) { SptReturnType retType = null; for (SptReturnType rt : values()) { if (rt.getTypeValue() == typeValue) { retType = rt; break; } } return retType; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy