1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.healthmarketscience.jackcess.impl;
18
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import com.healthmarketscience.jackcess.TableMetaData;
28 import com.healthmarketscience.jackcess.query.Query;
29
30
31
32
33
34
35
36
37
38 public class QueryNameMapImpl extends NameMapImpl
39 {
40
41 private final DatabaseImpl _database;
42
43 private QueryNameMapImpl(byte[] bytes, DatabaseImpl database)
44 throws IOException
45 {
46 super(bytes);
47 _database = database;
48 }
49
50
51
52
53
54
55
56 public static QueryNameMapImpl read(byte[] bytes, DatabaseImpl database)
57 throws IOException
58 {
59 return new QueryNameMapImpl(bytes, database);
60 }
61
62 @Override
63 protected boolean isWritable() {
64 return false;
65 }
66
67
68
69
70
71
72
73
74
75
76 @Override
77 public List<Mismatch> findMismatches() throws IOException {
78 DatabaseImpl db = _database;
79 List<Mismatch> mismatches = new ArrayList<>();
80 Map<String,TableImpl> tablesByGuid = null;
81
82
83 Map<String,TableImpl> recordTables = new HashMap<>();
84
85
86 Set<String> skippedGuids = new HashSet<>();
87 SourceQueries queries = null;
88
89 for(RecordImpl rec : _records) {
90 if(rec._type == TABLE_TYPE) {
91 if(tablesByGuid == null) {
92 tablesByGuid = readTablesByGuid(db);
93 }
94 String guid = rec.getGuid();
95 TableImpl table = ((guid != null) ?
96 tablesByGuid.get(toGuidKey(guid)) : null);
97 if(table != null) {
98 recordTables.put(toGuidKey(guid), table);
99 if(!rec._name.equals(table.getName())) {
100 mismatches.add(new MismatchImpl(MismatchType.NAME_DIFFERS, table,
101 null, rec));
102 }
103 continue;
104 }
105
106 if(queries == null) {
107 queries = new SourceQueries(db);
108 }
109 Query query = ((guid != null) ? queries.getByGuid(guid) : null);
110 if(query != null) {
111 skippedGuids.add(toGuidKey(guid));
112 if(!rec._name.equals(query.getName())) {
113 mismatches.add(new MismatchImpl(MismatchType.NAME_DIFFERS, query,
114 rec));
115 }
116 continue;
117 }
118
119 TableMetaData metaData = db.getTableMetaData(rec._name);
120 if(metaData == null) {
121 query = queries.getByName(rec._name);
122 if(query == null) {
123 mismatches.add(new MismatchImpl(MismatchType.MISSING_OBJECT, null,
124 null, rec));
125 continue;
126 }
127 if(getGuid(query.getProperties()) != null) {
128 mismatches.add(new MismatchImpl(MismatchType.GUID_DIFFERS, query,
129 rec));
130 }
131 }
132 if((metaData == null) || metaData.isLinked()) {
133 if(guid != null) {
134 skippedGuids.add(toGuidKey(guid));
135 }
136 continue;
137 }
138
139
140 table = db.getTable(rec._name, true);
141 if(guid != null) {
142 recordTables.put(toGuidKey(guid), table);
143 }
144 if(getGuid(table.getProperties()) != null) {
145 mismatches.add(new MismatchImpl(MismatchType.GUID_DIFFERS, table,
146 null, rec));
147 }
148
149 } else if(rec._type == COLUMN_TYPE) {
150 String parentGuid = rec.getParentGuid();
151 String parentKey = ((parentGuid != null) ? toGuidKey(parentGuid) :
152 null);
153 if(skippedGuids.contains(parentKey)) {
154 continue;
155 }
156 TableImpl table = recordTables.get(parentKey);
157 if(table == null) {
158 mismatches.add(new MismatchImpl(MismatchType.MISSING_OBJECT, null,
159 null, rec));
160 continue;
161 }
162
163 ColumnImpl col = findColumn(table, rec.getGuid());
164 if(col != null) {
165 if(!rec._name.equals(col.getName())) {
166 mismatches.add(new MismatchImpl(MismatchType.NAME_DIFFERS, table,
167 col, rec));
168 }
169 continue;
170 }
171
172 col = (table.hasColumn(rec._name) ? table.getColumn(rec._name) :
173 null);
174 if(col == null) {
175 mismatches.add(new MismatchImpl(MismatchType.MISSING_OBJECT, table,
176 null, rec));
177 } else if(getGuid(col.getProperties()) != null) {
178 mismatches.add(new MismatchImpl(MismatchType.GUID_DIFFERS, table,
179 col, rec));
180 }
181 }
182 }
183
184 return mismatches;
185 }
186
187
188
189
190 private static Map<String,TableImpl> readTablesByGuid(DatabaseImpl db)
191 throws IOException
192 {
193 Map<String,TableImpl> tables = new HashMap<>();
194 for(String name : db.getTableNames()) {
195 if(db.getTableMetaData(name).isLinked()) {
196 continue;
197 }
198 TableImpl table = db.getTable(name);
199 String guid = getGuid(table.getProperties());
200 if(guid != null) {
201 tables.put(toGuidKey(guid), table);
202 }
203 }
204 return tables;
205 }
206
207
208
209
210
211 private static final class SourceQueries
212 {
213 private final Map<String,Query> _byGuid = new HashMap<>();
214 private final Map<String,Query> _byName = new HashMap<>();
215
216 private SourceQueries(DatabaseImpl db) throws IOException {
217 for(Query query : db.getQueries()) {
218 _byName.put(DatabaseImpl.toLookupName(query.getName()), query);
219 String guid = getGuid(query.getProperties());
220 if(guid != null) {
221 _byGuid.put(toGuidKey(guid), query);
222 }
223 }
224 }
225
226 private Query getByGuid(String guid) {
227 return _byGuid.get(toGuidKey(guid));
228 }
229
230 private Query getByName(String name) {
231 return _byName.get(DatabaseImpl.toLookupName(name));
232 }
233 }
234
235 private static ColumnImpl findColumn(TableImpl table, String guid)
236 throws IOException
237 {
238 for(ColumnImpl col : table.getColumns()) {
239 String colGuid = getGuid(col.getProperties());
240 if((colGuid != null) && colGuid.equalsIgnoreCase(guid)) {
241 return col;
242 }
243 }
244 return null;
245 }
246 }