00001 #include <QApplication>
00002 #include <QtSql>
00003 #include <time.h>
00004 #include <iostream>
00005 using namespace std;
00006
00007
00008 #define HOST "127.0.0.1"
00009 #define DB "xe"
00010 #define PORT 1521
00011 #define USER "testbed"
00012 #define PASSWD "secret"
00013
00014 QString clean_error_msg(QString msg) {
00015 return msg.replace("\n", "\n\t");
00016 }
00017
00018 bool test_connect(QSqlDatabase& db) {
00019 if (db.open() == FALSE) {
00020 cout << "\n\tError: opening DB failed because "
00021 << clean_error_msg(db.lastError().text()).toStdString() << endl;
00022 return false;
00023 }
00024 return true;
00025 }
00026
00027 bool test_create_table(QSqlDatabase& db) {
00028 const char create_sql[] =
00029 "create table occi_datatype_example_tb ( \
00030 col_varchar varchar2(100), \
00031 col_number number, \
00032 col_char char, \
00033 col_date date, \
00034 col_time timestamp, \
00035 col_blob blob )";
00036 QSqlQuery query(db);
00037
00038
00039 query.exec("drop table occi_datatype_example_tb purge");
00040
00041 if (query.exec(create_sql) == false) {
00042 cout << "\n\tError: Running query failed bacause "
00043 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00044 }
00045 return true;
00046 }
00047
00048 bool test_prepare(QSqlDatabase& db)
00049 {
00050 QSqlQuery query(db);
00051
00052
00053 if ( query.prepare("select * from user_tables") == FALSE ||
00054 query.exec() == FALSE ||
00055 query.prepare("select * from user_tables") == FALSE ||
00056 query.exec() == FALSE)
00057 {
00058 cout << "Error: query failed because "
00059 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00060 return false;
00061 }
00062
00063 return true;
00064 }
00065
00066 bool test_blobs(QSqlDatabase& db)
00067 {
00068 const int MAX_SIZE = 23;
00069 QByteArray pBlob[MAX_SIZE];
00070 QSqlQuery query(db);
00071
00072 const char insert_sql[] =
00073 "insert into occi_datatype_example_tb \
00074 (col_number, col_blob) \
00075 values \
00076 (:1, :2)";
00077
00078 const char select_sql[] =
00079 "select col_blob from occi_datatype_example_tb \
00080 where col_number = :1";
00081
00082 srand( time(NULL) );
00083
00084 if (query.prepare(insert_sql) == FALSE) {
00085 cout << "Error: query failed because "
00086 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00087 return false;
00088 }
00089
00090 for (int p = 8; p < MAX_SIZE; p++) {
00091 for (int i = 0; i < (1<<p); i++) {
00092 pBlob[p].append(char(rand()));
00093 }
00094
00095 query.bindValue(":1", p);
00096 query.bindValue(":2", pBlob[p]);
00097
00098 if (query.exec() == FALSE) {
00099 cout << "Error: query failed because "
00100 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00101 return false;
00102 }
00103 }
00104
00105
00106
00107 for (int p = 8; p < MAX_SIZE; p++) {
00108
00109 if (query.prepare(select_sql) == FALSE) {
00110 cout << "Error: query failed because "
00111 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00112 return false;
00113 }
00114
00115 query.bindValue(":1", p);
00116
00117 if (query.exec() == FALSE) {
00118 cout << "Error: query failed because "
00119 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00120 return false;
00121 }
00122
00123 query.next();
00124 QByteArray ret = query.value(0).toByteArray();
00125
00126 for (int i = 0; i < ret.length(); i++) {
00127 if (ret[i] != pBlob[p][i]) {
00128 cout << "Error: test failed because values diffed on test " << p << endl;
00129 return false;
00130 }
00131 }
00132 }
00133
00134 return true;
00135 }
00136
00137 bool test_foward_only(QSqlDatabase& db)
00138 {
00139 QSqlQuery query(db);
00140 query.prepare("select table_name from user_tables");
00141 query.setForwardOnly(TRUE);
00142
00143 if (query.exec() == FALSE) {
00144 cout << "Error: query failed because "
00145 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00146 return false;
00147 }
00148
00149 while (query.next()) {
00150 QString tbl_name = query.value(0).toString();
00151 bool isNull = query.isNull(0);
00152 }
00153 return true;
00154 }
00155
00156 bool test_high_volume(QSqlDatabase& db)
00157 {
00158 QSqlQuery query(db);
00159
00160 const int MAX_SELECTS = 800;
00161
00162 for (int i = 0; i < MAX_SELECTS; i++) {
00163
00164 if (query.exec("select table_name from user_tables") == FALSE) {
00165 cout << "Error: query failed because "
00166 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00167 return false;
00168 }
00169
00170 if (query.exec("insert into occi_datatype_example_tb (col_number) values (1234)") == FALSE) {
00171 cout << "Error: query failed because "
00172 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00173 return false;
00174 }
00175 }
00176 return true;
00177 }
00178
00179 bool test_rowid(QSqlDatabase& db)
00180 {
00181 QSqlQuery query(db);
00182 if (query.exec("select rowid as \"rowid\" from occi_datatype_example_tb") == FALSE) {
00183 cout << "Error: query failed because "
00184 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00185 return false;
00186 }
00187 return true;
00188 }
00189
00190 bool test_varchar_boundry(QSqlDatabase& db)
00191 {
00192 QSqlQuery query(db);
00193 if (query.exec("select col_varchar from occi_datatype_example_tb") == FALSE) {
00194 cout << "Error: query failed because "
00195 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00196 return false;
00197 }
00198
00199 int varchar_len = query.record().field(0).length();
00200 QString test_str;
00201
00202 for (int i = 0; i < varchar_len; i++)
00203 test_str.append('a'+ char(rand()%26));
00204
00205
00206 if (query.prepare("insert into occi_datatype_example_tb (col_varchar) values (:1) ") == FALSE) {
00207 cout << "Error: query failed because "
00208 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00209 return false;
00210 }
00211
00212 query.bindValue(":1", test_str);
00213
00214 if (query.exec() == FALSE) {
00215 cout << "Error: query failed because "
00216 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00217 return false;
00218 }
00219
00220 if (query.prepare("select col_varchar from occi_datatype_example_tb where col_varchar = :1") == FALSE) {
00221 cout << "Error: query failed because "
00222 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00223 return false;
00224 }
00225
00226 query.bindValue(":1", test_str);
00227
00228 if (query.exec() == FALSE) {
00229 cout << "Error: query failed because "
00230 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00231 return false;
00232 }
00233
00234 while (query.next()) {
00235 return true;
00236 }
00237
00238 return false;
00239 }
00240
00241 bool test_out_binds(QSqlDatabase& db)
00242 {
00243 char proc_sql[] = "create or replace procedure occi_test_proc\n(test_val out number)\nas\nbegin\ntest_val := 50;\nend occi_test_proc;\n";
00244
00245 char call_sql[] = "BEGIN occi_test_proc(:0); END;";
00246
00247 QSqlQuery query(db);
00248
00249 if (query.exec(proc_sql) == FALSE) {
00250 cout << "Error: query failed because "
00251 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00252 return false;
00253 }
00254
00255 QVariant test_number(QVariant::Int);
00256
00257 query.prepare(call_sql);
00258 query.bindValue(0, 0);
00259
00260 if (query.exec() == FALSE) {
00261 cout << "Error: query failed because "
00262 << clean_error_msg(query.lastError().text()).toStdString() << endl;
00263 return false;
00264 }
00265
00266 if (query.boundValue(0).toInt() == 50) return true;
00267 return false;
00268 }
00269
00270
00271 bool test_named_placeholders(QSqlDatabase& db)
00272 {
00273 char proc_sql[] = "create or replace procedure occi_test_proc2\n(test_val out varchar)\nas\nbegin\ntest_val := 'TEST';\nend occi_test_proc2;\n";
00274
00275 char call_sql[] = "BEGIN occi_test_proc2(:str); END;";
00276
00277 QSqlQuery query(db);
00278
00279 if (query.exec(proc_sql) == FALSE) {
00280 cout << "Error: query failed because "
00281 << clean_error_msg(query.lastError().text()).toStdString() << "\n"
00282 << "Ran [" << proc_sql << "]\n";
00283 return false;
00284 }
00285
00286
00287 query.prepare(call_sql);
00288 query.bindValue(":str", QVariant(QVariant::String));
00289
00290 if (query.exec() == FALSE) {
00291 cout << "Error: query failed because "
00292 << clean_error_msg(query.lastError().text()).toStdString() << "\n"
00293 << "Ran [" << call_sql << "]\n";
00294 return false;
00295 }
00296
00297 if (query.boundValue(":str") == "TEST") {
00298 return true;
00299 }
00300 return false;
00301 }
00302 void test_wrapper( char* msg, bool(*func)(QSqlDatabase&), QSqlDatabase& db )
00303 {
00304 cout << "Testing " << msg << "...";
00305 if (func(db))
00306 cout << "passed\n";
00307 else
00308 cout << "Test failed!\n";
00309 }
00310
00311 int main(int argc, char *argv[])
00312 {
00313 QApplication app(argc, argv);
00314
00315 try {
00316 QSqlDatabase qDB = QSqlDatabase::addDatabase("QOpenOCCI");
00317
00318 qDB.setHostName(HOST);
00319 qDB.setDatabaseName(DB);
00320 qDB.setPort(PORT);
00321 qDB.setUserName(USER);
00322 qDB.setPassword(PASSWD);
00323
00324
00325 qDB.setConnectOptions("Prefetch_Memory=5242880;Prefetch_Rows=250");
00326
00327 test_wrapper("Connect", test_connect, qDB);
00328 test_wrapper("Create table", test_create_table, qDB);
00329 test_wrapper("Blob Support", test_blobs, qDB);
00330 test_wrapper("Rowid", test_rowid, qDB);
00331 test_wrapper("Varchar Bounds", test_varchar_boundry, qDB);
00332 test_wrapper("Out Binds", test_out_binds, qDB);
00333 test_wrapper("Named Placeholders", test_named_placeholders, qDB);
00334 test_wrapper("High Volume", test_high_volume, qDB);
00335 test_wrapper("Regression 1900996 'Double Connect bug'", test_connect, qDB);
00336 test_wrapper("Regression 1901126 'Double Prepare bug'", test_prepare, qDB);
00337 test_wrapper("Regression 1901414 'Forwared Only bug'", test_foward_only, qDB);
00338 }
00339 catch (exception& e) {
00340 cout << e.what() << endl;
00341 }
00342 return 0;
00343 }