com.sequoiadb.base.Sequoiadb Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sequoiadb-driver Show documentation
Show all versions of sequoiadb-driver Show documentation
Java client driver for SequoiaDB
/*
* Copyright 2018 SequoiaDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.sequoiadb.base;
import 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;
}
}
}