2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 package com.mysql.clusterj.tie;
20 import java.util.IdentityHashMap;
23 import com.mysql.ndbjtie.ndbapi.Ndb;
24 import com.mysql.ndbjtie.ndbapi.Ndb_cluster_connection;
26 import com.mysql.clusterj.ClusterJDatastoreException;
27 import com.mysql.clusterj.ClusterJFatalInternalException;
29 import com.mysql.clusterj.core.store.Db;
31 import com.mysql.clusterj.core.util.I18NHelper;
32 import com.mysql.clusterj.core.util.Logger;
33 import com.mysql.clusterj.core.util.LoggerFactoryService;
38 public class ClusterConnectionImpl
39 implements com.mysql.clusterj.core.store.ClusterConnection {
41 /** My message translator */
42 static final I18NHelper local = I18NHelper.getInstance(ClusterConnectionImpl.class);
45 static final Logger logger = LoggerFactoryService.getFactory()
46 .getInstance(com.mysql.clusterj.core.store.ClusterConnection.class);
48 /** Load the ndbjtie system library */
50 loadSystemLibrary("ndbclient");
51 // initialize the charset map
52 Utility.getCharsetMap();
55 /** Ndb_cluster_connection is wrapped by ClusterConnection */
56 protected Ndb_cluster_connection clusterConnection;
58 /** The connection string for this connection */
59 final String connectString;
61 /** The node id requested for this connection; 0 for default */
64 /** All dbs given out by this cluster connection */
65 private Map<DbImpl, Object> dbs = new IdentityHashMap<DbImpl, Object>();
67 /** Connect to the MySQL Cluster
69 * @param connectString the connect string
70 * @param nodeId the node id; node id of zero means "any node"
72 public ClusterConnectionImpl(String connectString, int nodeId) {
73 this.connectString = connectString;
75 clusterConnection = Ndb_cluster_connection.create(connectString, nodeId);
76 handleError(clusterConnection, connectString, nodeId);
77 logger.info(local.message("INFO_Create_Cluster_Connection", connectString, nodeId));
80 static protected void loadSystemLibrary(String name) {
84 System.loadLibrary(name);
85 } catch (UnsatisfiedLinkError e) {
86 path = getLoadLibraryPath();
87 message = local.message("ERR_Failed_Loading_Library",
88 name, path, "UnsatisfiedLinkError", e.getLocalizedMessage());
89 logger.fatal(message);
91 } catch (SecurityException e) {
92 path = getLoadLibraryPath();
93 message = local.message("ERR_Failed_Loading_Library",
94 name, path, "SecurityException", e.getLocalizedMessage());
95 logger.fatal(message);
101 * @return the load library path or the Exception string
103 private static String getLoadLibraryPath() {
106 path = System.getProperty("java.library.path");
107 } catch (Exception ex) {
108 path = "<Exception: " + ex.getMessage() + ">";
114 public void connect(int connectRetries, int connectDelay, boolean verbose) {
116 int returnCode = clusterConnection.connect(connectRetries, connectDelay, verbose?1:0);
117 handleError(returnCode, clusterConnection, connectString, nodeId);
120 public Db createDb(String database, int maxTransactions) {
123 // synchronize because create is not guaranteed thread-safe
125 ndb = Ndb.create(clusterConnection, database, "def");
126 handleError(ndb, clusterConnection, connectString, nodeId);
128 DbImpl result = new DbImpl(this, ndb, maxTransactions);
129 dbs.put(result, null);
133 public void waitUntilReady(int connectTimeoutBefore, int connectTimeoutAfter) {
135 int returnCode = clusterConnection.wait_until_ready(connectTimeoutBefore, connectTimeoutAfter);
136 handleError(returnCode, clusterConnection, connectString, nodeId);
139 private void checkConnection() {
140 if (clusterConnection == null) {
141 throw new ClusterJFatalInternalException(local.message("ERR_Cluster_Connection_Must_Not_Be_Null"));
145 protected static void handleError(int returnCode, Ndb_cluster_connection clusterConnection,
146 String connectString, int nodeId) {
147 if (returnCode >= 0) {
151 throwError(returnCode, clusterConnection, connectString, nodeId);
153 // all errors on Ndb_cluster_connection are fatal
154 Ndb_cluster_connection.delete(clusterConnection);
159 protected static void handleError(Object object, Ndb_cluster_connection clusterConnection,
160 String connectString, int nodeId) {
161 if (object != null) {
164 throwError(null, clusterConnection, connectString, nodeId);
168 protected static void handleError(Ndb_cluster_connection clusterConnection, String connectString, int nodeId) {
169 if (clusterConnection == null) {
170 String message = local.message("ERR_Connect", connectString, nodeId);
171 logger.error(message);
172 throw new ClusterJDatastoreException(message);
176 protected static void throwError(Object returnCode, Ndb_cluster_connection clusterConnection,
177 String connectString, int nodeId) {
178 String message = clusterConnection.get_latest_error_msg();
179 int errorCode = clusterConnection.get_latest_error();
180 String msg = local.message("ERR_NdbError", returnCode, errorCode, message, connectString, nodeId);
181 throw new ClusterJDatastoreException(msg);
184 public void close() {
185 if (clusterConnection != null) {
186 logger.info(local.message("INFO_Close_Cluster_Connection", connectString, nodeId));
187 Ndb_cluster_connection.delete(clusterConnection);
188 clusterConnection = null;
192 public void close(Db db) {
196 public int dbCount() {