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 java.io.Closeable;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import com.sequoiadb.util.Helper;
import org.bson.BSONObject;
import org.bson.BasicBSONObject;
import org.bson.types.BasicBSONList;
import org.bson.types.Code;
import org.bson.util.JSON;

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.AdminRequest;
import com.sequoiadb.message.request.AuthRequest;
import com.sequoiadb.message.request.DisconnectRequest;
import com.sequoiadb.message.request.InterruptRequest;
import com.sequoiadb.message.request.KillContextRequest;
import com.sequoiadb.message.request.MessageRequest;
import com.sequoiadb.message.request.QueryRequest;
import com.sequoiadb.message.request.Request;
import com.sequoiadb.message.request.SQLRequest;
import com.sequoiadb.message.request.SdbRequest;
import com.sequoiadb.message.request.SysInfoRequest;
import com.sequoiadb.message.request.TransactionRequest;
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 com.sequoiadb.net.ConnectionProxy;

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

    // 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;

    private final static int DEFAULT_BUFF_LENGTH = 512;
    private ByteBuffer requestBuffer = null;

    /**
     * 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_BACKUPS = 17 ;
    //public final static int SDB_LIST_RESERVED1 = 18 ;
    //public final static int SDB_LIST_RESERVED2 = 19 ;
    //public final static int SDB_LIST_RESERVED3 = 20 ;
    //public final static int SDB_LIST_RESERVED4 = 21 ;
    public final static int SDB_LIST_DATASOURCES = 22;
    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 SDB_SNAP_RESERVED1 = 16;
    //public final static int SDB_SNAP_RESERVED2 = 17;
    public final static int SDB_SNAP_QUERIES = 18;
    public final static int SDB_SNAP_LATCHWAITS = 19;
    public final static int SDB_SNAP_LOCKWAITS = 20;
    public final static int SDB_SNAP_INDEXSTATS = 21;

    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 setIsOldVersionLobServer(boolean isOldVersionLobServer) {
        this.isOldVersionLobServer = isOldVersionLobServer;
    }

    boolean getIsOldVersionLobServer() {
        return isOldVersionLobServer;
    }

    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();

        connProxy = new ConnectionProxy(connection);

        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 {
        if (username == null || username.length() == 0 || password == null) {
            throw new BaseException(SDBError.SDB_INVALIDARG);
        }
        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(int) : Assign how large the page size is for the collection created in * this collection space, default to be 64K *
  • Domain(String) : Assign which domain does current collection space belong to, it will * belongs to the system domain if not assign this option *
  • LobPageSize(int) : The Lob data page size, default value is 262144 * and the unit is byte *
  • DataSource(String) : Assign which data source does current collection space belong to *
  • Mapping(String) : The name of the collection space mapped by the current collection space *
* @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. *
Sequoiadb.SDB_LIST_BACKUPS : Get all the backup information. *
Sequoiadb.SDB_LIST_DATASOURCES : Get all the data source 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. *
Sequoiadb.SDB_LIST_BACKUPS : Get all the backup information. *
Sequoiadb.SDB_LIST_DATASOURCES : Get all the data source 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 { if (options == null) { options = new BasicBSONObject(); } 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 update configs online. * * @param configs The specific configuration parameters to update * @throws BaseException If error happens. */ public void updateConfig(BSONObject configs) throws BaseException { updateConfig(configs, new BasicBSONObject()); } /** * 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 *
Sequoiadb.SDB_SNAP_QUERIES : Get the snapshot of queries *
Sequoiadb.SDB_SNAP_LATCHWAITS : Get the snapshot of latch waits *
Sequoiadb.SDB_SNAP_LOCKWAITS : Get the snapshot of lock waits *
Sequoiadb.SDB_SNAP_INDEXSTATS : Get the snapshot of index statistics *
* @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 *
Sequoiadb.SDB_SNAP_QUERIES : Get the snapshot of queries *
Sequoiadb.SDB_SNAP_LATCHWAITS : Get the snapshot of latch waits *
Sequoiadb.SDB_SNAP_LOCKWAITS : Get the snapshot of lock waits *
Sequoiadb.SDB_SNAP_INDEXSTATS : Get the snapshot of index statistics *
* @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 *
Sequoiadb.SDB_SNAP_QUERIES : Get the snapshot of queries *
Sequoiadb.SDB_SNAP_LATCHWAITS : Get the snapshot of latch waits *
Sequoiadb.SDB_SNAP_LOCKWAITS : Get the snapshot of lock waits *
Sequoiadb.SDB_SNAP_INDEXSTATS : Get the snapshot of index statistics *
* @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_SVCTASKS: return AdminCommand.SNAP_SVCTASKS; case SDB_SNAP_SEQUENCES: return AdminCommand.SNAP_SEQUENCES; case SDB_SNAP_QUERIES: return AdminCommand.SNAP_QUERIES; case SDB_SNAP_LATCHWAITS: return AdminCommand.SNAP_LATCHWAITS; case SDB_SNAP_LOCKWAITS: return AdminCommand.SNAP_LOCKWAITS; case SDB_SNAP_INDEXSTATS: return AdminCommand.SNAP_INDEXSTATS; 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". */ @Deprecated 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(); for (String key: options.keySet()) { Object value = options.get(key); if (key.equalsIgnoreCase(SdbConstants.FIELD_NAME_PREFERED_INSTANCE)){ if (value instanceof String) { String valueStr = (String)value; int v ; if (valueStr.equalsIgnoreCase("M") ||valueStr.equalsIgnoreCase("-M")) { v = PreferInstance.MASTER; } else if (valueStr.equalsIgnoreCase("S") ||valueStr.equalsIgnoreCase("-S")) { v = PreferInstance.SLAVE; } else if (valueStr.equalsIgnoreCase("A") ||valueStr.equalsIgnoreCase("-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); }else { newObj.put(key, 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 { interrupt(); } /** * Send an interrupt message to engine. * * @throws BaseException If error happens. */ public void interrupt() throws BaseException { if (isClosed()) { return; } InterruptRequest request = new InterruptRequest(); sendRequest(request); } /** * Send "INTERRUPT_SELF" message to engine to stop the current operation. When the current operation had finish, * nothing happened, Otherwise, the current operation will be stop, and return error. * * @throws BaseException If error happens. */ public void interruptOperation() throws BaseException { if (isClosed()) { return; } InterruptRequest request = new InterruptRequest(true); 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, "Domain name can't be null or empty"); } return _checkIsExistByList(SDB_LIST_DOMAINS, domainName); } /** * 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 { if (rgName == null || rgName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "The name of replica group is null or empty"); } 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 { if (rgName == null || rgName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "The name of replica group is null or empty"); } 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 { if (rgName == null || rgName.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "The name of replica group is null or empty"); } 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. */ @Deprecated 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); } /** * Stop the specified session's current operation and terminate it. * * @param sessionID The ID of the session. */ public void forceSession(long sessionID) { forceSession(sessionID, null); } /** * Stop the specified session's current operation and terminate it. * * @param sessionID The ID of the session. * @param option The control options, Please reference * {@see here} * for more detail. */ public void forceSession(long sessionID, BSONObject option) { BSONObject matcher = new BasicBSONObject(); matcher.put(SdbConstants.FIELD_NAME_SESSION_ID, sessionID); if (option != null) { matcher.putAllUnique(option); } AdminRequest request = new AdminRequest(AdminCommand.FORCE_SESSION, matcher); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * 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); } /** * Create a sequence with default options. * * @param seqName The name of sequence * @return A sequence object of creation */ public DBSequence createSequence(String seqName){ return createSequence(seqName, null); } /** * Create a sequence with default options. * * @param seqName The name of sequence * @param options The options specified by user, details as bellow: *
    *
  • StartValue(long) : The start value of sequence *
  • MinValue(long) : The minimum value of sequence *
  • MaxValue(long) : The maxmun value of sequence *
  • Increment(int) : The increment value of sequence *
  • CacheSize(int) : The cache size of sequence *
  • AcquireSize(int) : The acquire size of sequence *
  • Cycled(boolean) : The cycled flag of sequence *
* @return A sequence object of creation */ public DBSequence createSequence(String seqName, BSONObject options){ if (seqName == null || seqName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "Sequence name can't be null or empty"); } BSONObject obj = new BasicBSONObject(); obj.put(SdbConstants.FIELD_NAME_NAME, seqName); if (options != null) { obj.putAll(options); } AdminRequest request = new AdminRequest(AdminCommand.CREATE_SEQUENCE, obj); SdbReply response = requestAndResponse(request); throwIfError(response); return new DBSequence(seqName,this); } /** * Drop the specified sequence. * * @param seqName The name of sequence */ public void dropSequence(String seqName){ if (seqName == null || seqName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "Sequence name can't be null or empty"); } BSONObject newObj = new BasicBSONObject(); newObj.put(SdbConstants.FIELD_NAME_NAME, seqName); AdminRequest request = new AdminRequest(AdminCommand.DROP_SEQUENCE, newObj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Get the specified sequence. * * @param seqName The name of sequence * @return The specified sequence object */ public DBSequence getSequence(String seqName){ DBSequence sequence = null; if (seqName == null || seqName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "Sequence name can't be null or empty"); } if (isSequenceExist(seqName)){ sequence = new DBSequence(seqName, this); } return sequence; } private boolean isSequenceExist(String seqName) throws BaseException { if (seqName == null || seqName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "Sequence name can't be null or empty"); } return _checkIsExistByList(SDB_LIST_SEQUENCES, seqName); } /** * Rename sequence. * * @param oldName The old name of sequence * @param newName The new name of sequence */ public void renameSequence(String oldName, String newName){ if (oldName == null || oldName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "oldName can't be null or empty"); } if (newName == null || newName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "newName can't be null or empty"); } BSONObject option = new BasicBSONObject(); option.put(SdbConstants.FIELD_NAME_NAME, oldName); option.put(SdbConstants.FIELD_NAME_NEWNAME, newName); BSONObject obj = new BasicBSONObject(); obj.put(SdbConstants.FIELD_NAME_ACTION, SdbConstants.SEQ_OPT_RENAME); obj.put(SdbConstants.FIELD_NAME_OPTIONS, option); AdminRequest request = new AdminRequest(AdminCommand.ALTER_SEQUENCE, obj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * Whether the data source exists or not. * * @param dataSourceName The data source name * @throws BaseException If error happens. */ public boolean isDataSourceExist(String dataSourceName) throws BaseException { if (null == dataSourceName || dataSourceName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "data source name cannot be empty or null"); } return _checkIsExistByList(SDB_LIST_DATASOURCES, dataSourceName); } /** * Create data source. * @param dataSourceName The data source name * @param addresses The list of coord addresses for the target sequoiadb cluster, spearated by ',' * @param user User name of the data source * @param password User password of the data source * @param type Data source type, default is "SequoiaDB" * @param option Optional configuration option for create data source, as follows: *
    *
  • AccessMode(String) : Configure access permissions for the data source, default is "ALL", * the values are as follows: *
      *
    • "READ" : Allow read-only operation *
    • "WRITE" : Allow write-only operation *
    • "ALL" or "READ|WRITE" : Allow all operations *
    • "NONE" : Neither read nor write operation is allowed *
    *
  • ErrorFilterMask(String) : Configure error filtering for data operations on data sources, * default is "NONE", the values are as follows: *
      *
    • "READ" : Filter data read errors *
    • "WRITE" : Filter data write errors *
    • "ALL" or "READ|WRITE" : Filter both data read and write errors *
    • "NONE" : Do not filter any errors *
    *
  • ErrorControlLevel(String) : Configure the error control level when performing unsupported data * operations(such as DDL) on the mapping collection or collection space, default is "low", * the values are as follows: *
      *
    • "high" : Report an error and output an error message *
    • "low" : Ignore unsupported data operations and do not execute on data source *
    *
  • TransPropagateMode(String) : Configure the transaction propagation mode on data source, * default is "never", the values are as follows: *
      *
    • "never": Transaction operation is forbidden. Report an error and output and error message. *
    • "notsupport": Transaction operation is not supported on data source. The operation * will be converted to non-transactional and send to data source. *
    *
  • InheritSessionAttr(Bool): Configure whether the session between the coordination node and the * data source inherits properties of the local session, default is true. The supported attributes include PreferedInstance, PreferedInstanceMode, PreferedStrict, PreferedPeriod and Timeout. *
* @return A data source object * @throws BaseException If error happens. */ public DataSource createDataSource(String dataSourceName, String addresses, String user, String password, String type, BSONObject option) throws BaseException { if (dataSourceName == null || dataSourceName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "data source name is empty or null"); } if (addresses == null || addresses.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "data source address list is empty or null"); } if ( type == null || type.equals("")){ type = "SequoiaDB"; } BSONObject obj = new BasicBSONObject(); if ( option != null ) { obj.putAllUnique(option); } obj.put(SdbConstants.FIELD_NAME_NAME, dataSourceName); obj.put(SdbConstants.FIELD_NAME_ADDRESS, addresses); obj.put(SdbConstants.FIELD_NAME_USER, user); obj.put(SdbConstants.FIELD_NAME_PASSWD, Helper.md5(password)); obj.put(SdbConstants.FIELD_NAME_TYPE, type); AdminRequest request = new AdminRequest(AdminCommand.CREATE_DATASOURCE, obj); SdbReply response = requestAndResponse(request); throwIfError(response); return new DataSource(this, dataSourceName); } /** * Drop data source. * * @param dataSourceName The data source name * @throws BaseException If error happens. */ public void dropDataSource(String dataSourceName) throws BaseException { if (dataSourceName == null || dataSourceName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, "data source name is empty or null"); } BSONObject obj = new BasicBSONObject(SdbConstants.FIELD_NAME_NAME, dataSourceName); AdminRequest request = new AdminRequest(AdminCommand.DROP_DATASOURCE, obj); SdbReply response = requestAndResponse(request); throwIfError(response); } /** * List data source. * * @param matcher The matching rule, return all the records if null * @param selector The selective rule, return the whole records if null * @param orderBy The ordered rule, never sort if null * @param hint Reserved, please specify null * @return Cursor of data source information * @throws BaseException If error happens. */ public DBCursor listDataSources(BSONObject matcher, BSONObject selector, BSONObject orderBy, BSONObject hint) throws BaseException { return getList(SDB_LIST_DATASOURCES, matcher, selector, orderBy); } /** * Get data source. * * @param dataSourceName The data source name * @return The data source object * @throws BaseException If error happens. */ public DataSource getDataSource(String dataSourceName) throws BaseException { if (isDataSourceExist(dataSourceName)) { return new DataSource(this, dataSourceName); } else { throw new BaseException(SDBError.SDB_CAT_DATASOURCE_NOTEXIST, dataSourceName); } } private boolean _checkIsExistByList(int listType, String targetName) throws BaseException { if (null == targetName || targetName.equals("")) { throw new BaseException(SDBError.SDB_INVALIDARG, targetName); } BSONObject matcher = new BasicBSONObject(); matcher.put(SdbConstants.FIELD_NAME_NAME, targetName); DBCursor cursor = getList(listType, matcher, null, null); try { if (cursor != null && cursor.hasNext()) { return true; } else { return false; } } finally { if (cursor != null) { cursor.close(); } } } 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_BACKUPS: return AdminCommand.LIST_BACKUPS; case SDB_LIST_DATASOURCES: return AdminCommand.LIST_DATASOURCES; 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 { if (name == null || name.isEmpty()) { throw new BaseException(SDBError.SDB_INVALIDARG, "name is null or empty"); } 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(ByteBuffer buffer) { try { byte[] lengthBytes = connection.receive(4); int length = ByteBuffer.wrap(lengthBytes).order(byteOrder).getInt(); buffer = Helper.resetBuff(buffer, length, byteOrder); System.arraycopy(lengthBytes, 0, buffer.array(), 0, lengthBytes.length); connection.receive(buffer.array(), 4, length - 4); }catch (Exception e){ connection.close(); throw new BaseException(SDBError.SDB_NETWORK, "Failed to receive message.", e); } 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 void resetRequestBuff(int len) { requestBuffer = Helper.resetBuff(requestBuffer, len, byteOrder); } protected void cleanRequestBuff(){ requestBuffer = null; } private ByteBuffer encodeRequest(Request request) { resetRequestBuff(request.length()); request.setRequestId(getNextRequestId()); request.encode(requestBuffer); return requestBuffer; } 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, ByteBuffer buff) { if (!isClosed()) { connection.send(request); lastUseTime = System.currentTimeMillis(); return receiveSdbResponse(buff); } else { throw new BaseException(SDBError.SDB_NOT_CONNECTED); } } SdbReply requestAndResponse(SdbRequest request) { return requestAndResponse(request, SdbReply.class); } T requestAndResponse(SdbRequest request, Class tClass) { return requestAndResponse(request, tClass, null); } T requestAndResponse(SdbRequest request, Class tClass, ByteBuffer buff) { ByteBuffer out = encodeRequest(request); ByteBuffer in = sendAndReceive(out, buff); T response = decodeResponse(in, tClass); validateResponse(request, response); return response; } 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 { cleanRequestBuff(); connection.close(); } } /** * Get the connection proxy object, which can be used to update the configuration * of the connection object. * * @return The connection proxy object */ public ConnectionProxy getConnProxy(){ return connProxy; } /** * 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