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.jdbc;
20 import com.mysql.clusterj.ClusterJFatalInternalException;
21 import com.mysql.clusterj.ClusterJUserException;
23 import com.mysql.clusterj.core.metadata.AbstractDomainTypeHandlerImpl;
24 import com.mysql.clusterj.core.metadata.IndexHandlerImpl;
26 import com.mysql.clusterj.core.spi.DomainFieldHandler;
27 import com.mysql.clusterj.core.spi.ValueHandler;
29 import com.mysql.clusterj.core.store.Column;
30 import com.mysql.clusterj.core.store.Dictionary;
31 import com.mysql.clusterj.core.store.Index;
32 import com.mysql.clusterj.core.store.Table;
34 import com.mysql.clusterj.core.util.I18NHelper;
35 import com.mysql.clusterj.core.util.Logger;
36 import com.mysql.clusterj.core.util.LoggerFactoryService;
38 import java.lang.reflect.Proxy;
39 import java.util.Arrays;
40 import java.util.HashMap;
43 /** This instance manages the persistent representation of a jdbc statement or result set.
44 * The class also provides the factory for DomainTypeHandlers via the static method
45 * getDomainTypeHandler(String tableName, Dictionary dictionary).
46 * @param T the class of the persistence-capable type
48 public class DomainTypeHandlerImpl<T> extends AbstractDomainTypeHandlerImpl<T> {
50 /** My message translator */
51 static final I18NHelper local = I18NHelper.getInstance(DomainTypeHandlerImpl.class);
54 static final Logger logger = LoggerFactoryService.getFactory().getInstance(DomainTypeHandlerImpl.class);
56 /** The map of table name to DomainTypeHandler */
57 static Map<String, DomainTypeHandlerImpl<?>> domainTypeHandlerMap = new HashMap<String, DomainTypeHandlerImpl<?>>();
59 /** Find a domain type handler by table name or create a new one.
60 * If the table does not exist in ndb, return null.
61 * @param tableName the name of the table
62 * @param dictionary the dictionary
63 * @return the domain type handle for the table or null if the table does not exist in ndb
65 public static DomainTypeHandlerImpl<?> getDomainTypeHandler(String tableName, Dictionary dictionary) {
66 DomainTypeHandlerImpl<?> result = null;
67 synchronized (domainTypeHandlerMap) {
68 result = domainTypeHandlerMap.get(tableName);
70 Table table = dictionary.getTable(tableName);
72 result = new DomainTypeHandlerImpl(tableName, dictionary);
73 domainTypeHandlerMap.put(tableName, result);
74 if (logger.isDetailEnabled()) logger.detail("New DomainTypeHandler created for table " + tableName);
76 if (logger.isDetailEnabled()) logger.detail("DomainTypeHandler for table " + tableName
77 + " not created; table is not an ndb table.");
80 if (logger.isDetailEnabled()) logger.detail("Found DomainTypeHandler for table " + tableName);
86 /** Construct a DomainTypeHandler for a table. Find primary key columns, partition key columns,
87 * and indexes. Construct a DomainTypeHandler for each column in the table.
89 protected DomainTypeHandlerImpl(String tableName, Dictionary dictionary) {
90 if (logger.isDebugEnabled()) logger.debug("New JDBC DomainTypeHandlerImpl for table " + tableName);
91 this.tableName = tableName;
92 this.table = dictionary.getTable(tableName);
94 throw new ClusterJUserException(local.message("ERR_Get_NdbTable", tableName, tableName));
96 String[] columnNames = table.getColumnNames();
97 fieldNames = columnNames;
98 if (logger.isDebugEnabled()) logger.debug("Found Table for " + tableName
99 + " with columns " + Arrays.toString(columnNames));
100 // the id field handlers will be initialized via registerPrimaryKeyColumn
101 this.primaryKeyColumnNames = table.getPrimaryKeyColumnNames();
102 this.numberOfIdFields = primaryKeyColumnNames.length;
103 this.idFieldHandlers = new DomainFieldHandlerImpl[numberOfIdFields];
104 this.idFieldNumbers = new int[numberOfIdFields];
105 // the partition key field handlers will be initialized via registerPrimaryKeyColumn
106 this.partitionKeyColumnNames = table.getPartitionKeyColumnNames();
107 this.numberOfPartitionKeyColumns = partitionKeyColumnNames.length;
108 this.partitionKeyFieldHandlers = new DomainFieldHandlerImpl[numberOfPartitionKeyColumns];
110 // Process indexes for the table. There might not be a field associated with the index.
111 // The first entry in indexHandlerImpls is for the mandatory hash primary key,
112 // which is not really an index but is treated as an index by query.
113 Index primaryIndex = dictionary.getIndex("PRIMARY$KEY", tableName, "PRIMARY");
114 IndexHandlerImpl primaryIndexHandler =
115 new IndexHandlerImpl(this, dictionary, primaryIndex, primaryKeyColumnNames);
116 indexHandlerImpls.add(primaryIndexHandler);
118 String[] indexNames = table.getIndexNames();
119 for (String indexName: indexNames) {
120 // the index alias is the name as known by the user (without the $unique suffix)
121 String indexAlias = removeUniqueSuffix(indexName);
122 Index index = dictionary.getIndex(indexName, tableName, indexAlias);
123 String[] indexColumnNames = index.getColumnNames();
124 IndexHandlerImpl imd = new IndexHandlerImpl(this, dictionary, index, indexColumnNames);
125 indexHandlerImpls.add(imd);
128 // Now iterate the columns in the table, creating a DomainFieldHandler for each column
129 for (String columnName: columnNames) {
130 Column column = table.getColumn(columnName);
131 DomainFieldHandler domainFieldHandler = new DomainFieldHandlerImpl(this, table,
132 numberOfFields++, column);
133 fieldNameToNumber.put(domainFieldHandler.getName(), domainFieldHandler.getFieldNumber());
134 persistentFieldHandlers.add(domainFieldHandler);
135 if (!column.isPrimaryKey()) {
136 nonPKFieldHandlers.add(domainFieldHandler);
139 // Check that all index columnNames have corresponding fields
140 // indexes without fields will be unusable for query
141 for (IndexHandlerImpl indexHandler:indexHandlerImpls) {
142 indexHandler.assertAllColumnsHaveFields();
147 /** Is this type supported? */
148 public boolean isSupportedType() {
149 // only supported types survive construction
153 public ValueHandler getValueHandler(Object instance)
154 throws IllegalArgumentException {
155 if (instance instanceof ValueHandler) {
156 return (ValueHandler)instance;
158 ValueHandler handler = (ValueHandler)
159 Proxy.getInvocationHandler(instance);
165 public void objectResetModified(ValueHandler handler) {
166 // ignore this for now
169 public void objectSetKeys(Object arg0, Object arg1) {
170 throw new ClusterJFatalInternalException("Not implemented.");