]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
a1355f1983d98254d89acd1e480487457a2eda15
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2    Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3
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.
7
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.
12
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
16 */
17
18 package com.mysql.clusterj.jdbc;
19
20 import com.mysql.clusterj.ClusterJFatalInternalException;
21 import com.mysql.clusterj.ClusterJUserException;
22
23 import com.mysql.clusterj.core.metadata.AbstractDomainTypeHandlerImpl;
24 import com.mysql.clusterj.core.metadata.IndexHandlerImpl;
25
26 import com.mysql.clusterj.core.spi.DomainFieldHandler;
27 import com.mysql.clusterj.core.spi.ValueHandler;
28
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;
33
34 import com.mysql.clusterj.core.util.I18NHelper;
35 import com.mysql.clusterj.core.util.Logger;
36 import com.mysql.clusterj.core.util.LoggerFactoryService;
37
38 import java.lang.reflect.Proxy;
39 import java.util.Arrays;
40 import java.util.HashMap;
41 import java.util.Map;
42
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
47  */
48 public class DomainTypeHandlerImpl<T> extends AbstractDomainTypeHandlerImpl<T> {
49
50     /** My message translator */
51     static final I18NHelper local = I18NHelper.getInstance(DomainTypeHandlerImpl.class);
52
53     /** My logger */
54     static final Logger logger = LoggerFactoryService.getFactory().getInstance(DomainTypeHandlerImpl.class);
55
56     /** The map of table name to DomainTypeHandler */
57     static Map<String, DomainTypeHandlerImpl<?>> domainTypeHandlerMap = new HashMap<String, DomainTypeHandlerImpl<?>>();
58
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
64      */
65     public static DomainTypeHandlerImpl<?> getDomainTypeHandler(String tableName, Dictionary dictionary) {
66         DomainTypeHandlerImpl<?> result = null;
67         synchronized (domainTypeHandlerMap) {
68             result = domainTypeHandlerMap.get(tableName);
69             if (result == null) {
70                 Table table = dictionary.getTable(tableName);
71                 if (table != null) {
72                     result = new DomainTypeHandlerImpl(tableName, dictionary);
73                     domainTypeHandlerMap.put(tableName, result);
74                     if (logger.isDetailEnabled()) logger.detail("New DomainTypeHandler created for table " + tableName);
75                 } else {
76                     if (logger.isDetailEnabled()) logger.detail("DomainTypeHandler for table " + tableName
77                             + " not created; table is not an ndb table.");
78                 }
79             } else {
80                 if (logger.isDetailEnabled()) logger.detail("Found DomainTypeHandler for table " + tableName);
81             }
82         }
83         return result;
84     }
85
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.
88      */
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);
93         if (table == null) {
94             throw new ClusterJUserException(local.message("ERR_Get_NdbTable", tableName, tableName));
95         }
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];
109
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);
117
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);
126         }
127
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);
137             }
138         }
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();
143         }
144
145     }
146
147     /** Is this type supported? */
148     public boolean isSupportedType() {
149         // only supported types survive construction
150         return true;
151     }
152
153     public ValueHandler getValueHandler(Object instance)
154             throws IllegalArgumentException {
155         if (instance instanceof ValueHandler) {
156             return (ValueHandler)instance;
157         } else {
158             ValueHandler handler = (ValueHandler)
159                     Proxy.getInvocationHandler(instance);
160             return handler;
161         }
162     }
163
164     @Override
165     public void objectResetModified(ValueHandler handler) {
166         // ignore this for now
167     }
168
169     public void objectSetKeys(Object arg0, Object arg1) {
170         throw new ClusterJFatalInternalException("Not implemented.");
171     }
172 }