View Javadoc

1   /*
2    * Copyright (c) 2011.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.hbql.impl;
22  
23  import org.apache.hadoop.hbase.hbql.client.HBqlException;
24  import org.apache.hadoop.hbase.hbql.client.HMapping;
25  import org.apache.hadoop.hbase.hbql.client.HPreparedStatement;
26  import org.apache.hadoop.hbase.hbql.client.HRecord;
27  import org.apache.hadoop.hbase.hbql.mapping.FamilyMapping;
28  import org.apache.hadoop.hbase.hbql.mapping.TableMapping;
29  import org.apache.hadoop.hbase.hbql.statement.args.KeyInfo;
30  import org.apache.hadoop.hbase.hbql.util.Maps;
31  import org.apache.hadoop.hbase.hbql.util.Sets;
32  
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  
37  public class MappingManager {
38  
39      private static final String SYSTEM_MAPPINGS = "system_mappings";
40  
41      private final HConnectionImpl connection;
42      private final Map<String, TableMapping> userMappingsMap   = Maps.newConcurrentHashMap();
43      private final Map<String, TableMapping> systemMappingsMap = Maps.newConcurrentHashMap();
44      private final Map<String, TableMapping> cachedMappingsMap = Maps.newConcurrentHashMap();
45  
46      public MappingManager(final HConnectionImpl conn) {
47          this.connection = conn;
48      }
49  
50      public void clear() {
51          this.getUserMappingsMap().clear();
52          this.getCachedMappingsMap().clear();
53      }
54  
55      public synchronized void validatePersistentMetadata() throws HBqlException {
56  
57          final String sql1 = "CREATE TEMP SYSTEM MAPPING " + SYSTEM_MAPPINGS
58                              + " (mapping_name KEY, f1(mapping_obj object alias mapping_obj))";
59          this.getConnection().execute(sql1);
60  
61          if (!this.getConnection().tableExists(SYSTEM_MAPPINGS)) {
62              final String sql2 = "CREATE TABLE " + SYSTEM_MAPPINGS + " (f1(MAX_VERSIONS: 1))";
63              this.getConnection().execute(sql2);
64          }
65      }
66  
67      private HConnectionImpl getConnection() {
68          return this.connection;
69      }
70  
71      private Map<String, TableMapping> getUserMappingsMap() {
72          return this.userMappingsMap;
73      }
74  
75      private Map<String, TableMapping> getSystemMappingsMap() {
76          return this.systemMappingsMap;
77      }
78  
79      private Map<String, TableMapping> getCachedMappingsMap() {
80          return this.cachedMappingsMap;
81      }
82  
83      public Set<HMapping> getAllMappings() throws HBqlException {
84  
85          final Set<HMapping> names = Sets.newHashSet();
86          names.addAll(getUserMappingsMap().values());
87          names.addAll(getSystemMappingsMap().values());
88  
89          final String sql = "SELECT mapping_obj FROM " + SYSTEM_MAPPINGS;
90          final List<HRecord> recs = this.getConnection().executeQueryAndFetch(sql);
91          for (final HRecord rec : recs)
92              names.add((TableMapping)rec.getCurrentValue("mapping_obj"));
93          return names;
94      }
95  
96      public synchronized boolean mappingExists(final String mappingName) throws HBqlException {
97  
98          if (this.getUserMappingsMap().get(mappingName) != null)
99              return true;
100         else if (this.getSystemMappingsMap().get(mappingName) != null)
101             return true;
102         else {
103             // Do not check cached mappings map, go to the server for answer
104             final String sql = "SELECT mapping_name FROM " + SYSTEM_MAPPINGS + " WITH KEYS ?";
105             final HPreparedStatement stmt = this.getConnection().prepareStatement(sql);
106             ((HStatementImpl)stmt).setIgnoreQueryExecutor(true);
107             stmt.setParameter(1, mappingName);
108             final List<HRecord> recs = stmt.executeQueryAndFetch();
109             stmt.close();
110             final boolean retval = recs.size() > 0;
111 
112             if (!retval) {
113                 // Remove from cached mappings map if it was dropped by another user
114                 if (this.getCachedMappingsMap().containsKey(mappingName))
115                     this.getCachedMappingsMap().remove(mappingName);
116             }
117 
118             return retval;
119         }
120     }
121 
122     public synchronized boolean dropMapping(final String mappingName) throws HBqlException {
123 
124         if (this.getUserMappingsMap().containsKey(mappingName)) {
125             this.getUserMappingsMap().remove(mappingName);
126             return true;
127         }
128         else if (this.getSystemMappingsMap().containsKey(mappingName)) {
129             this.getSystemMappingsMap().remove(mappingName);
130             return true;
131         }
132         else {
133             // Remove from cached mappings map
134             if (this.getCachedMappingsMap().containsKey(mappingName))
135                 this.getCachedMappingsMap().remove(mappingName);
136 
137             final String sql = "DELETE FROM " + SYSTEM_MAPPINGS + " WITH KEYS ?";
138             final HPreparedStatement stmt = this.getConnection().prepareStatement(sql);
139             stmt.setParameter(1, mappingName);
140             final int cnt = stmt.executeUpdate().getCount();
141             return cnt > 0;
142         }
143     }
144 
145     public synchronized TableMapping createMapping(final boolean isTemp,
146                                                    final boolean isSystem,
147                                                    final String mappingName,
148                                                    final String tableName,
149                                                    final KeyInfo keyInfo,
150                                                    final List<FamilyMapping> familyMappingList) throws HBqlException {
151 
152         if (!mappingName.equals(SYSTEM_MAPPINGS) && this.mappingExists(mappingName))
153             throw new HBqlException("Mapping already defined: " + mappingName);
154 
155         final TableMapping tableMapping = new TableMapping(this.getConnection(),
156                                                            isTemp,
157                                                            isSystem,
158                                                            mappingName,
159                                                            tableName,
160                                                            keyInfo,
161                                                            familyMappingList);
162 
163         if (tableMapping.isTempMapping()) {
164             if (!tableMapping.isSystemMapping())
165                 this.getUserMappingsMap().put(mappingName, tableMapping);
166             else
167                 this.getSystemMappingsMap().put(mappingName, tableMapping);
168         }
169         else {
170             this.getCachedMappingsMap().put(mappingName, tableMapping);
171 
172             final String sql = "INSERT INTO " + SYSTEM_MAPPINGS + " (mapping_name, mapping_obj) VALUES (?, ?)";
173             final HPreparedStatement stmt = this.getConnection().prepareStatement(sql);
174             stmt.setParameter(1, tableMapping.getMappingName());
175             stmt.setParameter(2, tableMapping);
176             stmt.execute();
177         }
178 
179         return tableMapping;
180     }
181 
182     public TableMapping getMapping(final String mappingName) throws HBqlException {
183 
184         if (this.getUserMappingsMap().containsKey(mappingName)) {
185             return this.getUserMappingsMap().get(mappingName);
186         }
187         else if (this.getSystemMappingsMap().containsKey(mappingName)) {
188             return this.getSystemMappingsMap().get(mappingName);
189         }
190         else if (this.getCachedMappingsMap().containsKey(mappingName)) {
191             return this.getCachedMappingsMap().get(mappingName);
192         }
193         else {
194             final String sql = "SELECT mapping_obj FROM " + SYSTEM_MAPPINGS + " WITH KEYS ?";
195             final HPreparedStatement stmt = this.getConnection().prepareStatement(sql);
196             stmt.setParameter(1, mappingName);
197             List<HRecord> recs = stmt.executeQueryAndFetch();
198 
199             if (recs.size() == 0)
200                 throw new HBqlException("Mapping not found: " + mappingName);
201             else
202                 return (TableMapping)recs.get(0).getCurrentValue("mapping_obj");
203         }
204     }
205 }