Skip to content

Commit fff085c

Browse files
committed
adds JdbcSchemaLoader
1 parent 83f3f97 commit fff085c

12 files changed

Lines changed: 769 additions & 73 deletions

File tree

hyperquery/src/main/java/org/slowcoders/hyperquery/core/QInlineView.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
import org.slowcoders.hyperquery.impl.HModel;
44
import org.slowcoders.hyperquery.impl.HSchema;
5+
import org.slowcoders.hyperquery.impl.JdbcConnector;
56
import org.slowcoders.hyperquery.impl.ViewResolver;
67

7-
import java.sql.Connection;
8-
98
public class QInlineView extends HModel {
109

1110
private final String viewDefinition;
@@ -15,7 +14,7 @@ public QInlineView(String query) {
1514
}
1615

1716
@Override
18-
protected HSchema loadSchema(Connection dbConn) {
17+
protected HSchema loadSchema(JdbcConnector dbConn) {
1918
return HSchema.loadSchema((Class)QEntity.class, false, dbConn);
2019
}
2120

hyperquery/src/main/java/org/slowcoders/hyperquery/core/QJoin.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import org.slowcoders.hyperquery.impl.AliasNode;
44
import org.slowcoders.hyperquery.impl.HModel;
55
import org.slowcoders.hyperquery.impl.HSchema;
6-
7-
import java.sql.Connection;
6+
import org.slowcoders.hyperquery.impl.JdbcConnector;
87

98
public class QJoin extends AliasNode {
109

@@ -39,7 +38,7 @@ public String getJoinCriteria() {
3938
}
4039
public boolean isToUnique() { return toUnique; }
4140

42-
public HModel getTargetRelation(Connection dbConn) {
41+
public HModel getTargetRelation(JdbcConnector dbConn) {
4342
if (model == null) {
4443
model = HSchema.loadSchema(viewType, false, dbConn);
4544
}

hyperquery/src/main/java/org/slowcoders/hyperquery/core/QMapperView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import org.slowcoders.hyperquery.impl.HModel;
44
import org.slowcoders.hyperquery.impl.HSchema;
5+
import org.slowcoders.hyperquery.impl.JdbcConnector;
56
import org.slowcoders.hyperquery.impl.ViewResolver;
67

7-
import java.sql.Connection;
88
import java.util.Map;
99

1010
public class QMapperView<R extends QRecord<?>> extends HModel {
@@ -37,7 +37,7 @@ public QMapperView(Class<R> recordType, String namespace, String sqlId, Map<Stri
3737
}
3838

3939
@Override
40-
protected HSchema loadSchema(Connection dbConn) {
40+
protected HSchema loadSchema(JdbcConnector dbConn) {
4141
if (schema == null) {
4242
schema = HSchema.loadSchema(recordType, false, dbConn);
4343
}

hyperquery/src/main/java/org/slowcoders/hyperquery/impl/HModel.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
import org.slowcoders.hyperquery.core.*;
44

5+
import java.lang.reflect.Field;
56
import java.sql.Connection;
7+
import java.sql.SQLException;
68

79
public abstract class HModel {
810

9-
public void initialize() {
11+
public void initialize(Connection conn) throws SQLException {
1012
}
1113

12-
protected abstract HSchema loadSchema(Connection dbConn);
14+
protected abstract HSchema loadSchema(JdbcConnector dbConn);
1315

1416
protected abstract String getTableName();
1517

@@ -19,12 +21,15 @@ protected QAttribute getAttribute(String property) {
1921
return null;
2022
}
2123

22-
protected QJoin getJoin(String alias, Connection dbConn) {
24+
protected QJoin getJoin(String alias, JdbcConnector dbConn) {
2325
return null;
2426
}
2527

2628
protected QLambda getLambda(String alias) {
2729
return null;
2830
}
2931

32+
public String getColumnExpr(Field f) {
33+
return HSchema.Helper.getColumnName(f);
34+
}
3035
}

hyperquery/src/main/java/org/slowcoders/hyperquery/impl/HSchema.java

Lines changed: 71 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
import jakarta.persistence.Column;
44
import org.slowcoders.hyperquery.core.*;
5+
import org.slowcoders.hyperquery.impl.jdbc.JdbcColumn;
6+
import org.slowcoders.hyperquery.impl.jdbc.JdbcSchemaLoader;
7+
import org.slowcoders.hyperquery.impl.jdbc.PGSchemaLoader;
58

69
import java.lang.reflect.Field;
710
import java.lang.reflect.Modifier;
811
import java.lang.reflect.ParameterizedType;
912
import java.lang.reflect.Type;
1013
import java.sql.Connection;
11-
import java.sql.DatabaseMetaData;
12-
import java.sql.ResultSet;
1314
import java.sql.SQLException;
1415
import java.util.ArrayList;
1516
import java.util.Collection;
@@ -24,6 +25,8 @@ public class HSchema extends HModel {
2425
private Map<String, QAttribute> attributes;
2526

2627
private static final HashMap<Class<?>, HSchema> relations = new HashMap<>();
28+
private ArrayList<JdbcColumn> jdbcColumns;
29+
private ArrayList<String> pkColumnNames;
2730

2831
private static class EmptyEntity implements QEntity<EmptyEntity> {}
2932
static {
@@ -46,7 +49,7 @@ protected HSchema(Class<? extends QRecord<?>> entityType, boolean isEntity) {
4649
public final Class<? extends QRecord<?>> getEntityType() { return entityType; }
4750

4851
public QAttribute getAttribute(String property) {
49-
this.initialize();
52+
// this.initialize(conn);
5053
return attributes.get(property);
5154
}
5255

@@ -67,9 +70,19 @@ public QLambda getLambda(String alias) {
6770
// return relation;
6871
// }
6972

70-
public synchronized void initialize() {
73+
static JdbcSchemaLoader jdbcSchemaLoader = null;
74+
public synchronized void initialize(Connection conn) throws SQLException {
7175
if (joins != null) return;
7276

77+
if (jdbcSchemaLoader == null) {
78+
jdbcSchemaLoader = new PGSchemaLoader(conn);
79+
}
80+
if (!this.tableName.isEmpty()) {
81+
JdbcSchemaLoader.TablePath tablePath = jdbcSchemaLoader.makeTablePath(tableName);
82+
this.pkColumnNames = jdbcSchemaLoader.getPrimaryKeys(conn, tablePath);
83+
this.jdbcColumns = jdbcSchemaLoader.getColumns(conn, new HashMap<>(), tablePath, pkColumnNames);
84+
}
85+
7386
HashMap<String, QJoin> joins = new HashMap<>();
7487
HashMap<String, QLambda> lambdas = new HashMap<>();
7588
HashMap<String, QAttribute> attributes = new HashMap<>();
@@ -105,7 +118,7 @@ else if (QAttribute.class.isAssignableFrom(propertyType)) {
105118
this.attributes = attributes;
106119
}
107120

108-
public static HSchema loadSchema(Class<?> clazz, boolean isEntity, Connection dbConn) {
121+
public static HSchema loadSchema(Class<?> clazz, boolean isEntity, JdbcConnector dbConn) {
109122
synchronized (relations) {
110123
HSchema schema = relations.get(clazz);
111124
if (schema != null) return schema;
@@ -142,7 +155,12 @@ public static HSchema loadSchema(Class<?> clazz, boolean isEntity, Connection db
142155
synchronized (relations) {
143156
HSchema schema = relations.get(genericClass);
144157
if (schema == null) {
145-
schema = new HSchema((Class<? extends QEntity<?>>) genericClass, isEntity);
158+
final HSchema newSchema = new HSchema((Class<? extends QEntity<?>>) genericClass, isEntity);
159+
dbConn.execute(conn -> {
160+
newSchema.initialize(conn);
161+
return null;
162+
});
163+
schema = newSchema;
146164
relations.put(genericClass, schema);
147165
}
148166
return schema;
@@ -152,7 +170,7 @@ public static HSchema loadSchema(Class<?> clazz, boolean isEntity, Connection db
152170

153171

154172
@Override
155-
protected HSchema loadSchema(Connection dbConn) {
173+
protected HSchema loadSchema(JdbcConnector dbConn) {
156174
return this;
157175
}
158176

@@ -161,8 +179,8 @@ protected String getTableName() {
161179
return this.tableName;
162180
}
163181

164-
public QJoin getJoin(String join, Connection dbConn) {
165-
this.initialize();
182+
public QJoin getJoin(String join, JdbcConnector dbConn) {
183+
// this.initialize(conn);
166184
int next = join.indexOf('@', 1);
167185
String nextJoin = null;
168186
if (next > 0) {
@@ -174,7 +192,7 @@ public QJoin getJoin(String join, Connection dbConn) {
174192
return joins.get(join);
175193
}
176194

177-
String getColumnExpr(Field f) {
195+
public String getColumnExpr(Field f) {
178196
String columnExpr = Helper.getColumnName(f);
179197
if (columnExpr != null) return columnExpr;
180198
if (this.attributes != null) {
@@ -184,49 +202,49 @@ String getColumnExpr(Field f) {
184202
return null;
185203
}
186204

187-
public static class TablePath {
188-
private final String catalog;
189-
private final String schema;
190-
private final String simpleName;
191-
192-
TablePath(String catalog, String schema, String simpleName) {
193-
this.catalog = (catalog);
194-
this.schema = (schema);
195-
this.simpleName = (simpleName);
196-
}
197-
198-
199-
public String getSimpleName() {
200-
return simpleName;
201-
}
202-
203-
public String getCatalog() {
204-
return catalog;
205-
}
206-
207-
public String getSchema() {
208-
return schema;
209-
}
210-
}
211-
private ArrayList<String> getPrimaryKeys(Connection conn, TablePath tablePath) throws SQLException {
212-
DatabaseMetaData md = conn.getMetaData();
213-
ResultSet rs = md.getPrimaryKeys(tablePath.getCatalog(), tablePath.getSchema(), tablePath.getSimpleName());
214-
ArrayList<String> keys = new ArrayList<>();
215-
int next_key_seq = 1;
216-
while (rs.next()) {
217-
String key = rs.getString("column_name");
218-
if (false) {
219-
// postgresql 에서만 동작.
220-
int seq = rs.getInt("key_seq");
221-
if (seq != next_key_seq) {
222-
throw new RuntimeException("something wrong");
223-
}
224-
next_key_seq++;
225-
}
226-
keys.add(key);
227-
}
228-
return keys;
229-
}
205+
// public static class TablePath {
206+
// private final String catalog;
207+
// private final String schema;
208+
// private final String simpleName;
209+
//
210+
// TablePath(String catalog, String schema, String simpleName) {
211+
// this.catalog = (catalog);
212+
// this.schema = (schema);
213+
// this.simpleName = (simpleName);
214+
// }
215+
//
216+
//
217+
// public String getSimpleName() {
218+
// return simpleName;
219+
// }
220+
//
221+
// public String getCatalog() {
222+
// return catalog;
223+
// }
224+
//
225+
// public String getSchema() {
226+
// return schema;
227+
// }
228+
// }
229+
// private ArrayList<String> getPrimaryKeys(Connection conn, TablePath tablePath) throws SQLException {
230+
// DatabaseMetaData md = conn.getMetaData();
231+
// ResultSet rs = md.getPrimaryKeys(tablePath.getCatalog(), tablePath.getSchema(), tablePath.getSimpleName());
232+
// ArrayList<String> keys = new ArrayList<>();
233+
// int next_key_seq = 1;
234+
// while (rs.next()) {
235+
// String key = rs.getString("column_name");
236+
// if (false) {
237+
// // postgresql 에서만 동작.
238+
// int seq = rs.getInt("key_seq");
239+
// if (seq != next_key_seq) {
240+
// throw new RuntimeException("something wrong");
241+
// }
242+
// next_key_seq++;
243+
// }
244+
// keys.add(key);
245+
// }
246+
// return keys;
247+
// }
230248

231249
static class Helper implements QEntity<Helper> {
232250
static String getColumnName(Field f) {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.slowcoders.hyperquery.impl;
2+
3+
import org.springframework.dao.DataAccessException;
4+
import org.springframework.jdbc.core.ConnectionCallback;
5+
6+
public interface JdbcConnector {
7+
8+
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException;
9+
10+
}

hyperquery/src/main/java/org/slowcoders/hyperquery/impl/QStore.java

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,21 @@
99
import org.apache.ibatis.session.Configuration;
1010
import org.mybatis.spring.SqlSessionTemplate;
1111
import org.slowcoders.hyperquery.core.*;
12+
import org.springframework.dao.DataAccessException;
13+
import org.springframework.jdbc.core.ConnectionCallback;
14+
import org.springframework.jdbc.datasource.DataSourceUtils;
1215
import org.w3c.dom.Document;
1316
import org.w3c.dom.Element;
1417
import org.w3c.dom.Node;
1518
import org.w3c.dom.NodeList;
1619

20+
import javax.sql.DataSource;
1721
import java.lang.reflect.Field;
22+
import java.sql.Connection;
23+
import java.sql.SQLException;
1824
import java.util.*;
1925

20-
public class QStore<T> implements ViewResolver {
26+
public class QStore<T> implements ViewResolver, JdbcConnector {
2127
private final Configuration configuration;
2228
private final SqlSessionTemplate sqlSessionTemplate;
2329
private final Class<? extends QRepository> repositoryType;
@@ -37,12 +43,12 @@ public <E extends QEntity<E>, R extends QRecord<E>> R selectOne(Class<R> resultT
3743

3844

3945
public <E extends QEntity<E>, R extends QRecord<E>> List<R> selectList(HModel view, Class<R> resultType, QFilter<E> filter) {
40-
HSchema viewSchema = view.loadSchema(sqlSessionTemplate.getConnection());
46+
HSchema viewSchema = view.loadSchema(this);
4147
if (filter != null && loadSchema(filter.getClass(), false) != viewSchema) {
4248
throw new IllegalArgumentException("Filter type is not related to result type.");
4349
}
4450

45-
SqlBuilder gen = new SqlBuilder(viewSchema, this);
51+
SqlBuilder gen = new SqlBuilder(view, this);
4652
HQuery query = gen.buildSelect(resultType, filter);
4753

4854
String id = registerMapper(query.with, resultType);
@@ -85,17 +91,17 @@ public <E extends QEntity<E>> int insert(QEntity<E> entity, boolean updateOnConf
8591

8692
@Override
8793
public HSchema loadSchema(Class<?> entityType, boolean isEntity) {
88-
return HSchema.loadSchema(entityType, isEntity, sqlSessionTemplate.getConnection());
94+
return HSchema.loadSchema(entityType, isEntity, this);
8995
}
9096

9197
@Override
9298
public HSchema getTargetSchema(QJoin join) {
93-
return join.getTargetRelation(sqlSessionTemplate.getConnection()).loadSchema(sqlSessionTemplate.getConnection());
99+
return join.getTargetRelation(this).loadSchema(this);
94100
}
95101

96102
@Override
97103
public QJoin getJoin(HModel model, String alias) {
98-
return model.getJoin(alias, sqlSessionTemplate.getConnection());
104+
return model.getJoin(alias, this);
99105
}
100106

101107
public <E extends QEntity<E>> int update(QUniqueRecord<E> entity) {
@@ -261,4 +267,22 @@ private boolean isDynamicXmlQuery(Node node) {
261267
}
262268
return false;
263269
}
270+
271+
@Override
272+
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
273+
DataSource dataSource = sqlSessionTemplate
274+
.getSqlSessionFactory()
275+
.getConfiguration()
276+
.getEnvironment()
277+
.getDataSource();
278+
279+
Connection con = DataSourceUtils.getConnection(dataSource);
280+
try {
281+
return action.doInConnection(con);
282+
} catch (Exception e) {
283+
throw new RuntimeException(e);
284+
} finally {
285+
DataSourceUtils.releaseConnection(con, dataSource);
286+
}
287+
}
264288
}

0 commit comments

Comments
 (0)