1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
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
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
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 }