Skip to content

Commit 1cc4ee3

Browse files
committed
Added Spring Framework driver,
JDBC StatementCache improved, Added StatementWrapper abstraction CSV driver fixes Cosmetic changes
1 parent d399416 commit 1cc4ee3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1443
-260
lines changed

NOTICE

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- The HSQLDB Development Group (http://www.hsqldb.org)
1212
- Thomas Mueller (http://h2database.com)
1313
- Arno Unkrig (http://janino.net)
14+
- The Spring Framework Project (http://www.springframework.org)
1415

1516
Please read the different license files present in the lib directory of
1617
this distribution.

build.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
<description>Prepares examples distribution</description>
113113
<delete file="${build.dir}/${examples.zip.name}" failonerror="false"/>
114114
<zip destfile="${build.dir}/${examples.zip.name}">
115-
<fileset dir="${basedir}/samples" includes="**"/>
115+
<fileset dir="${basedir}/samples" excludes="lib/spring.jar"/>
116116
</zip>
117117
</target>
118118

core/src/java/scriptella/core/QueryExecutor.java

+42-4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
import scriptella.spi.QueryCallback;
2525
import scriptella.spi.Resource;
2626

27+
import java.io.InputStream;
28+
import java.io.Reader;
2729
import java.util.ArrayList;
30+
import java.util.HashMap;
2831
import java.util.List;
32+
import java.util.Map;
2933
import java.util.logging.Level;
3034
import java.util.logging.Logger;
3135

@@ -71,15 +75,15 @@ public void execute(final DynamicContext ctx) {
7175
}
7276
final QueryCtxDecorator ctxDecorator = new QueryCtxDecorator(ctx);
7377
if (LOG.isLoggable(Level.FINE)) {
74-
LOG.fine("Executing query "+getLocation());
78+
LOG.fine("Executing query " + getLocation());
7579
}
7680
c.executeQuery(content, ctx,
7781
new QueryCallback() {
7882
public void processRow(final ParametersCallback params) {
7983
ctxDecorator.rownum++;
8084
ctxDecorator.setParams(params);
8185
if (LOG.isLoggable(Level.FINE)) {
82-
LOG.fine("Processing row #"+ctxDecorator.rownum+" for query "+getLocation());
86+
LOG.fine("Processing row #" + ctxDecorator.rownum + " for query " + getLocation());
8387
}
8488

8589
for (ExecutableElement exec : nestedElements) {
@@ -88,7 +92,12 @@ public void processRow(final ParametersCallback params) {
8892
}
8993
});
9094
if (LOG.isLoggable(Level.FINE)) {
91-
LOG.fine("Query "+getLocation()+" process completed");
95+
if (ctxDecorator.rownum == 0) {
96+
LOG.fine("Query " + getLocation() + " returned no results.");
97+
} else {
98+
LOG.fine("Query " + getLocation() + " processed.");
99+
}
100+
92101
}
93102

94103
}
@@ -105,23 +114,52 @@ public static ExecutableElement prepare(final QueryEl queryEl) {
105114
}
106115

107116
private static final class QueryCtxDecorator extends DynamicContextDecorator {
117+
private static final Object NULL = new Object(); //NULL object flag
108118
private ParametersCallback params;
109119
private int rownum; //current row number
120+
private Map<String, Object> cachedParams;
121+
110122

111123
public QueryCtxDecorator(DynamicContext context) {
112124
super(context);
113125
}
114126

115127
void setParams(final ParametersCallback params) {
116128
this.params = params;
129+
if (cachedParams != null) {
130+
cachedParams.clear();
131+
}
117132
}
118133

119134
@Override
120135
public final Object getParameter(final String name) {
121136
if ("rownum".equals(name)) { //return current row number
122137
return rownum;
123138
}
124-
return params.getParameter(name);
139+
Object res = cachedParams==null?null:cachedParams.get(name);
140+
if (res == null) {
141+
res = params.getParameter(name);
142+
if (res == null) {
143+
res = NULL;
144+
}
145+
if (isCacheable(res)) {
146+
if (cachedParams==null) {
147+
cachedParams=new HashMap<String, Object>();
148+
}
149+
cachedParams.put(name, res);
150+
}
151+
}
152+
return res == NULL ? null : res;
125153
}
154+
155+
/**
156+
* Check if object is cacheable, i.e. no need to fetch it again.
157+
* @param o object to check.
158+
* @return true if object is cacheable.
159+
*/
160+
private boolean isCacheable(Object o) {
161+
return !(o instanceof InputStream || o instanceof Reader);
162+
}
163+
126164
}
127165
}

core/src/java/scriptella/core/Session.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ public void init(final ConfigurationEl configuration,
6868
for (ConnectionEl c : connections) {
6969
final ConnectionManager con = new ConnectionManager(ctx, c);
7070
Connection connection = con.getConnection();
71-
progressCallback.step(1, "Connection "+connection.toString()+" registered");
71+
String id = connections.size() > 1 ? ("id=" + c.getId() + ", ") : "";//print an ID if more than one connection
72+
progressCallback.step(1, "Connection " + id + connection.toString() +
73+
", " + connection.getDialectIdentifier() + " registered");
7274
registerConnection(c.getId(), con);
7375
}
7476

@@ -86,7 +88,7 @@ public void init(final ConfigurationEl configuration,
8688
} else if (s instanceof ScriptEl) {
8789
executors.add(ScriptExecutor.prepare((ScriptEl) s));
8890
}
89-
progressCallback.step(1, s.getLocation()+" prepared");
91+
progressCallback.step(1, s.getLocation() + " prepared");
9092
}
9193
}
9294

core/src/java/scriptella/execution/ScriptsContext.java

-4
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ public Object getParameter(final String name) {
4949
return properties.get(name);
5050
}
5151

52-
public Map<String, String> getProperties() {
53-
return properties;
54-
}
55-
5652
public ProgressCallback getProgressCallback() {
5753
return progressCallback;
5854
}

core/src/java/scriptella/execution/ScriptsExecutor.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ private void execute(final ScriptsContext ctx) {
126126
ctx.setProgressCallback(oldProgress);
127127
}
128128

129+
/**
130+
* Prepares the scripts context.
131+
* @param indicator progress indicator to use.
132+
* @return prepared scripts context.
133+
*/
129134
protected ScriptsContext prepare(final ProgressIndicator indicator) {
130135
ScriptsContext ctx = new ScriptsContext();
131136
ctx.setBaseURL(configuration.getDocumentUrl());
@@ -148,6 +153,10 @@ protected ScriptsContext prepare(final ProgressIndicator indicator) {
148153
return ctx;
149154
}
150155

156+
/**
157+
* A getter for external Properties.
158+
* @return external properties set by {@link #setExternalProperties}.
159+
*/
151160
public Map<String, String> getExternalProperties() {
152161
return externalProperties;
153162
}
@@ -160,7 +169,7 @@ public Map<String, String> getExternalProperties() {
160169
*
161170
* @param externalProperties
162171
*/
163-
public void setExternalProperties(final Map<?, ?> externalProperties) {
172+
public void setExternalProperties(final Map<String, String> externalProperties) {
164173
this.externalProperties = new LinkedHashMap<String, String>((Map<String, String>) externalProperties);
165174
}
166175

core/src/java/scriptella/jdbc/JDBCConnection.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* @version 1.0
3636
*/
3737
public class JDBCConnection extends AbstractConnection {
38-
public static final String STATEMENT_CACHE_SIZE_KEY = "statement.cache.size";
38+
public static final String STATEMENT_CACHE_KEY = "statement.cache";
3939
private Connection con;
4040
private static final Logger LOG = Logger.getLogger(JDBCConnection.class.getName());
4141
private boolean transactable = false;
@@ -68,17 +68,17 @@ public JDBCConnection(Connection con, ConnectionParameters parameters) {
6868
* Called in constructor
6969
*/
7070
protected void init(ConnectionParameters parameters) {
71-
String cacheSizeStr = parameters.getProperty(STATEMENT_CACHE_SIZE_KEY);
71+
String cacheSizeStr = parameters.getProperty(STATEMENT_CACHE_KEY);
7272
int statementCacheSize = 100;
7373
if (cacheSizeStr != null && cacheSizeStr.trim().length() > 0) {
7474
try {
7575
statementCacheSize = Integer.valueOf(cacheSizeStr);
7676
} catch (NumberFormatException e) {
77-
throw new JDBCException(STATEMENT_CACHE_SIZE_KEY + " property must be a non negative integer", e);
77+
throw new JDBCException(STATEMENT_CACHE_KEY + " property must be a non negative integer", e);
7878
}
7979
}
8080

81-
statementCache = new StatementCache(statementCacheSize);
81+
statementCache = new StatementCache(con, statementCacheSize);
8282
parametersParser = new ParametersParser(parameters.getContext());
8383
initDialectIdentifier();
8484
}
@@ -152,16 +152,14 @@ public void rollback() {
152152

153153
public void close() {
154154
if (con != null) {
155+
statementCache.close();
156+
statementCache = null;
155157
try {
156158
con.close();
157159
con = null;
158160
} catch (SQLException e) {
159161
throw new JDBCException("Unable to close a connection", e);
160162
}
161-
if (statementCache != null) {
162-
statementCache.close();
163-
statementCache = null;
164-
}
165163

166164
}
167165
}
@@ -171,7 +169,7 @@ public Connection getNativeConnection() {
171169
}
172170

173171
public String toString() {
174-
return "JDBCConnection{" + (con == null ? "" : con.getClass().getName()) + "}, "+getDialectIdentifier();
172+
return "JDBCConnection{" + (con == null ? "" : con.getClass().getName()) + '}';
175173
}
176174

177175
public JDBCTypesConverter newConverter() {

core/src/java/scriptella/jdbc/ResultSetAdapter.java

+6-14
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import java.sql.ResultSet;
2424
import java.sql.ResultSetMetaData;
2525
import java.sql.SQLException;
26-
import java.util.Arrays;
2726

2827

2928
/**
@@ -38,8 +37,8 @@ public class ResultSetAdapter implements ParametersCallback, Closeable {
3837
private ResultSet resultSet;
3938
private ColumnsMap columnsMap;
4039
private ParametersCallback params; //parent parameters callback to use
41-
private Object[] row;//cache for row elements
4240
private JDBCTypesConverter converter;
41+
private final int columnsCount;
4342

4443
/**
4544
* Instantiates an adapter, prepares a cache and builds a map of column names.
@@ -57,12 +56,11 @@ public ResultSetAdapter(ResultSet resultSet,
5756

5857
try {
5958
final ResultSetMetaData m = resultSet.getMetaData();
60-
final int n = m.getColumnCount();
59+
columnsCount = m.getColumnCount();
6160

62-
for (int i = 1; i <= n; i++) {
61+
for (int i = 1; i <= columnsCount; i++) {
6362
columnsMap.registerColumn(m.getColumnName(i), i);
6463
}
65-
row = new Object[n];
6664
} catch (SQLException e) {
6765
throw new JDBCException("Unable to process result set ", e);
6866
}
@@ -74,9 +72,7 @@ public ResultSetAdapter(ResultSet resultSet,
7472
*/
7573
public boolean next() {
7674
try {
77-
boolean res = resultSet.next();
78-
Arrays.fill(row, null);
79-
return res;
75+
return resultSet.next();
8076
} catch (SQLException e) {
8177
throw new JDBCException("Unable to move cursor to the next row", e);
8278
}
@@ -86,12 +82,9 @@ public boolean next() {
8682
public Object getParameter(final String name) {
8783
try {
8884
Integer index = columnsMap.find(name);
89-
if (index != null && index > 0 && index <= row.length) { //if index found and in range
85+
if (index != null && index > 0 && index <= columnsCount) { //if index found and in range
9086
int ind = index - 1;
91-
if (row[ind] == null) { //cache miss
92-
row[ind] = converter.getObject(resultSet, ind + 1);
93-
}
94-
return row[ind];
87+
return converter.getObject(resultSet, ind + 1);
9588
} else { //otherwise call uppper level params
9689
return params.getParameter(name);
9790
}
@@ -110,7 +103,6 @@ public void close() {
110103
JDBCUtils.closeSilent(resultSet);
111104
IOUtils.closeSilently(converter);
112105
resultSet = null;
113-
row = null;
114106
params = null;
115107
columnsMap = null;
116108
}

0 commit comments

Comments
 (0)