View | Details | Raw Unified | Return to bug 52128
Collapse All | Expand All

(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/AbstractJdbcTestElement.java (+555 lines)
Line 0 Link Here
1
package org.apache.jmeter.protocol.jdbc;
2
3
import java.io.IOException;
4
import java.io.UnsupportedEncodingException;
5
import java.lang.reflect.Field;
6
import java.sql.CallableStatement;
7
import java.sql.Connection;
8
import java.sql.PreparedStatement;
9
import java.sql.ResultSet;
10
import java.sql.ResultSetMetaData;
11
import java.sql.SQLException;
12
import java.sql.Statement;
13
import java.util.ArrayList;
14
import java.util.Collection;
15
import java.util.HashMap;
16
import java.util.LinkedHashMap;
17
import java.util.List;
18
import java.util.Map;
19
20
import org.apache.commons.lang.text.StrBuilder;
21
import org.apache.jmeter.samplers.SampleResult;
22
import org.apache.jmeter.save.CSVSaveService;
23
import org.apache.jmeter.testelement.AbstractTestElement;
24
import org.apache.jmeter.threads.JMeterVariables;
25
import org.apache.jmeter.util.JMeterUtils;
26
import org.apache.jorphan.logging.LoggingManager;
27
import org.apache.log.Logger;
28
29
/**
30
 * A base class for all JDBC test elements handling the basics of a SQL request.
31
 * 
32
 */
33
public abstract class AbstractJdbcTestElement extends AbstractTestElement {
34
    private static final long serialVersionUID = 235L;
35
36
    private static final Logger log = LoggingManager.getLoggerForClass();
37
38
    private static final String COMMA = ","; // $NON-NLS-1$
39
    private static final char COMMA_CHAR = ',';
40
41
    private static final String UNDERSCORE = "_"; // $NON-NLS-1$
42
43
    // This value is used for both the connection (perConnCache) and statement (preparedStatementMap) caches.
44
    // TODO - do they have to be the same size?
45
    private static final int MAX_ENTRIES =
46
        JMeterUtils.getPropDefault("jdbcsampler.cachesize",200); // $NON-NLS-1$
47
48
    // String used to indicate a null value
49
    private static final String NULL_MARKER =
50
        JMeterUtils.getPropDefault("jdbcsampler.nullmarker","]NULL["); // $NON-NLS-1$
51
52
    private static final String INOUT = "INOUT"; // $NON-NLS-1$
53
54
    private static final String OUT = "OUT"; // $NON-NLS-1$
55
56
    // TODO - should the encoding be configurable?
57
    protected static final String ENCODING = "UTF-8"; // $NON-NLS-1$
58
59
    // key: name (lowercase) from java.sql.Types; entry: corresponding int value
60
    private static final Map<String, Integer> mapJdbcNameToInt;
61
    // read-only after class init
62
63
    static {
64
        // based on e291. Getting the Name of a JDBC Type from javaalmanac.com
65
        // http://javaalmanac.com/egs/java.sql/JdbcInt2Str.html
66
        mapJdbcNameToInt = new HashMap<String, Integer>();
67
68
        //Get all fields in java.sql.Types and store the corresponding int values
69
        Field[] fields = java.sql.Types.class.getFields();
70
        for (int i=0; i<fields.length; i++) {
71
            try {
72
                String name = fields[i].getName();
73
                Integer value = (Integer)fields[i].get(null);
74
                mapJdbcNameToInt.put(name.toLowerCase(java.util.Locale.ENGLISH),value);
75
            } catch (IllegalAccessException e) {
76
                throw new RuntimeException(e); // should not happen
77
            }
78
        }
79
    }
80
81
    // Query types (used to communicate with GUI)
82
    // N.B. These must not be changed, as they are used in the JMX files
83
    static final String SELECT   = "Select Statement"; // $NON-NLS-1$
84
    static final String UPDATE   = "Update Statement"; // $NON-NLS-1$
85
    static final String CALLABLE = "Callable Statement"; // $NON-NLS-1$
86
    static final String PREPARED_SELECT = "Prepared Select Statement"; // $NON-NLS-1$
87
    static final String PREPARED_UPDATE = "Prepared Update Statement"; // $NON-NLS-1$
88
    static final String COMMIT   = "Commit"; // $NON-NLS-1$
89
    static final String ROLLBACK = "Rollback"; // $NON-NLS-1$
90
    static final String AUTOCOMMIT_FALSE = "AutoCommit(false)"; // $NON-NLS-1$
91
    static final String AUTOCOMMIT_TRUE  = "AutoCommit(true)"; // $NON-NLS-1$
92
93
    private String query = ""; // $NON-NLS-1$
94
95
    private String dataSource = ""; // $NON-NLS-1$
96
97
    private String queryType = SELECT;
98
    private String queryArguments = ""; // $NON-NLS-1$
99
    private String queryArgumentsTypes = ""; // $NON-NLS-1$
100
    private String variableNames = ""; // $NON-NLS-1$
101
    private String resultVariable = "";
102
103
    /**
104
     *  Cache of PreparedStatements stored in a per-connection basis. Each entry of this
105
     *  cache is another Map mapping the statement string to the actual PreparedStatement.
106
     *  The cache has a fixed size of MAX_ENTRIES and it will throw away all PreparedStatements
107
     *  from the least recently used connections.
108
     */
109
    private static final Map<Connection, Map<String, PreparedStatement>> perConnCache =
110
        new LinkedHashMap<Connection, Map<String, PreparedStatement>>(MAX_ENTRIES){
111
        private static final long serialVersionUID = 1L;
112
        @Override
113
        protected boolean removeEldestEntry(Map.Entry<Connection, Map<String, PreparedStatement>> arg0) {
114
            if (size() > MAX_ENTRIES) {
115
                final  Map<String, PreparedStatement> value = arg0.getValue();
116
                closeAllStatements(value.values());
117
                return true;
118
            }
119
            return false;
120
        }
121
    };
122
123
    /**
124
     * Creates a JDBCSampler.
125
     */
126
    protected AbstractJdbcTestElement() {
127
    }
128
    
129
    /**
130
     * Execute the test element.
131
     * 
132
     * @param res a {@link SampleResult} in case the test should sample; <code>null</code> if only execution is requested
133
     * @throws UnsupportedOperationException if the user provided incorrect query type 
134
     */
135
    protected byte[] execute(Connection conn) throws SQLException, UnsupportedEncodingException, IOException, UnsupportedOperationException {
136
        log.debug("executing jdbc");
137
        Statement stmt = null;
138
        
139
        try {
140
            // Based on query return value, get results
141
            String _queryType = getQueryType();
142
            if (SELECT.equals(_queryType)) {
143
                stmt = conn.createStatement();
144
                ResultSet rs = null;
145
                try {
146
                    rs = stmt.executeQuery(getQuery());
147
                    return getStringFromResultSet(rs).getBytes(ENCODING);
148
                } finally {
149
                    close(rs);
150
                }
151
            } else if (CALLABLE.equals(_queryType)) {
152
                CallableStatement cstmt = getCallableStatement(conn);
153
                int out[]=setArguments(cstmt);
154
                // A CallableStatement can return more than 1 ResultSets
155
                // plus a number of update counts.
156
                boolean hasResultSet = cstmt.execute();
157
                String sb = resultSetsToString(cstmt,hasResultSet, out);
158
                return sb.getBytes(ENCODING);
159
            } else if (UPDATE.equals(_queryType)) {
160
                stmt = conn.createStatement();
161
                stmt.executeUpdate(getQuery());
162
                int updateCount = stmt.getUpdateCount();
163
                String results = updateCount + " updates";
164
                return results.getBytes(ENCODING);
165
            } else if (PREPARED_SELECT.equals(_queryType)) {
166
                PreparedStatement pstmt = getPreparedStatement(conn);
167
                setArguments(pstmt);
168
                boolean hasResultSet = pstmt.execute();
169
                String sb = resultSetsToString(pstmt,hasResultSet,null);
170
                return sb.getBytes(ENCODING);
171
            } else if (PREPARED_UPDATE.equals(_queryType)) {
172
                PreparedStatement pstmt = getPreparedStatement(conn);
173
                setArguments(pstmt);
174
                pstmt.executeUpdate();
175
                String sb = resultSetsToString(pstmt,false,null);
176
                return sb.getBytes(ENCODING);
177
            } else if (ROLLBACK.equals(_queryType)){
178
                conn.rollback();
179
                return ROLLBACK.getBytes(ENCODING);
180
            } else if (COMMIT.equals(_queryType)){
181
                conn.commit();
182
                return COMMIT.getBytes(ENCODING);
183
            } else if (AUTOCOMMIT_FALSE.equals(_queryType)){
184
                conn.setAutoCommit(false);
185
                return AUTOCOMMIT_FALSE.getBytes(ENCODING);
186
            } else if (AUTOCOMMIT_TRUE.equals(_queryType)){
187
                conn.setAutoCommit(true);
188
                return AUTOCOMMIT_TRUE.getBytes(ENCODING);
189
            } else { // User provided incorrect query type
190
                throw new UnsupportedOperationException("Unexpected query type: "+_queryType);
191
            }
192
        } finally {
193
            close(stmt);
194
        }
195
    }
196
197
    private String resultSetsToString(PreparedStatement pstmt, boolean result, int[] out) throws SQLException, UnsupportedEncodingException {
198
        StrBuilder sb = new StrBuilder();
199
        int updateCount = 0;
200
        if (!result) {
201
            updateCount = pstmt.getUpdateCount();
202
        }
203
        do {
204
            if (result) {
205
                ResultSet rs = null;
206
                try {
207
                    rs = pstmt.getResultSet();
208
                    sb.append(getStringFromResultSet(rs)).append("\n"); // $NON-NLS-1$
209
                } finally {
210
                    close(rs);
211
                }
212
            } else {
213
                sb.append(updateCount).append(" updates.\n");
214
            }
215
            result = pstmt.getMoreResults();
216
            if (!result) {
217
                updateCount = pstmt.getUpdateCount();
218
            }
219
        } while (result || (updateCount != -1));
220
        if (out!=null && pstmt instanceof CallableStatement){
221
            CallableStatement cs = (CallableStatement) pstmt;
222
            sb.append("Output variables by position:\n");
223
            for(int i=0; i < out.length; i++){
224
                if (out[i]!=java.sql.Types.NULL){
225
                    sb.append("[");
226
                    sb.append(i+1);
227
                    sb.append("] ");
228
                    sb.append(cs.getObject(i+1));
229
                    sb.append("\n");
230
                }
231
            }
232
        }
233
        return sb.toString();
234
    }
235
236
237
    private int[] setArguments(PreparedStatement pstmt) throws SQLException, IOException {
238
        if (getQueryArguments().trim().length()==0) {
239
            return new int[]{};
240
        }
241
        String[] arguments = CSVSaveService.csvSplitString(getQueryArguments(), COMMA_CHAR);
242
        String[] argumentsTypes = getQueryArgumentsTypes().split(COMMA);
243
        if (arguments.length != argumentsTypes.length) {
244
            throw new SQLException("number of arguments ("+arguments.length+") and number of types ("+argumentsTypes.length+") are not equal");
245
        }
246
        int[] outputs= new int[arguments.length];
247
        for (int i = 0; i < arguments.length; i++) {
248
            String argument = arguments[i];
249
            String argumentType = argumentsTypes[i];
250
            String[] arg = argumentType.split(" ");
251
            String inputOutput="";
252
            if (arg.length > 1) {
253
                argumentType = arg[1];
254
                inputOutput=arg[0];
255
            }
256
            int targetSqlType = getJdbcType(argumentType);
257
            try {
258
                if (!OUT.equalsIgnoreCase(inputOutput)){
259
                    if (argument.equals(NULL_MARKER)){
260
                        pstmt.setNull(i+1, targetSqlType);
261
                    } else {
262
                        pstmt.setObject(i+1, argument, targetSqlType);
263
                    }
264
                }
265
                if (OUT.equalsIgnoreCase(inputOutput)||INOUT.equalsIgnoreCase(inputOutput)) {
266
                    CallableStatement cs = (CallableStatement) pstmt;
267
                    cs.registerOutParameter(i+1, targetSqlType);
268
                    outputs[i]=targetSqlType;
269
                } else {
270
                    outputs[i]=java.sql.Types.NULL; // can't have an output parameter type null
271
                }
272
            } catch (NullPointerException e) { // thrown by Derby JDBC (at least) if there are no "?" markers in statement
273
                throw new SQLException("Could not set argument no: "+(i+1)+" - missing parameter marker?");
274
            }
275
        }
276
        return outputs;
277
    }
278
279
280
    private static int getJdbcType(String jdbcType) throws SQLException {
281
        Integer entry = mapJdbcNameToInt.get(jdbcType.toLowerCase(java.util.Locale.ENGLISH));
282
        if (entry == null) {
283
            try {
284
                entry = Integer.decode(jdbcType);
285
            } catch (NumberFormatException e) {
286
                throw new SQLException("Invalid data type: "+jdbcType);
287
            }
288
        }
289
        return (entry).intValue();
290
    }
291
292
293
    private CallableStatement getCallableStatement(Connection conn) throws SQLException {
294
        return (CallableStatement) getPreparedStatement(conn,true);
295
296
    }
297
    private PreparedStatement getPreparedStatement(Connection conn) throws SQLException {
298
        return getPreparedStatement(conn,false);
299
    }
300
301
    private PreparedStatement getPreparedStatement(Connection conn, boolean callable) throws SQLException {
302
        Map<String, PreparedStatement> preparedStatementMap = perConnCache.get(conn);
303
        if (null == preparedStatementMap ) {
304
            // MRU PreparedStatements cache.
305
            preparedStatementMap = new LinkedHashMap<String, PreparedStatement>(MAX_ENTRIES) {
306
                private static final long serialVersionUID = 240L;
307
308
                @Override
309
                protected boolean removeEldestEntry(Map.Entry<String, PreparedStatement> arg0) {
310
                    final int theSize = size();
311
                    if (theSize > MAX_ENTRIES) {
312
                        Object value = arg0.getValue();
313
                        if (value instanceof PreparedStatement) {
314
                            PreparedStatement pstmt = (PreparedStatement) value;
315
                            close(pstmt);
316
                        }
317
                        return true;
318
                    }
319
                    return false;
320
                }
321
            };
322
            perConnCache.put(conn, preparedStatementMap);
323
        }
324
        PreparedStatement pstmt = preparedStatementMap.get(getQuery());
325
        if (null == pstmt) {
326
            if (callable) {
327
                pstmt = conn.prepareCall(getQuery());
328
            } else {
329
                pstmt = conn.prepareStatement(getQuery());
330
            }
331
            preparedStatementMap.put(getQuery(), pstmt);
332
        }
333
        pstmt.clearParameters();
334
        return pstmt;
335
    }
336
337
    private static void closeAllStatements(Collection<PreparedStatement> collection) {
338
        for (PreparedStatement pstmt : collection) {
339
            close(pstmt);
340
        }
341
    }
342
343
    /**
344
     * Gets a Data object from a ResultSet.
345
     *
346
     * @param rs
347
     *            ResultSet passed in from a database query
348
     * @return a Data object
349
     * @throws java.sql.SQLException
350
     * @throws UnsupportedEncodingException
351
     */
352
    private String getStringFromResultSet(ResultSet rs) throws SQLException, UnsupportedEncodingException {
353
        ResultSetMetaData meta = rs.getMetaData();
354
355
        StrBuilder sb = new StrBuilder();
356
357
        int numColumns = meta.getColumnCount();
358
        for (int i = 1; i <= numColumns; i++) {
359
            sb.append(meta.getColumnName(i));
360
            if (i==numColumns){
361
                sb.append('\n');
362
            } else {
363
                sb.append('\t');
364
            }
365
        }
366
        
367
368
        JMeterVariables jmvars = getThreadContext().getVariables();
369
        String varnames[] = getVariableNames().split(COMMA);
370
        String resultVariable = getResultVariable().trim();
371
        List<Map<String, Object> > results = null;
372
        if(resultVariable.length() > 0) {
373
            results = new ArrayList<Map<String,Object> >();
374
            jmvars.putObject(resultVariable, results);
375
        }
376
        int j = 0;
377
        while (rs.next()) {
378
            Map<String, Object> row = null;
379
            j++;
380
            for (int i = 1; i <= numColumns; i++) {
381
                Object o = rs.getObject(i);
382
                if(results != null) {
383
                    if(row == null) {
384
                        row = new HashMap<String, Object>(numColumns);
385
                        results.add(row);
386
                    }
387
                    row.put(meta.getColumnName(i), o);
388
                }
389
                if (o instanceof byte[]) {
390
                    o = new String((byte[]) o, ENCODING);
391
                }
392
                sb.append(o);
393
                if (i==numColumns){
394
                    sb.append('\n');
395
                } else {
396
                    sb.append('\t');
397
                }
398
                if (i <= varnames.length) { // i starts at 1
399
                    String name = varnames[i - 1].trim();
400
                    if (name.length()>0){ // Save the value in the variable if present
401
                        jmvars.put(name+UNDERSCORE+j, o == null ? null : o.toString());
402
                    }
403
                }
404
            }
405
        }
406
        // Remove any additional values from previous sample
407
        for(int i=0; i < varnames.length; i++){
408
            String name = varnames[i].trim();
409
            if (name.length()>0 && jmvars != null){
410
                final String varCount = name+"_#"; // $NON-NLS-1$
411
                // Get the previous count
412
                String prevCount = jmvars.get(varCount);
413
                if (prevCount != null){
414
                    int prev = Integer.parseInt(prevCount);
415
                    for (int n=j+1; n <= prev; n++ ){
416
                        jmvars.remove(name+UNDERSCORE+n);
417
                    }
418
                }
419
                jmvars.put(varCount, Integer.toString(j)); // save the current count
420
            }
421
        }
422
423
        return sb.toString();
424
    }
425
426
    public static void close(Connection c) {
427
        try {
428
            if (c != null) {
429
                c.close();
430
            }
431
        } catch (SQLException e) {
432
            log.warn("Error closing Connection", e);
433
        }
434
    }
435
436
    public static void close(Statement s) {
437
        try {
438
            if (s != null) {
439
                s.close();
440
            }
441
        } catch (SQLException e) {
442
            log.warn("Error closing Statement " + s.toString(), e);
443
        }
444
    }
445
446
    public static void close(ResultSet rs) {
447
        try {
448
            if (rs != null) {
449
                rs.close();
450
            }
451
        } catch (SQLException e) {
452
            log.warn("Error closing ResultSet", e);
453
        }
454
    }
455
456
    public String getQuery() {
457
        return query;
458
    }
459
460
    @Override
461
    public String toString() {
462
        StrBuilder sb = new StrBuilder(80);
463
        sb.append("["); // $NON-NLS-1$
464
        sb.append(getQueryType());
465
        sb.append("] "); // $NON-NLS-1$
466
        sb.append(getQuery());
467
        sb.append("\n");
468
        sb.append(getQueryArguments());
469
        sb.append("\n");
470
        sb.append(getQueryArgumentsTypes());
471
        return sb.toString();
472
    }
473
474
    /**
475
     * @param query
476
     *            The query to set.
477
     */
478
    public void setQuery(String query) {
479
        this.query = query;
480
    }
481
482
    /**
483
     * @return Returns the dataSource.
484
     */
485
    public String getDataSource() {
486
        return dataSource;
487
    }
488
489
    /**
490
     * @param dataSource
491
     *            The dataSource to set.
492
     */
493
    public void setDataSource(String dataSource) {
494
        this.dataSource = dataSource;
495
    }
496
497
    /**
498
     * @return Returns the queryType.
499
     */
500
    public String getQueryType() {
501
        return queryType;
502
    }
503
504
    /**
505
     * @param queryType The queryType to set.
506
     */
507
    public void setQueryType(String queryType) {
508
        this.queryType = queryType;
509
    }
510
511
    public String getQueryArguments() {
512
        return queryArguments;
513
    }
514
515
    public void setQueryArguments(String queryArguments) {
516
        this.queryArguments = queryArguments;
517
    }
518
519
    public String getQueryArgumentsTypes() {
520
        return queryArgumentsTypes;
521
    }
522
523
    public void setQueryArgumentsTypes(String queryArgumentsType) {
524
        this.queryArgumentsTypes = queryArgumentsType;
525
    }
526
527
    /**
528
     * @return the variableNames
529
     */
530
    public String getVariableNames() {
531
        return variableNames;
532
    }
533
534
    /**
535
     * @param variableNames the variableNames to set
536
     */
537
    public void setVariableNames(String variableNames) {
538
        this.variableNames = variableNames;
539
    }
540
541
    /**
542
     * @return the resultVariable
543
     */
544
    public String getResultVariable() {
545
        return resultVariable ;
546
    }
547
548
    /**
549
     * @param resultVariable the variable name in which results will be stored
550
     */
551
    public void setResultVariable(String resultVariable) {
552
        this.resultVariable = resultVariable;
553
    }
554
    
555
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupport.java (+100 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
/*
20
 * Created on May 16, 2004
21
 *
22
 */
23
package org.apache.jmeter.protocol.jdbc;
24
25
import java.beans.PropertyDescriptor;
26
27
import org.apache.jmeter.testbeans.BeanInfoSupport;
28
import org.apache.jmeter.testbeans.gui.TextAreaEditor;
29
30
public abstract class JDBCBeanInfoSupport extends BeanInfoSupport {
31
32
    /**
33
     *
34
     */
35
    public JDBCBeanInfoSupport(Class<?> beanClass) {
36
        super(beanClass);
37
38
        createPropertyGroup("varName", // $NON-NLS-1$
39
                new String[]{"dataSource" }); // $NON-NLS-1$
40
41
        createPropertyGroup("diagnostics", // $NON-NLS-1$
42
                new String[] { "collectDiagnostics" }); // $NON-NLS-1$
43
44
        createPropertyGroup("sql", // $NON-NLS-1$
45
                new String[] {
46
                "queryType", // $NON-NLS-1$
47
                "query", // $NON-NLS-1$
48
                "queryArguments", // $NON-NLS-1$
49
                "queryArgumentsTypes", // $NON-NLS-1$
50
                "variableNames", // $NON-NLS-1$
51
                "resultVariable", // $NON-NLS-1$
52
                });
53
54
        PropertyDescriptor p = property("collectDiagnostics"); // $NON-NLS-1$
55
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
56
        p.setValue(DEFAULT, Boolean.FALSE);
57
58
        p = property("dataSource"); // $NON-NLS-1$
59
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
60
        p.setValue(DEFAULT, "");
61
62
        p = property("queryArguments"); // $NON-NLS-1$
63
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
64
        p.setValue(DEFAULT, "");
65
66
        p = property("queryArgumentsTypes"); // $NON-NLS-1$
67
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
68
        p.setValue(DEFAULT, "");
69
70
        p = property("variableNames"); // $NON-NLS-1$
71
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
72
        p.setValue(DEFAULT, "");
73
74
        p = property("resultVariable"); // $NON-NLS-1$
75
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
76
        p.setValue(DEFAULT, "");
77
78
        p = property("queryType"); // $NON-NLS-1$
79
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
80
        p.setValue(DEFAULT, AbstractJdbcTestElement.SELECT);
81
        p.setValue(NOT_OTHER,Boolean.TRUE);
82
        p.setValue(TAGS,new String[]{
83
                AbstractJdbcTestElement.SELECT,
84
                AbstractJdbcTestElement.UPDATE,
85
                AbstractJdbcTestElement.CALLABLE,
86
                AbstractJdbcTestElement.PREPARED_SELECT,
87
                AbstractJdbcTestElement.PREPARED_UPDATE,
88
                AbstractJdbcTestElement.COMMIT,
89
                AbstractJdbcTestElement.ROLLBACK,
90
                AbstractJdbcTestElement.AUTOCOMMIT_FALSE,
91
                AbstractJdbcTestElement.AUTOCOMMIT_TRUE,
92
                });
93
94
        p = property("query"); // $NON-NLS-1$
95
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
96
        p.setValue(DEFAULT, "");
97
        p.setPropertyEditorClass(TextAreaEditor.class);
98
99
    }
100
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources.properties (+34 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
displayName=JDBC Request
17
varName.displayName=Variable Name Bound to Pool
18
sql.displayName=SQL Query
19
query.displayName=Query
20
query.shortDescription=SQL Query to send to database
21
queryType.displayName=Query Type
22
queryType.shortDescription=Determines if the SQL statement should be run as a select statement or an update statement.
23
dataSource.displayName=Variable Name
24
dataSource.shortDescription=Name of the JMeter variable that the connection pool is bound to.
25
queryArguments.displayName=Parameter values
26
queryArguments.shortDescription=SQL parameter values (comma separated)
27
queryArgumentsTypes.displayName=Parameter types
28
queryArgumentsTypes.shortDescription=JDBC Type names from java.sql.Types. VARCHAR, INTEGER, etc. (comma separated)
29
variableNames.displayName=Variable names
30
variableNames.shortDescription=Output variable names for each column  (comma separated)
31
resultVariable.displayName=Result variable name
32
resultVariable.shortDescription=Name of the JMeter variable that stores the result set objects in a list of maps for looking up results by column name.
33
diagnostics.displayName=Diagnostics
34
collectDiagnostics.displayName=Collect diagnostic messages
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources_es.properties (+29 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=Nombre de Variable
18
dataSource.shortDescription=Nombre de la variable JMeter a la cual est\u00E1 ligado el pool de conexiones
19
query.displayName=Query
20
query.shortDescription=Query SQL a enviar a la base de datos
21
queryType.displayName=Solo Query
22
queryType.shortDescription=is true, se lanzar\u00E1 como una query y no como un update/inser. Si no, se lanza como update.
23
sql.displayName=Query SQL
24
varName.displayName=Nombre de Variable Ligada al Pool
25
queryArguments.displayName=Argumentos
26
queryArguments.shortDescription=los valores de los argumentos separados por comas
27
queryArgumentsTypes.displayName=Tipos de los argumentos
28
queryArgumentsTypes.shortDescription=los valores de los argumentos separados por comas
29
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources_fr.properties (+32 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=Nom de liaison 
18
dataSource.shortDescription=Nom de la variable JMeter qui sera li\u00E9e au pool de connexion
19
query.displayName=Requ\u00EAte 
20
query.shortDescription=Requ\u00EAte SQL \u00E0 envoyer \u00E0 la base de donn\u00E9es
21
queryArguments.displayName=Valeurs des param\u00E8tres 
22
queryArguments.shortDescription=Valeurs des param\u00E8tres SQL
23
queryArgumentsTypes.displayName=Types des param\u00E8tres 
24
queryArgumentsTypes.shortDescription=Noms des types JDBC depuis java.sql.Types. Ex. VARCHAR, INTEGER, etc. (s\u00E9par\u00E9s par des virgules)
25
queryType.displayName=Type de requ\u00EAte 
26
queryType.shortDescription=D\u00E9termine si l'instruction SQL doit \u00EAtre ex\u00E9cut\u00E9e comme une commande SELECT ou une commande UPDATE.
27
resultVariable.displayName=Nom de la variable des R\u00E9sultats
28
resultVariable.shortDescription=Nom de la variable JMeter qui stocke les r\u00E9sultats sous forme d'objets dans une liste de type 'maps' permettant la recherche des r\u00E9sultats par nom de colonne.
29
sql.displayName=Requ\u00EAte SQL
30
varName.displayName=Nom de liaison avec le pool
31
variableNames.displayName=Noms des variables 
32
variableNames.shortDescription=Noms des variables en sortie pour chaque colonne (s\u00E9par\u00E9s par des virgules)
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources_pt_BR.properties (+29 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
dataSource.displayName=Nome da Vari\u00E1vel
17
dataSource.shortDescription=Nome da vari\u00E1vel do JMeter que referencia o grupo de conex\u00F5es.
18
query.displayName=Consulta
19
query.shortDescription=Consulta SQL que ser\u00E1 enviada ao banco de dados
20
queryArguments.displayName=Valores dos par\u00E2metros
21
queryArguments.shortDescription=Valores dos par\u00E2metros do SQL (separados por v\u00EDrgula)
22
queryArgumentsTypes.displayName=Tipos dos par\u00E2metros
23
queryArgumentsTypes.shortDescription=Nomes dos tipos do JDBC de java.sql.Types. VARCHAR, INTEGER, etc. (separados por v\u00EDrgula)
24
queryType.displayName=Tipo da Consulta
25
queryType.shortDescription=Determina se a instru\u00E7\u00E3o SQL dever\u00E1 ser executada como uma instru\u00E7\u00E3o de consulta ou de atualiza\u00E7\u00E3o.
26
sql.displayName=Consulta SQL
27
varName.displayName=Nome da vari\u00E1vel que referencia o grupo de conex\u00F5es.
28
variableNames.displayName=Nomes das vari\u00E1veis
29
variableNames.shortDescription=Nomes das vari\u00E1veis de sa\u00EDda para cada coluna (separado por v\u00EDrgula)
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources_tr.properties (+28 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=De\u011Fi\u015Fken \u0130smi
18
dataSource.shortDescription=Ba\u011Flant\u0131 havuzunun ili\u015Fkilendirilece\u011Fi JMeter de\u011Fi\u015Fkeninin ismi.
19
query.displayName=Sorgu
20
query.shortDescription=Veritaban\u0131na g\u00F6nderilecek SQL sorgusu
21
queryArguments.displayName=Parametre de\u011Ferleri
22
queryArguments.shortDescription=SQL parametresi de\u011Ferleri
23
queryArgumentsTypes.displayName=Parametre tipleri
24
queryArgumentsTypes.shortDescription=java.sql.Types'tan JDBC Tip isimleri. VARCHAR, INTEGER, gibi.
25
queryType.displayName=Sorgu Tipi
26
queryType.shortDescription=SQL ifadesinin select veya update ifadesi olarak \u00E7al\u0131\u015Ft\u0131r\u0131laca\u011F\u0131n\u0131 belirler.
27
sql.displayName=SQL Sorgusu
28
varName.displayName=Havuzla ili\u015Fkilendirilecek De\u011Fi\u015Fkenin \u0130smi
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/JDBCBeanInfoSupportResources_zh_TW.properties (+22 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=\u8B8A\u6578\u540D\u7A31
18
dataSource.shortDescription=\u8CC7\u6599\u5EAB\u9023\u7DDA\u6C60\u8B8A\u6578\u540D\u7A31
19
query.displayName=\u67E5\u8A62
20
query.shortDescription=\u50B3\u9001\u7D66\u8CC7\u6599\u5EAB\u7684 SQL \u654D\u8FF0
21
sql.displayName=SQL \u654D\u8FF0
22
varName.displayName=\u8CC7\u6599\u5EAB\u9023\u7DDA\u6C60\u8B8A\u6578\u540D\u7A31
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/AbstractJDBCProcessor.java (+40 lines)
Line 0 Link Here
1
package org.apache.jmeter.protocol.jdbc.processor;
2
3
import java.io.IOException;
4
import java.sql.Connection;
5
import java.sql.SQLException;
6
7
import org.apache.jmeter.protocol.jdbc.AbstractJdbcTestElement;
8
import org.apache.jmeter.protocol.jdbc.config.DataSourceElement;
9
import org.apache.jorphan.logging.LoggingManager;
10
import org.apache.log.Logger;
11
12
/**
13
 * As pre- and post-processors essentially do the same this class provides the implmentation.
14
 */
15
public abstract class AbstractJDBCProcessor extends AbstractJdbcTestElement {
16
    
17
    private static final Logger log = LoggingManager.getLoggerForClass();
18
19
    private static final long serialVersionUID = 232L;
20
21
    /**
22
     * Calls the JDBC code to be executed.
23
     */
24
    protected void process() {
25
        Connection conn = null;
26
        try {
27
            conn = DataSourceElement.getConnection(getDataSource());
28
            execute(conn);
29
        } catch (SQLException ex) {
30
            log.warn("SQL Problem in  "+ getName() + ": " + ex.toString());
31
        } catch (IOException ex) {
32
            log.warn("IO Problem in  "+ getName() + ": " + ex.toString());
33
        } catch (UnsupportedOperationException ex) {
34
            log.warn("Execution Problem in "+ getName() + ": " + ex.toString());
35
        } finally {
36
            close(conn);
37
        }
38
    }
39
40
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPostProcessor.java (+16 lines)
Line 0 Link Here
1
package org.apache.jmeter.protocol.jdbc.processor;
2
3
import org.apache.jmeter.processor.PostProcessor;
4
import org.apache.jmeter.testbeans.TestBean;
5
6
/**
7
 * Post processor handling JDBC Requests
8
 */
9
public class JDBCPostProcessor extends AbstractJDBCProcessor implements TestBean, PostProcessor {
10
11
    @Override
12
    public void process() {
13
        super.process();
14
    }
15
    
16
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPostProcessorBeanInfo.java (+36 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
/*
20
 * Created on May 16, 2004
21
 *
22
 */
23
package org.apache.jmeter.protocol.jdbc.processor;
24
25
import org.apache.jmeter.protocol.jdbc.JDBCBeanInfoSupport;
26
27
28
public class JDBCPostProcessorBeanInfo extends JDBCBeanInfoSupport {
29
30
    /**
31
     *
32
     */
33
    public JDBCPostProcessorBeanInfo() {
34
        super(JDBCPostProcessor.class);
35
    }
36
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPostProcessorResources.properties (+16 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
displayName=JDBC PostProcessor Request
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPreProcessor.java (+16 lines)
Line 0 Link Here
1
package org.apache.jmeter.protocol.jdbc.processor;
2
3
import org.apache.jmeter.processor.PreProcessor;
4
import org.apache.jmeter.testbeans.TestBean;
5
6
/**
7
 * Preprocessor handling JDBC Requests
8
 */
9
public class JDBCPreProcessor extends AbstractJDBCProcessor implements TestBean, PreProcessor {
10
11
    @Override
12
    public void process() {
13
        super.process();
14
    }
15
    
16
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPreProcessorBeanInfo.java (+36 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
/*
20
 * Created on May 16, 2004
21
 *
22
 */
23
package org.apache.jmeter.protocol.jdbc.processor;
24
25
import org.apache.jmeter.protocol.jdbc.JDBCBeanInfoSupport;
26
27
28
public class JDBCPreProcessorBeanInfo extends JDBCBeanInfoSupport {
29
30
    /**
31
     *
32
     */
33
    public JDBCPreProcessorBeanInfo() {
34
        super(JDBCPreProcessor.class);
35
    }
36
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/processor/JDBCPreProcessorResources.properties (+16 lines)
Line 0 Link Here
1
#   Licensed to the Apache Software Foundation (ASF) under one or more
2
#   contributor license agreements.  See the NOTICE file distributed with
3
#   this work for additional information regarding copyright ownership.
4
#   The ASF licenses this file to You under the Apache License, Version 2.0
5
#   (the "License"); you may not use this file except in compliance with
6
#   the License.  You may obtain a copy of the License at
7
# 
8
#       http://www.apache.org/licenses/LICENSE-2.0
9
# 
10
#   Unless required by applicable law or agreed to in writing, software
11
#   distributed under the License is distributed on an "AS IS" BASIS,
12
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
15
16
displayName=JDBC PreProcessor Request
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSampler.java (-523 / +8 lines)
Lines 19-49 Link Here
19
package org.apache.jmeter.protocol.jdbc.sampler;
19
package org.apache.jmeter.protocol.jdbc.sampler;
20
20
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.UnsupportedEncodingException;
23
import java.lang.reflect.Field;
24
import java.sql.CallableStatement;
25
import java.sql.Connection;
22
import java.sql.Connection;
26
import java.sql.PreparedStatement;
27
import java.sql.ResultSet;
28
import java.sql.ResultSetMetaData;
29
import java.sql.SQLException;
23
import java.sql.SQLException;
30
import java.sql.Statement;
31
import java.util.ArrayList;
32
import java.util.Collection;
33
import java.util.HashMap;
34
import java.util.LinkedHashMap;
35
import java.util.List;
36
import java.util.Map;
37
24
38
import org.apache.commons.lang.text.StrBuilder;
25
import org.apache.jmeter.protocol.jdbc.AbstractJdbcTestElement;
39
import org.apache.jmeter.protocol.jdbc.config.DataSourceElement;
26
import org.apache.jmeter.protocol.jdbc.config.DataSourceElement;
40
import org.apache.jmeter.samplers.AbstractSampler;
41
import org.apache.jmeter.samplers.Entry;
27
import org.apache.jmeter.samplers.Entry;
42
import org.apache.jmeter.samplers.SampleResult;
28
import org.apache.jmeter.samplers.SampleResult;
43
import org.apache.jmeter.save.CSVSaveService;
29
import org.apache.jmeter.samplers.Sampler;
44
import org.apache.jmeter.testbeans.TestBean;
30
import org.apache.jmeter.testbeans.TestBean;
45
import org.apache.jmeter.threads.JMeterVariables;
46
import org.apache.jmeter.util.JMeterUtils;
47
import org.apache.jorphan.logging.LoggingManager;
31
import org.apache.jorphan.logging.LoggingManager;
48
import org.apache.log.Logger;
32
import org.apache.log.Logger;
49
33
Lines 51-147 Link Here
51
 * A sampler which understands JDBC database requests.
35
 * A sampler which understands JDBC database requests.
52
 *
36
 *
53
 */
37
 */
54
public class JDBCSampler extends AbstractSampler implements TestBean {
38
public class JDBCSampler extends AbstractJdbcTestElement implements Sampler, TestBean {
55
    private static final long serialVersionUID = 233L;
39
    
56
40
    private static final long serialVersionUID = 234L;
41
    
57
    private static final Logger log = LoggingManager.getLoggerForClass();
42
    private static final Logger log = LoggingManager.getLoggerForClass();
58
43
59
    private static final String COMMA = ","; // $NON-NLS-1$
60
    private static final char COMMA_CHAR = ',';
61
62
    private static final String UNDERSCORE = "_"; // $NON-NLS-1$
63
64
    // This value is used for both the connection (perConnCache) and statement (preparedStatementMap) caches.
65
    // TODO - do they have to be the same size?
66
    private static final int MAX_ENTRIES =
67
        JMeterUtils.getPropDefault("jdbcsampler.cachesize",200); // $NON-NLS-1$
68
69
    // String used to indicate a null value
70
    private static final String NULL_MARKER =
71
        JMeterUtils.getPropDefault("jdbcsampler.nullmarker","]NULL["); // $NON-NLS-1$
72
73
    private static final String INOUT = "INOUT"; // $NON-NLS-1$
74
75
    private static final String OUT = "OUT"; // $NON-NLS-1$
76
77
    // TODO - should the encoding be configurable?
78
    private static final String ENCODING = "UTF-8"; // $NON-NLS-1$
79
80
    // key: name (lowercase) from java.sql.Types; entry: corresponding int value
81
    private static final Map<String, Integer> mapJdbcNameToInt;
82
    // read-only after class init
83
84
    static {
85
        // based on e291. Getting the Name of a JDBC Type from javaalmanac.com
86
        // http://javaalmanac.com/egs/java.sql/JdbcInt2Str.html
87
        mapJdbcNameToInt = new HashMap<String, Integer>();
88
89
        //Get all fields in java.sql.Types and store the corresponding int values
90
        Field[] fields = java.sql.Types.class.getFields();
91
        for (int i=0; i<fields.length; i++) {
92
            try {
93
                String name = fields[i].getName();
94
                Integer value = (Integer)fields[i].get(null);
95
                mapJdbcNameToInt.put(name.toLowerCase(java.util.Locale.ENGLISH),value);
96
            } catch (IllegalAccessException e) {
97
                throw new RuntimeException(e); // should not happen
98
            }
99
        }
100
    }
101
102
    // Query types (used to communicate with GUI)
103
    // N.B. These must not be changed, as they are used in the JMX files
104
    static final String SELECT   = "Select Statement"; // $NON-NLS-1$
105
    static final String UPDATE   = "Update Statement"; // $NON-NLS-1$
106
    static final String CALLABLE = "Callable Statement"; // $NON-NLS-1$
107
    static final String PREPARED_SELECT = "Prepared Select Statement"; // $NON-NLS-1$
108
    static final String PREPARED_UPDATE = "Prepared Update Statement"; // $NON-NLS-1$
109
    static final String COMMIT   = "Commit"; // $NON-NLS-1$
110
    static final String ROLLBACK = "Rollback"; // $NON-NLS-1$
111
    static final String AUTOCOMMIT_FALSE = "AutoCommit(false)"; // $NON-NLS-1$
112
    static final String AUTOCOMMIT_TRUE  = "AutoCommit(true)"; // $NON-NLS-1$
113
114
    private String query = ""; // $NON-NLS-1$
115
116
    private String dataSource = ""; // $NON-NLS-1$
117
118
    private String queryType = SELECT;
119
    private String queryArguments = ""; // $NON-NLS-1$
120
    private String queryArgumentsTypes = ""; // $NON-NLS-1$
121
    private String variableNames = ""; // $NON-NLS-1$
122
    private String resultVariable = "";
123
124
    /**
44
    /**
125
     *  Cache of PreparedStatements stored in a per-connection basis. Each entry of this
126
     *  cache is another Map mapping the statement string to the actual PreparedStatement.
127
     *  The cache has a fixed size of MAX_ENTRIES and it will throw away all PreparedStatements
128
     *  from the least recently used connections.
129
     */
130
    private static final Map<Connection, Map<String, PreparedStatement>> perConnCache =
131
        new LinkedHashMap<Connection, Map<String, PreparedStatement>>(MAX_ENTRIES){
132
        private static final long serialVersionUID = 1L;
133
        @Override
134
        protected boolean removeEldestEntry(Map.Entry<Connection, Map<String, PreparedStatement>> arg0) {
135
            if (size() > MAX_ENTRIES) {
136
                final  Map<String, PreparedStatement> value = arg0.getValue();
137
                closeAllStatements(value.values());
138
                return true;
139
            }
140
            return false;
141
        }
142
    };
143
144
    /**
145
     * Creates a JDBCSampler.
45
     * Creates a JDBCSampler.
146
     */
46
     */
147
    public JDBCSampler() {
47
    public JDBCSampler() {
Lines 165-171 Link Here
165
65
166
        res.sampleStart();
66
        res.sampleStart();
167
        Connection conn = null;
67
        Connection conn = null;
168
        Statement stmt = null;
169
68
170
        try {
69
        try {
171
70
Lines 175-242 Link Here
175
                res.latencyEnd(); // use latency to measure connection time
74
                res.latencyEnd(); // use latency to measure connection time
176
            }
75
            }
177
            res.setResponseHeaders(conn.toString());
76
            res.setResponseHeaders(conn.toString());
77
            res.setResponseData(execute(conn));
178
78
179
            // Based on query return value, get results
180
            String _queryType = getQueryType();
181
            if (SELECT.equals(_queryType)) {
182
                stmt = conn.createStatement();
183
                ResultSet rs = null;
184
                try {
185
                    rs = stmt.executeQuery(getQuery());
186
                    res.setResponseData(getStringFromResultSet(rs).getBytes(ENCODING));
187
                } finally {
188
                    close(rs);
189
                }
190
            } else if (CALLABLE.equals(_queryType)) {
191
                CallableStatement cstmt = getCallableStatement(conn);
192
                int out[]=setArguments(cstmt);
193
                // A CallableStatement can return more than 1 ResultSets
194
                // plus a number of update counts.
195
                boolean hasResultSet = cstmt.execute();
196
                String sb = resultSetsToString(cstmt,hasResultSet, out);
197
                res.setResponseData(sb.getBytes(ENCODING));
198
            } else if (UPDATE.equals(_queryType)) {
199
                stmt = conn.createStatement();
200
                stmt.executeUpdate(getQuery());
201
                int updateCount = stmt.getUpdateCount();
202
                String results = updateCount + " updates";
203
                res.setResponseData(results.getBytes(ENCODING));
204
            } else if (PREPARED_SELECT.equals(_queryType)) {
205
                PreparedStatement pstmt = getPreparedStatement(conn);
206
                setArguments(pstmt);
207
                boolean hasResultSet = pstmt.execute();
208
                String sb = resultSetsToString(pstmt,hasResultSet,null);
209
                res.setResponseData(sb.getBytes(ENCODING));
210
            } else if (PREPARED_UPDATE.equals(_queryType)) {
211
                PreparedStatement pstmt = getPreparedStatement(conn);
212
                setArguments(pstmt);
213
                pstmt.executeUpdate();
214
                String sb = resultSetsToString(pstmt,false,null);
215
                res.setResponseData(sb.getBytes(ENCODING));
216
            } else if (ROLLBACK.equals(_queryType)){
217
                conn.rollback();
218
                res.setResponseData(ROLLBACK.getBytes(ENCODING));
219
            } else if (COMMIT.equals(_queryType)){
220
                conn.commit();
221
                res.setResponseData(COMMIT.getBytes(ENCODING));
222
            } else if (AUTOCOMMIT_FALSE.equals(_queryType)){
223
                conn.setAutoCommit(false);
224
                res.setResponseData(AUTOCOMMIT_FALSE.getBytes(ENCODING));
225
            } else if (AUTOCOMMIT_TRUE.equals(_queryType)){
226
                conn.setAutoCommit(true);
227
                res.setResponseData(AUTOCOMMIT_TRUE.getBytes(ENCODING));
228
            } else { // User provided incorrect query type
229
                String results="Unexpected query type: "+_queryType;
230
                res.setResponseMessage(results);
231
                res.setSuccessful(false);
232
            }
233
234
        } catch (SQLException ex) {
79
        } catch (SQLException ex) {
235
            final String errCode = Integer.toString(ex.getErrorCode());
80
            final String errCode = Integer.toString(ex.getErrorCode());
236
            res.setResponseMessage(ex.toString());
81
            res.setResponseMessage(ex.toString());
237
            res.setResponseCode(ex.getSQLState()+ " " +errCode);
82
            res.setResponseCode(ex.getSQLState()+ " " +errCode);
238
            res.setSuccessful(false);
83
            res.setSuccessful(false);
239
        } catch (UnsupportedEncodingException ex) {
84
        } catch (UnsupportedOperationException ex) {
240
            res.setResponseMessage(ex.toString());
85
            res.setResponseMessage(ex.toString());
241
            res.setResponseCode("000"); // TODO - is this correct?
86
            res.setResponseCode("000"); // TODO - is this correct?
242
            res.setSuccessful(false);
87
            res.setSuccessful(false);
Lines 245-251 Link Here
245
            res.setResponseCode("000"); // TODO - is this correct?
90
            res.setResponseCode("000"); // TODO - is this correct?
246
            res.setSuccessful(false);
91
            res.setSuccessful(false);
247
        } finally {
92
        } finally {
248
            close(stmt);
249
            close(conn);
93
            close(conn);
250
        }
94
        }
251
95
Lines 253-615 Link Here
253
        res.sampleEnd();
97
        res.sampleEnd();
254
        return res;
98
        return res;
255
    }
99
    }
256
257
    private String resultSetsToString(PreparedStatement pstmt, boolean result, int[] out) throws SQLException, UnsupportedEncodingException {
258
        StrBuilder sb = new StrBuilder();
259
        int updateCount = 0;
260
        if (!result) {
261
            updateCount = pstmt.getUpdateCount();
262
        }
263
        do {
264
            if (result) {
265
                ResultSet rs = null;
266
                try {
267
                    rs = pstmt.getResultSet();
268
                    sb.append(getStringFromResultSet(rs)).append("\n"); // $NON-NLS-1$
269
                } finally {
270
                    close(rs);
271
                }
272
            } else {
273
                sb.append(updateCount).append(" updates.\n");
274
            }
275
            result = pstmt.getMoreResults();
276
            if (!result) {
277
                updateCount = pstmt.getUpdateCount();
278
            }
279
        } while (result || (updateCount != -1));
280
        if (out!=null && pstmt instanceof CallableStatement){
281
            CallableStatement cs = (CallableStatement) pstmt;
282
            sb.append("Output variables by position:\n");
283
            for(int i=0; i < out.length; i++){
284
                if (out[i]!=java.sql.Types.NULL){
285
                    sb.append("[");
286
                    sb.append(i+1);
287
                    sb.append("] ");
288
                    sb.append(cs.getObject(i+1));
289
                    sb.append("\n");
290
                }
291
            }
292
        }
293
        return sb.toString();
294
    }
295
296
297
    private int[] setArguments(PreparedStatement pstmt) throws SQLException, IOException {
298
        if (getQueryArguments().trim().length()==0) {
299
            return new int[]{};
300
        }
301
        String[] arguments = CSVSaveService.csvSplitString(getQueryArguments(), COMMA_CHAR);
302
        String[] argumentsTypes = getQueryArgumentsTypes().split(COMMA);
303
        if (arguments.length != argumentsTypes.length) {
304
            throw new SQLException("number of arguments ("+arguments.length+") and number of types ("+argumentsTypes.length+") are not equal");
305
        }
306
        int[] outputs= new int[arguments.length];
307
        for (int i = 0; i < arguments.length; i++) {
308
            String argument = arguments[i];
309
            String argumentType = argumentsTypes[i];
310
            String[] arg = argumentType.split(" ");
311
            String inputOutput="";
312
            if (arg.length > 1) {
313
                argumentType = arg[1];
314
                inputOutput=arg[0];
315
            }
316
            int targetSqlType = getJdbcType(argumentType);
317
            try {
318
                if (!OUT.equalsIgnoreCase(inputOutput)){
319
                    if (argument.equals(NULL_MARKER)){
320
                        pstmt.setNull(i+1, targetSqlType);
321
                    } else {
322
                        pstmt.setObject(i+1, argument, targetSqlType);
323
                    }
324
                }
325
                if (OUT.equalsIgnoreCase(inputOutput)||INOUT.equalsIgnoreCase(inputOutput)) {
326
                    CallableStatement cs = (CallableStatement) pstmt;
327
                    cs.registerOutParameter(i+1, targetSqlType);
328
                    outputs[i]=targetSqlType;
329
                } else {
330
                    outputs[i]=java.sql.Types.NULL; // can't have an output parameter type null
331
                }
332
            } catch (NullPointerException e) { // thrown by Derby JDBC (at least) if there are no "?" markers in statement
333
                throw new SQLException("Could not set argument no: "+(i+1)+" - missing parameter marker?");
334
            }
335
        }
336
        return outputs;
337
    }
338
339
340
    private static int getJdbcType(String jdbcType) throws SQLException {
341
        Integer entry = mapJdbcNameToInt.get(jdbcType.toLowerCase(java.util.Locale.ENGLISH));
342
        if (entry == null) {
343
            try {
344
                entry = Integer.decode(jdbcType);
345
            } catch (NumberFormatException e) {
346
                throw new SQLException("Invalid data type: "+jdbcType);
347
            }
348
        }
349
        return (entry).intValue();
350
    }
351
352
353
    private CallableStatement getCallableStatement(Connection conn) throws SQLException {
354
        return (CallableStatement) getPreparedStatement(conn,true);
355
356
    }
357
    private PreparedStatement getPreparedStatement(Connection conn) throws SQLException {
358
        return getPreparedStatement(conn,false);
359
    }
360
361
    private PreparedStatement getPreparedStatement(Connection conn, boolean callable) throws SQLException {
362
        Map<String, PreparedStatement> preparedStatementMap = perConnCache.get(conn);
363
        if (null == preparedStatementMap ) {
364
            // MRU PreparedStatements cache.
365
            preparedStatementMap = new LinkedHashMap<String, PreparedStatement>(MAX_ENTRIES) {
366
                private static final long serialVersionUID = 240L;
367
368
                @Override
369
                protected boolean removeEldestEntry(Map.Entry<String, PreparedStatement> arg0) {
370
                    final int theSize = size();
371
                    if (theSize > MAX_ENTRIES) {
372
                        Object value = arg0.getValue();
373
                        if (value instanceof PreparedStatement) {
374
                            PreparedStatement pstmt = (PreparedStatement) value;
375
                            close(pstmt);
376
                        }
377
                        return true;
378
                    }
379
                    return false;
380
                }
381
            };
382
            perConnCache.put(conn, preparedStatementMap);
383
        }
384
        PreparedStatement pstmt = preparedStatementMap.get(getQuery());
385
        if (null == pstmt) {
386
            if (callable) {
387
                pstmt = conn.prepareCall(getQuery());
388
            } else {
389
                pstmt = conn.prepareStatement(getQuery());
390
            }
391
            preparedStatementMap.put(getQuery(), pstmt);
392
        }
393
        pstmt.clearParameters();
394
        return pstmt;
395
    }
396
397
    private static void closeAllStatements(Collection<PreparedStatement> collection) {
398
        for (PreparedStatement pstmt : collection) {
399
            close(pstmt);
400
        }
401
    }
402
403
    /**
404
     * Gets a Data object from a ResultSet.
405
     *
406
     * @param rs
407
     *            ResultSet passed in from a database query
408
     * @return a Data object
409
     * @throws java.sql.SQLException
410
     * @throws UnsupportedEncodingException
411
     */
412
    private String getStringFromResultSet(ResultSet rs) throws SQLException, UnsupportedEncodingException {
413
        ResultSetMetaData meta = rs.getMetaData();
414
415
        StrBuilder sb = new StrBuilder();
416
417
        int numColumns = meta.getColumnCount();
418
        for (int i = 1; i <= numColumns; i++) {
419
            sb.append(meta.getColumnName(i));
420
            if (i==numColumns){
421
                sb.append('\n');
422
            } else {
423
                sb.append('\t');
424
            }
425
        }
426
        
427
428
        JMeterVariables jmvars = getThreadContext().getVariables();
429
        String varnames[] = getVariableNames().split(COMMA);
430
        String resultVariable = getResultVariable().trim();
431
        List<Map<String, Object> > results = null;
432
        if(resultVariable.length() > 0) {
433
            results = new ArrayList<Map<String,Object> >();
434
            jmvars.putObject(resultVariable, results);
435
        }
436
        int j = 0;
437
        while (rs.next()) {
438
        	Map<String, Object> row = null;
439
            j++;
440
            for (int i = 1; i <= numColumns; i++) {
441
                Object o = rs.getObject(i);
442
                if(results != null) {
443
                	if(row == null) {
444
                		row = new HashMap<String, Object>(numColumns);
445
                		results.add(row);
446
                	}
447
                	row.put(meta.getColumnName(i), o);
448
                }
449
                if (o instanceof byte[]) {
450
                    o = new String((byte[]) o, ENCODING);
451
                }
452
                sb.append(o);
453
                if (i==numColumns){
454
                    sb.append('\n');
455
                } else {
456
                    sb.append('\t');
457
                }
458
                if (i <= varnames.length) { // i starts at 1
459
                    String name = varnames[i - 1].trim();
460
                    if (name.length()>0){ // Save the value in the variable if present
461
                        jmvars.put(name+UNDERSCORE+j, o == null ? null : o.toString());
462
                    }
463
                }
464
            }
465
        }
466
        // Remove any additional values from previous sample
467
        for(int i=0; i < varnames.length; i++){
468
            String name = varnames[i].trim();
469
            if (name.length()>0 && jmvars != null){
470
                final String varCount = name+"_#"; // $NON-NLS-1$
471
                // Get the previous count
472
                String prevCount = jmvars.get(varCount);
473
                if (prevCount != null){
474
                    int prev = Integer.parseInt(prevCount);
475
                    for (int n=j+1; n <= prev; n++ ){
476
                        jmvars.remove(name+UNDERSCORE+n);
477
                    }
478
                }
479
                jmvars.put(varCount, Integer.toString(j)); // save the current count
480
            }
481
        }
482
483
        return sb.toString();
484
    }
485
486
    public static void close(Connection c) {
487
        try {
488
            if (c != null) {
489
                c.close();
490
            }
491
        } catch (SQLException e) {
492
            log.warn("Error closing Connection", e);
493
        }
494
    }
495
496
    public static void close(Statement s) {
497
        try {
498
            if (s != null) {
499
                s.close();
500
            }
501
        } catch (SQLException e) {
502
            log.warn("Error closing Statement " + s.toString(), e);
503
        }
504
    }
505
506
    public static void close(ResultSet rs) {
507
        try {
508
            if (rs != null) {
509
                rs.close();
510
            }
511
        } catch (SQLException e) {
512
            log.warn("Error closing ResultSet", e);
513
        }
514
    }
515
516
    public String getQuery() {
517
        return query;
518
    }
519
520
    @Override
521
    public String toString() {
522
        StrBuilder sb = new StrBuilder(80);
523
        sb.append("["); // $NON-NLS-1$
524
        sb.append(getQueryType());
525
        sb.append("] "); // $NON-NLS-1$
526
        sb.append(getQuery());
527
        sb.append("\n");
528
        sb.append(getQueryArguments());
529
        sb.append("\n");
530
        sb.append(getQueryArgumentsTypes());
531
        return sb.toString();
532
    }
533
534
    /**
535
     * @param query
536
     *            The query to set.
537
     */
538
    public void setQuery(String query) {
539
        this.query = query;
540
    }
541
542
    /**
543
     * @return Returns the dataSource.
544
     */
545
    public String getDataSource() {
546
        return dataSource;
547
    }
548
549
    /**
550
     * @param dataSource
551
     *            The dataSource to set.
552
     */
553
    public void setDataSource(String dataSource) {
554
        this.dataSource = dataSource;
555
    }
556
557
    /**
558
     * @return Returns the queryType.
559
     */
560
    public String getQueryType() {
561
        return queryType;
562
    }
563
564
    /**
565
     * @param queryType The queryType to set.
566
     */
567
    public void setQueryType(String queryType) {
568
        this.queryType = queryType;
569
    }
570
571
    public String getQueryArguments() {
572
        return queryArguments;
573
    }
574
575
    public void setQueryArguments(String queryArguments) {
576
        this.queryArguments = queryArguments;
577
    }
578
579
    public String getQueryArgumentsTypes() {
580
        return queryArgumentsTypes;
581
    }
582
583
    public void setQueryArgumentsTypes(String queryArgumentsType) {
584
        this.queryArgumentsTypes = queryArgumentsType;
585
    }
586
587
    /**
588
     * @return the variableNames
589
     */
590
    public String getVariableNames() {
591
        return variableNames;
592
    }
593
594
    /**
595
     * @param variableNames the variableNames to set
596
     */
597
    public void setVariableNames(String variableNames) {
598
        this.variableNames = variableNames;
599
    }
600
601
    /**
602
     * @return the resultVariable
603
     */
604
	public String getResultVariable() {
605
		return resultVariable ;
606
	}
607
608
    /**
609
     * @param resultVariable the variable name in which results will be stored
610
     */
611
	public void setResultVariable(String resultVariable) {
612
		this.resultVariable = resultVariable;
613
	}
614
    
615
}
100
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerBeanInfo.java (-59 / +2 lines)
Lines 22-93 Link Here
22
 */
22
 */
23
package org.apache.jmeter.protocol.jdbc.sampler;
23
package org.apache.jmeter.protocol.jdbc.sampler;
24
24
25
import java.beans.PropertyDescriptor;
25
import org.apache.jmeter.protocol.jdbc.JDBCBeanInfoSupport;
26
26
27
import org.apache.jmeter.testbeans.BeanInfoSupport;
28
import org.apache.jmeter.testbeans.gui.TextAreaEditor;
29
27
30
public class JDBCSamplerBeanInfo extends BeanInfoSupport {
28
public class JDBCSamplerBeanInfo extends JDBCBeanInfoSupport {
31
29
32
    /**
30
    /**
33
     *
31
     *
34
     */
32
     */
35
    public JDBCSamplerBeanInfo() {
33
    public JDBCSamplerBeanInfo() {
36
        super(JDBCSampler.class);
34
        super(JDBCSampler.class);
37
38
        createPropertyGroup("varName", // $NON-NLS-1$
39
                new String[]{"dataSource" }); // $NON-NLS-1$
40
41
        createPropertyGroup("sql", // $NON-NLS-1$
42
                new String[] {
43
                "queryType", // $NON-NLS-1$
44
                "query", // $NON-NLS-1$
45
                "queryArguments", // $NON-NLS-1$
46
                "queryArgumentsTypes", // $NON-NLS-1$
47
                "variableNames", // $NON-NLS-1$
48
                "resultVariable", // $NON-NLS-1$
49
                });
50
51
        PropertyDescriptor p = property("dataSource"); // $NON-NLS-1$
52
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
53
        p.setValue(DEFAULT, "");
54
55
        p = property("queryArguments"); // $NON-NLS-1$
56
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
57
        p.setValue(DEFAULT, "");
58
59
        p = property("queryArgumentsTypes"); // $NON-NLS-1$
60
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
61
        p.setValue(DEFAULT, "");
62
63
        p = property("variableNames"); // $NON-NLS-1$
64
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
65
        p.setValue(DEFAULT, "");
66
67
        p = property("resultVariable"); // $NON-NLS-1$
68
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
69
        p.setValue(DEFAULT, "");
70
71
        p = property("queryType"); // $NON-NLS-1$
72
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
73
        p.setValue(DEFAULT, JDBCSampler.SELECT);
74
        p.setValue(NOT_OTHER,Boolean.TRUE);
75
        p.setValue(TAGS,new String[]{
76
                JDBCSampler.SELECT,
77
                JDBCSampler.UPDATE,
78
                JDBCSampler.CALLABLE,
79
                JDBCSampler.PREPARED_SELECT,
80
                JDBCSampler.PREPARED_UPDATE,
81
                JDBCSampler.COMMIT,
82
                JDBCSampler.ROLLBACK,
83
                JDBCSampler.AUTOCOMMIT_FALSE,
84
                JDBCSampler.AUTOCOMMIT_TRUE,
85
                });
86
87
        p = property("query"); // $NON-NLS-1$
88
        p.setValue(NOT_UNDEFINED, Boolean.TRUE);
89
        p.setValue(DEFAULT, "");
90
        p.setPropertyEditorClass(TextAreaEditor.class);
91
92
    }
35
    }
93
}
36
}
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources.properties (-17 lines)
Lines 14-33 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
displayName=JDBC Request
16
displayName=JDBC Request
17
varName.displayName=Variable Name Bound to Pool
18
sql.displayName=SQL Query
19
query.displayName=Query
20
query.shortDescription=SQL Query to send to database
21
queryType.displayName=Query Type
22
queryType.shortDescription=Determines if the SQL statement should be run as a select statement or an update statement.
23
dataSource.displayName=Variable Name
24
dataSource.shortDescription=Name of the JMeter variable that the connection pool is bound to.
25
queryArguments.displayName=Parameter values
26
queryArguments.shortDescription=SQL parameter values (comma separated)
27
queryArgumentsTypes.displayName=Parameter types
28
queryArgumentsTypes.shortDescription=JDBC Type names from java.sql.Types. VARCHAR, INTEGER, etc. (comma separated)
29
variableNames.displayName=Variable names
30
variableNames.shortDescription=Output variable names for each column  (comma separated)
31
resultVariable.displayName=Result variable name
32
resultVariable.shortDescription=Name of the JMeter variable that stores the result set objects in a list of maps for looking up results by column name.
33
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources_es.properties (-13 lines)
Lines 14-30 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
#Stored by I18NEdit, may be edited!
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=Nombre de Variable
18
dataSource.shortDescription=Nombre de la variable JMeter a la cual est\u00E1 ligado el pool de conexiones
19
displayName=Petici\u00F3n JDBC
17
displayName=Petici\u00F3n JDBC
20
query.displayName=Query
21
query.shortDescription=Query SQL a enviar a la base de datos
22
queryType.displayName=Solo Query
23
queryType.shortDescription=is true, se lanzar\u00E1 como una query y no como un update/inser. Si no, se lanza como update.
24
sql.displayName=Query SQL
25
varName.displayName=Nombre de Variable Ligada al Pool
26
queryArguments.displayName=Argumentos
27
queryArguments.shortDescription=los valores de los argumentos separados por comas
28
queryArgumentsTypes.displayName=Tipos de los argumentos
29
queryArgumentsTypes.shortDescription=los valores de los argumentos separados por comas
30
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources_fr.properties (-16 lines)
Lines 14-33 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
#Stored by I18NEdit, may be edited!
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=Nom de liaison 
18
dataSource.shortDescription=Nom de la variable JMeter qui sera li\u00E9e au pool de connexion
19
displayName=Requ\u00EAte JDBC
17
displayName=Requ\u00EAte JDBC
20
query.displayName=Requ\u00EAte 
21
query.shortDescription=Requ\u00EAte SQL \u00E0 envoyer \u00E0 la base de donn\u00E9es
22
queryArguments.displayName=Valeurs des param\u00E8tres 
23
queryArguments.shortDescription=Valeurs des param\u00E8tres SQL
24
queryArgumentsTypes.displayName=Types des param\u00E8tres 
25
queryArgumentsTypes.shortDescription=Noms des types JDBC depuis java.sql.Types. Ex. VARCHAR, INTEGER, etc. (s\u00E9par\u00E9s par des virgules)
26
queryType.displayName=Type de requ\u00EAte 
27
queryType.shortDescription=D\u00E9termine si l'instruction SQL doit \u00EAtre ex\u00E9cut\u00E9e comme une commande SELECT ou une commande UPDATE.
28
resultVariable.displayName=Nom de la variable des R\u00E9sultats
29
resultVariable.shortDescription=Nom de la variable JMeter qui stocke les r\u00E9sultats sous forme d'objets dans une liste de type 'maps' permettant la recherche des r\u00E9sultats par nom de colonne.
30
sql.displayName=Requ\u00EAte SQL
31
varName.displayName=Nom de liaison avec le pool
32
variableNames.displayName=Noms des variables 
33
variableNames.shortDescription=Noms des variables en sortie pour chaque colonne (s\u00E9par\u00E9s par des virgules)
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources_pt_BR.properties (-14 lines)
Lines 13-30 Link Here
13
#   See the License for the specific language governing permissions and
13
#   See the License for the specific language governing permissions and
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
dataSource.displayName=Nome da Vari\u00E1vel
17
dataSource.shortDescription=Nome da vari\u00E1vel do JMeter que referencia o grupo de conex\u00F5es.
18
displayName=Requisi\u00E7\u00E3o JDBC
16
displayName=Requisi\u00E7\u00E3o JDBC
19
query.displayName=Consulta
20
query.shortDescription=Consulta SQL que ser\u00E1 enviada ao banco de dados
21
queryArguments.displayName=Valores dos par\u00E2metros
22
queryArguments.shortDescription=Valores dos par\u00E2metros do SQL (separados por v\u00EDrgula)
23
queryArgumentsTypes.displayName=Tipos dos par\u00E2metros
24
queryArgumentsTypes.shortDescription=Nomes dos tipos do JDBC de java.sql.Types. VARCHAR, INTEGER, etc. (separados por v\u00EDrgula)
25
queryType.displayName=Tipo da Consulta
26
queryType.shortDescription=Determina se a instru\u00E7\u00E3o SQL dever\u00E1 ser executada como uma instru\u00E7\u00E3o de consulta ou de atualiza\u00E7\u00E3o.
27
sql.displayName=Consulta SQL
28
varName.displayName=Nome da vari\u00E1vel que referencia o grupo de conex\u00F5es.
29
variableNames.displayName=Nomes das vari\u00E1veis
30
variableNames.shortDescription=Nomes das vari\u00E1veis de sa\u00EDda para cada coluna (separado por v\u00EDrgula)
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources_tr.properties (-12 lines)
Lines 14-29 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
#Stored by I18NEdit, may be edited!
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=De\u011Fi\u015Fken \u0130smi
18
dataSource.shortDescription=Ba\u011Flant\u0131 havuzunun ili\u015Fkilendirilece\u011Fi JMeter de\u011Fi\u015Fkeninin ismi.
19
displayName=JDBC \u0130ste\u011Fi
17
displayName=JDBC \u0130ste\u011Fi
20
query.displayName=Sorgu
21
query.shortDescription=Veritaban\u0131na g\u00F6nderilecek SQL sorgusu
22
queryArguments.displayName=Parametre de\u011Ferleri
23
queryArguments.shortDescription=SQL parametresi de\u011Ferleri
24
queryArgumentsTypes.displayName=Parametre tipleri
25
queryArgumentsTypes.shortDescription=java.sql.Types'tan JDBC Tip isimleri. VARCHAR, INTEGER, gibi.
26
queryType.displayName=Sorgu Tipi
27
queryType.shortDescription=SQL ifadesinin select veya update ifadesi olarak \u00E7al\u0131\u015Ft\u0131r\u0131laca\u011F\u0131n\u0131 belirler.
28
sql.displayName=SQL Sorgusu
29
varName.displayName=Havuzla ili\u015Fkilendirilecek De\u011Fi\u015Fkenin \u0130smi
(-)src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/sampler/JDBCSamplerResources_zh_TW.properties (-6 lines)
Lines 14-23 Link Here
14
#   limitations under the License.
14
#   limitations under the License.
15
15
16
#Stored by I18NEdit, may be edited!
16
#Stored by I18NEdit, may be edited!
17
dataSource.displayName=\u8B8A\u6578\u540D\u7A31
18
dataSource.shortDescription=\u8CC7\u6599\u5EAB\u9023\u7DDA\u6C60\u8B8A\u6578\u540D\u7A31
19
displayName=JDBC \u8981\u6C42
17
displayName=JDBC \u8981\u6C42
20
query.displayName=\u67E5\u8A62
21
query.shortDescription=\u50B3\u9001\u7D66\u8CC7\u6599\u5EAB\u7684 SQL \u654D\u8FF0
22
sql.displayName=SQL \u654D\u8FF0
23
varName.displayName=\u8CC7\u6599\u5EAB\u9023\u7DDA\u6C60\u8B8A\u6578\u540D\u7A31

Return to bug 52128