~maria-captains/mariadb-java-client/trunk

« back to all changes in this revision

Viewing changes to src/main/java/org/mariadb/jdbc/MySQLStatement.java

  • Committer: Massimo Siani
  • Date: 2014-09-12 15:03:29 UTC
  • Revision ID: massimo.siani@skysql.com-20140912150329-28tydhr0c6ku7927
Change TimezoneDaylightSavingTimeTest

Show diffs side-by-side

added added

removed removed

Lines of Context:
98
98
 
99
99
    List<String> batchQueries;
100
100
    Queue<Object> cachedResultSets;
 
101
    private boolean isRewriteable = true;
 
102
    private String firstRewrite = null;
101
103
 
102
104
 
103
105
    public boolean isStreaming() {
1086
1088
            batchQueries = new ArrayList<String>();
1087
1089
        }
1088
1090
        batchQueries.add(sql);
 
1091
        isInsertRewriteable(sql);
 
1092
    }
 
1093
    
 
1094
    /**
 
1095
     * Parses the sql string to understand whether it is compatible with rewritten batches.
 
1096
     * @param sql the sql string
 
1097
     */
 
1098
    private void isInsertRewriteable(String sql) {
 
1099
        if (!isRewriteable) {
 
1100
                return;
 
1101
        }
 
1102
        int index = getInsertIncipit(sql);
 
1103
        if (index == -1) {
 
1104
                isRewriteable = false;
 
1105
                return;
 
1106
        }
 
1107
        if (firstRewrite == null) {
 
1108
                firstRewrite = sql.substring(0, index);
 
1109
        }
 
1110
        boolean isRewrite = sql.startsWith(firstRewrite);
 
1111
        if (isRewrite) {
 
1112
                isRewriteable = isRewriteable && true;
 
1113
        }
 
1114
    }
 
1115
    
 
1116
    /**
 
1117
     * Parses the input string to understand if it is an INSERT statement.
 
1118
     * Returns the position of the round bracket after the VALUE(S) SQL keyword,
 
1119
     * or -1 if it cannot understand it is an INSERT statement.
 
1120
     * Multiple statements cannot be parsed.
 
1121
     * @param sql the input SQL statement
 
1122
     * @return the position of the round bracket after the VALUE(S) SQL keyword,
 
1123
     * or -1 if it cannot be parsed as an INSERT statement
 
1124
     */
 
1125
    protected int getInsertIncipit(String sql) {
 
1126
        String sqlUpper = sql.toUpperCase();
 
1127
        if (! sqlUpper.startsWith("INSERT")
 
1128
                        || sqlUpper.indexOf(";") != -1) {
 
1129
                return -1;
 
1130
        }
 
1131
        int idx = sqlUpper.indexOf(" VALUE");
 
1132
        int index = sqlUpper.indexOf("(", idx);
 
1133
        return index;
 
1134
    }
 
1135
    
 
1136
    /**
 
1137
     * If the batch array contains only rewriteable sql strings, returns the rewritten statement.
 
1138
     * @return the rewritten statement
 
1139
     */
 
1140
    private String rewrittenBatch() {
 
1141
        StringBuilder result = null;
 
1142
        if(isRewriteable) {
 
1143
                result = new StringBuilder("");
 
1144
                result.append(firstRewrite);
 
1145
                for (String query : batchQueries) {
 
1146
                        result.append(query.substring(getInsertIncipit(query)));
 
1147
                        result.append(",");
 
1148
                }
 
1149
                result.deleteCharAt(result.length() - 1);
 
1150
        }
 
1151
        return (result == null ? null : result.toString());
1089
1152
    }
1090
1153
 
1091
1154
 
1103
1166
        if (batchQueries != null) {
1104
1167
            batchQueries.clear();
1105
1168
        }
 
1169
        firstRewrite = null;
 
1170
        isRewriteable = true;
1106
1171
    }
1107
1172
 
1108
1173
    /**
1147
1212
        int[] ret = new int[batchQueries.size()];
1148
1213
        int i = 0;
1149
1214
        try {
1150
 
            synchronized (this.protocol) {
1151
 
                for(; i < batchQueries.size(); i++)  {
1152
 
                    execute(batchQueries.get(i));
1153
 
                    int updateCount = getUpdateCount();
1154
 
                    if (updateCount == -1) {
1155
 
                        ret[i] = SUCCESS_NO_INFO;
1156
 
                    } else {
1157
 
                        ret[i] = updateCount;
1158
 
                    }
1159
 
                }
1160
 
            }
 
1215
                synchronized (this.protocol) {
 
1216
                        if (getProtocol().getInfo().getProperty("rewriteBatchedStatements") != null
 
1217
                                        && "true".equalsIgnoreCase(getProtocol().getInfo().getProperty("rewriteBatchedStatements"))) {
 
1218
                                ret = executeBatchAsMultiQueries();
 
1219
                        } else {
 
1220
                                for(; i < batchQueries.size(); i++)  {
 
1221
                                        execute(batchQueries.get(i));
 
1222
                                        int updateCount = getUpdateCount();
 
1223
                                        if (updateCount == -1) {
 
1224
                                                ret[i] = SUCCESS_NO_INFO;
 
1225
                                        } else {
 
1226
                                                ret[i] = updateCount;
 
1227
                                        }
 
1228
                                }
 
1229
                        }
 
1230
                }
1161
1231
        } catch (SQLException sqle) {
1162
1232
            throw new BatchUpdateException(sqle.getMessage(), sqle.getSQLState(),Arrays.copyOf(ret, i), sqle);
1163
1233
        } finally {
1165
1235
        }
1166
1236
        return ret;
1167
1237
    }
 
1238
    
 
1239
    /**
 
1240
         * Builds a new statement which contains the batched Statements and executes it.
 
1241
         * @return an array of update counts containing one element for each command in the batch.
 
1242
         *  The elements of the array are ordered according to the order in which commands were added to the batch.
 
1243
         * @throws SQLException
 
1244
         */
 
1245
        private int[] executeBatchAsMultiQueries() throws SQLException {
 
1246
                int i = 0;
 
1247
                StringBuilder stringBuilder = new StringBuilder();
 
1248
                String rewrite = rewrittenBatch();
 
1249
                if (rewrite != null) {
 
1250
                        stringBuilder.append(rewrite);
 
1251
                        i++;
 
1252
                } else {
 
1253
                        for (; i < batchQueries.size(); i++) {
 
1254
                                stringBuilder.append(batchQueries.get(i) + ";");
 
1255
                        }
 
1256
                }
 
1257
                Statement ps = connection.createStatement();
 
1258
                ps.execute(stringBuilder.toString());
 
1259
                return getUpdateCounts(ps, i);
 
1260
        }
 
1261
        /**
 
1262
         * Retrieves the update counts for the batched statements rewritten as
 
1263
         * a multi query. The rewritten statement must have been executed already.
 
1264
         * @param statement the rewritten statement
 
1265
         * @return an array of update counts containing one element for each command in the batch.
 
1266
         *  The elements of the array are ordered according to the order in which commands were added to the batch.
 
1267
         * @throws SQLException
 
1268
         */
 
1269
        protected int[] getUpdateCounts(Statement statement, int size) throws SQLException {
 
1270
                int[] result = new int[size];
 
1271
                int updateCount;
 
1272
                for (int count=0; count<size; count++) {
 
1273
                        updateCount = statement.getUpdateCount();
 
1274
            if (updateCount == -1) {
 
1275
                result[count] = SUCCESS_NO_INFO;
 
1276
            } else {
 
1277
                result[count] = updateCount;
 
1278
            }
 
1279
            statement.getMoreResults();
 
1280
                }
 
1281
                return result;
 
1282
        }
1168
1283
 
1169
1284
    /**
1170
1285
     * Returns an object that implements the given interface to allow access to non-standard methods, or standard