dbqueries_source


SUBMITTED BY: davalillocm

DATE: July 29, 2021, 5:53 a.m.

FORMAT: Text only

SIZE: 99.6 kB

HITS: 551

  1. #include "dbqop.h"
  2. namespace databases{
  3. namespace odbc_database_operations{
  4. //STRUCTS DEFINITIONS
  5. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6. //DBConnection DEFINITIONS
  7. DBConnection::DBConnection():
  8. environment_handle(nullptr),database_connection_handle(nullptr),
  9. environment_handle_allocated(false),connection_handle_allocated(false),
  10. sql_command_prepared(false),asynch_support(false),is_connected(false),
  11. is_open(false),flag(0),connection_string(""),output_connection_string(""),
  12. server_string(""),user_string(""),password_string(""),last_message("")
  13. {
  14. }
  15. DBConnection::~DBConnection()
  16. {
  17. // Connection
  18. if(database_connection_handle!=SQL_NULL_HDBC)
  19. {
  20. SQLDisconnect(database_connection_handle);
  21. SQLFreeHandle(SQL_HANDLE_DBC,database_connection_handle);
  22. database_connection_handle=SQL_NULL_HDBC;
  23. }
  24. // Environment
  25. if(environment_handle!=SQL_NULL_HENV)
  26. {
  27. SQLFreeHandle(SQL_HANDLE_ENV,environment_handle);
  28. environment_handle=SQL_NULL_HENV;
  29. }
  30. }
  31. DBConnection& DBConnection::operator=(const DBConnection& rhs)
  32. {
  33. if(this != &rhs)// handle self assignment
  34. {
  35. this->environment_handle_allocated=rhs.environment_handle_allocated;
  36. this->connection_handle_allocated=rhs.connection_handle_allocated;
  37. this->sql_command_prepared=rhs.sql_command_prepared;
  38. this->asynch_support=rhs.asynch_support;
  39. this->is_connected=rhs.is_connected;
  40. this->is_open=rhs.is_open;
  41. this->connection_string=rhs.connection_string;
  42. this->output_connection_string=rhs.output_connection_string;
  43. this->server_string=rhs.server_string;
  44. this->user_string=rhs.user_string;
  45. this->password_string=rhs.password_string;
  46. this->last_message=rhs.last_message;
  47. this->flag=rhs.flag;
  48. this->environment_handle=rhs.environment_handle;//Environment handle
  49. this->database_connection_handle=rhs.database_connection_handle;//Database connection handle
  50. }
  51. return *this;
  52. }
  53. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. //DBColumn DEFINITIONS
  55. DBColumn::DBColumn():
  56. table_owner(0),column_type(0),catalog_name_length(0),schema_name_length(0),
  57. table_name_length(0),column_name_length(0),column_type_name_length(0),
  58. data_length_indicator(0),column_buffer_length(0),column_buffer(nullptr)
  59. {
  60. }
  61. DBColumn::~DBColumn()
  62. {
  63. delete[] column_buffer;
  64. }
  65. DBColumn::DBColumn(const short& new_column_type,const long& buffer_length):
  66. table_owner(0),column_type(new_column_type),catalog_name_length(0),
  67. schema_name_length(0),table_name_length(0),column_name_length(0),
  68. column_type_name_length(0),data_length_indicator(0),
  69. column_buffer_length(buffer_length),column_buffer(nullptr)
  70. {
  71. column_buffer=new SQLCHAR[buffer_length];
  72. }
  73. DBColumn::DBColumn(const DBColumn& other):
  74. table_owner(0),column_type(0),catalog_name_length(0),schema_name_length(0),
  75. table_name_length(0),column_name_length(0),column_type_name_length(0),
  76. data_length_indicator(0),column_buffer_length(0),column_buffer(nullptr)
  77. {
  78. table_owner=other.table_owner;
  79. column_type=other.column_type;
  80. catalog_name_length=other.catalog_name_length;
  81. schema_name_length=other.schema_name_length;
  82. table_name_length=other.table_name_length;
  83. column_name_length=other.column_name_length;
  84. column_type_name_length=other.column_type_name_length;
  85. data_length_indicator=other.data_length_indicator;
  86. column_buffer_length=other.column_buffer_length;//Max byte length of the column
  87. memcpy(catalog_name,other.catalog_name,SQL_MAX_CATALOG_NAME_LEN);
  88. memcpy(schema_name,other.schema_name,SQL_MAX_SCHEMA_NAME_LEN);
  89. memcpy(table_name,other.table_name,SQL_MAX_TABLE_NAME_LEN);
  90. memcpy(column_name,other.column_name,SQL_MAX_COLUMN_NAME_LEN);
  91. memcpy(column_type_name,other.column_type_name,MAX_COL_TYPE_NAME_LENGTH);
  92. column_buffer=new SQLCHAR[other.column_buffer_length];
  93. memcpy(column_buffer,other.column_buffer,other.column_buffer_length);
  94. }
  95. DBColumn& DBColumn::operator=(const DBColumn& rhs)
  96. {
  97. if(this != &rhs)
  98. {
  99. this->table_owner=rhs.table_owner;
  100. this->column_type=rhs.column_type;
  101. this->catalog_name_length=rhs.catalog_name_length;
  102. this->schema_name_length=rhs.schema_name_length;
  103. this->table_name_length=rhs.table_name_length;
  104. this->column_name_length=rhs.column_name_length;
  105. this->column_type_name_length=rhs.column_type_name_length;
  106. this->data_length_indicator=rhs.data_length_indicator;
  107. this->column_buffer_length=rhs.column_buffer_length;//Max byte length of the column
  108. memcpy(this->catalog_name,rhs.catalog_name,SQL_MAX_CATALOG_NAME_LEN);
  109. memcpy(this->schema_name,rhs.schema_name,SQL_MAX_SCHEMA_NAME_LEN);
  110. memcpy(this->table_name,rhs.table_name,SQL_MAX_TABLE_NAME_LEN);
  111. memcpy(this->column_name,rhs.column_name,SQL_MAX_COLUMN_NAME_LEN);
  112. memcpy(this->column_type_name,rhs.column_type_name,MAX_COL_TYPE_NAME_LENGTH);
  113. this->column_buffer=new SQLCHAR[rhs.column_buffer_length];
  114. memcpy(this->column_buffer,rhs.column_buffer,rhs.column_buffer_length);
  115. }
  116. return *this;
  117. }
  118. brw::Archive& DBColumn::operator&(brw::Archive& ar)
  119. {
  120. return ar;
  121. }
  122. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. //DBRow DEFINITIONS
  124. DBRow::DBRow():
  125. table_owner(0),row_index(0),row_data()
  126. {
  127. }
  128. DBRow::DBRow(const DBRow& other):
  129. table_owner(other.table_owner),row_index(other.row_index),row_data(other.row_data)
  130. {
  131. }
  132. DBRow::DBRow(const uintptr_t& row_table_owner,const UINT& new_row_index):
  133. table_owner(0),row_index(new_row_index),row_data()
  134. {
  135. DBTable table=*reinterpret_cast<DBTable*>(row_table_owner);
  136. table_owner=row_table_owner;
  137. //row_index=new_row_index;
  138. row_data=RowData(table.total_columns);
  139. for(short i=0;i<table.total_columns;i++)
  140. {
  141. CellData value;
  142. value.buffer_size=table.table_columns[i].column_buffer_length;
  143. value.buffer=new SQLCHAR[table.table_columns[i].column_buffer_length];
  144. row_data[i]=value;
  145. }
  146. }
  147. DBRow& DBRow::operator=(const DBRow& rhs)
  148. {
  149. if(this != &rhs)
  150. {
  151. this->table_owner=rhs.table_owner;
  152. this->row_index=rhs.row_index;
  153. this->row_data=rhs.row_data;
  154. }
  155. return *this;
  156. }
  157. DBRow::~DBRow()
  158. {
  159. }
  160. void* DBRow::getValue(const short& column_index) const
  161. {
  162. DBTable table=*reinterpret_cast<DBTable*>(table_owner);
  163. if(table.total_columns==0)
  164. {
  165. return nullptr;
  166. }
  167. CellData value=row_data[column_index];
  168. if(!value.buffer)
  169. {
  170. return nullptr;
  171. }
  172. long len=value.buffer_size;
  173. switch(table.table_columns[column_index].column_type)
  174. {
  175. case SQL_BIT:
  176. {
  177. break;
  178. }
  179. case SQL_CHAR:
  180. {
  181. char data1[len+1];
  182. for(long i=0;i<len;i++)
  183. {
  184. data1[i]=(char)value.buffer[i];
  185. }
  186. data1[len]='\0';
  187. static std::string value1;
  188. value1=std::string(data1);
  189. return &value1;
  190. }
  191. case SQL_VARCHAR:
  192. {
  193. char* data2=new char[len+1];
  194. for(long i=0;i<len;i++)
  195. {
  196. data2[i]=(char)value.buffer[i];
  197. }
  198. data2[len]='\0';
  199. static std::string value2;
  200. value2=std::string(data2);
  201. return &value2;
  202. }
  203. case SQL_LONGVARCHAR:
  204. {
  205. break;
  206. }
  207. case SQL_WCHAR:
  208. {
  209. break;
  210. }
  211. case SQL_WVARCHAR:
  212. {
  213. break;
  214. }
  215. case SQL_WLONGVARCHAR:
  216. {
  217. break;
  218. }
  219. case SQL_TINYINT:
  220. {
  221. PSQLCHAR data7=reinterpret_cast<PSQLCHAR>(value.buffer);
  222. static unsigned char value7;
  223. value7=(unsigned char)(*data7);
  224. return &value7;
  225. }
  226. case SQL_SMALLINT:
  227. {
  228. short* data8=reinterpret_cast<short*>(value.buffer);
  229. static short value8;
  230. value8=(short)(*data8);
  231. return &value8;
  232. }
  233. case SQL_INTEGER:
  234. {
  235. int* data9=reinterpret_cast<int*>(value.buffer);
  236. static int value9;
  237. value9=(int)(*data9);
  238. return &value9;
  239. break;
  240. }
  241. case SQL_BIGINT:
  242. {
  243. long* data10=reinterpret_cast<long*>(value.buffer);
  244. static long value10;
  245. value10=long(*data10);
  246. return &value10;
  247. }
  248. case SQL_DECIMAL:
  249. {
  250. break;
  251. }
  252. case SQL_NUMERIC:
  253. {
  254. break;
  255. }
  256. case SQL_REAL:
  257. {
  258. break;
  259. }
  260. case SQL_FLOAT:
  261. {
  262. float* data14=reinterpret_cast<float*>(value.buffer);
  263. static float value14;
  264. value14=float(*data14);
  265. return &value14;
  266. }
  267. case SQL_DOUBLE:
  268. {
  269. double* data15=reinterpret_cast<double*>(value.buffer);
  270. static double value15;
  271. value15=double(*data15);
  272. return &value15;
  273. }
  274. case SQL_DATE:
  275. {
  276. break;
  277. }
  278. case SQL_TIME:
  279. {
  280. break;
  281. }
  282. case SQL_TYPE_TIMESTAMP:
  283. {
  284. PTIMESTAMP buffer18=reinterpret_cast<PTIMESTAMP>(value.buffer);
  285. tm data18;
  286. data18.tm_year=buffer18->year;
  287. data18.tm_mon=buffer18->month;
  288. data18.tm_mday=buffer18->day;
  289. data18.tm_hour=buffer18->hour;
  290. data18.tm_min=buffer18->minute;
  291. data18.tm_sec=buffer18->second;
  292. tm timeinfo = {};
  293. timeinfo.tm_year = data18.tm_year - 1900;
  294. timeinfo.tm_mon = data18.tm_mon - 1;
  295. timeinfo.tm_mday = data18.tm_mday;
  296. mktime(&timeinfo);
  297. data18.tm_yday = timeinfo.tm_yday;
  298. data18.tm_wday=timeinfo.tm_wday;
  299. static tm value18;
  300. value18=data18;
  301. return &value18;
  302. }
  303. case SQL_BINARY:
  304. {
  305. break;
  306. }
  307. case SQL_VARBINARY:
  308. {
  309. break;
  310. }
  311. case SQL_LONGVARBINARY:
  312. {
  313. break;
  314. }
  315. default:
  316. {
  317. break;
  318. }
  319. }
  320. return nullptr;
  321. }
  322. void DBRow::getValue(const short& column_index,CellData& value) const
  323. {
  324. DBTable table=*reinterpret_cast<DBTable*>(table_owner);
  325. if(table.total_columns==0)
  326. {
  327. value.buffer=nullptr;
  328. value.buffer_size=0;
  329. }
  330. else
  331. {
  332. CellData value_data;
  333. CellData cell=row_data[column_index];
  334. value_data.buffer_size=cell.buffer_size;
  335. value_data.buffer=new SQLCHAR[value_data.buffer_size];
  336. memcpy(
  337. value_data.buffer,
  338. cell.buffer,
  339. cell.buffer_size
  340. );
  341. value=value_data;
  342. }
  343. }
  344. void DBRow::setValue(const short& column_index,void* value) const
  345. {
  346. }
  347. void DBRow::setValue(const short& column_index,const CellData& value)
  348. {
  349. row_data[column_index]=value;
  350. }
  351. DBRow DBRow::cloneRow() const
  352. {
  353. DBRow clone;
  354. clone.table_owner=table_owner;
  355. clone.row_index=row_index;
  356. clone.row_data=row_data;
  357. return clone;
  358. }
  359. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  360. //DBTable DEFINITIONS
  361. DBTable::DBTable():
  362. sql_statement(""),database_name(""),catalog_name(""),schema_name(""),table_name(""),
  363. total_columns(0),total_primary_key_columns(0),total_foreign_key_columns(0),
  364. primary_key_columns(nullptr),foreign_key_columns(nullptr),total_rows(0),
  365. table_columns(nullptr),statement_handle(nullptr),table_data(),
  366. is_primary_keys_set(false),is_foreign_keys_set(false)
  367. {
  368. }
  369. DBTable::~DBTable()
  370. {
  371. if(statement_handle!=SQL_NULL_HSTMT)
  372. {
  373. SQLFreeHandle(SQL_HANDLE_STMT,statement_handle);
  374. statement_handle=SQL_NULL_HSTMT;
  375. }
  376. delete[] table_columns;
  377. delete[] primary_key_columns;
  378. }
  379. DBTable::DBTable(const short& new_total_columns,DBColumn* new_table_columns):
  380. sql_statement(""),database_name(""),catalog_name(""),schema_name(""),table_name(""),
  381. total_columns(0),total_primary_key_columns(0),total_foreign_key_columns(0),
  382. primary_key_columns(nullptr),foreign_key_columns(nullptr),total_rows(0),
  383. table_columns(nullptr),statement_handle(nullptr),table_data(),
  384. is_primary_keys_set(false),is_foreign_keys_set(false)
  385. {
  386. total_columns=new_total_columns;
  387. table_columns=new DBColumn[new_total_columns];
  388. primary_key_columns=new short[new_total_columns];
  389. foreign_key_columns=new short[new_total_columns];
  390. for(short i=0;i<new_total_columns;i++)
  391. {
  392. table_columns[i]=DBColumn(new_table_columns[i]);
  393. }
  394. table_data=TableData();
  395. }
  396. DBTable::DBTable(const DBTable& other):
  397. sql_statement(other.sql_statement),database_name(other.database_name),
  398. catalog_name(other.catalog_name),schema_name(other.schema_name),
  399. table_name(other.table_name),total_columns(0),total_primary_key_columns(0),
  400. total_foreign_key_columns(0),primary_key_columns(nullptr),
  401. foreign_key_columns(nullptr),total_rows(other.total_rows),table_columns(nullptr),
  402. statement_handle(nullptr),table_data(),is_primary_keys_set(false),
  403. is_foreign_keys_set(false)
  404. {
  405. total_columns=other.total_columns;
  406. total_primary_key_columns=other.total_primary_key_columns;
  407. total_foreign_key_columns=other.total_foreign_key_columns;
  408. table_columns=new DBColumn[other.total_columns];
  409. primary_key_columns=new short[other.total_primary_key_columns];
  410. foreign_key_columns=new short[other.total_foreign_key_columns];
  411. for(short i=0;i<other.total_columns;i++)
  412. {
  413. table_columns[i]=other.table_columns[i];
  414. }
  415. for(short i=0;i<other.total_primary_key_columns;i++)
  416. {
  417. primary_key_columns[i]=other.primary_key_columns[i];
  418. }
  419. for(short i=0;i<other.total_foreign_key_columns;i++)
  420. {
  421. foreign_key_columns[i]=other.foreign_key_columns[i];
  422. }
  423. statement_handle=other.statement_handle;
  424. table_data=other.table_data;
  425. }
  426. DBTable& DBTable::operator=(const DBTable& rhs)
  427. {
  428. if(this != &rhs)
  429. {
  430. this->sql_statement=rhs.sql_statement;
  431. this->database_name=rhs.database_name;
  432. this->catalog_name=rhs.catalog_name;
  433. this->schema_name=rhs.schema_name;
  434. this->table_name=rhs.table_name;
  435. this->total_columns=rhs.total_columns;
  436. this->total_primary_key_columns=rhs.total_primary_key_columns;
  437. this->total_foreign_key_columns=rhs.total_foreign_key_columns;
  438. this->total_rows=rhs.total_rows;
  439. this->table_columns=new DBColumn[rhs.total_columns];
  440. this->primary_key_columns=new short[rhs.total_primary_key_columns];
  441. this->foreign_key_columns=new short[rhs.total_foreign_key_columns];
  442. for(short i=0;i<rhs.total_columns;i++)
  443. {
  444. this->table_columns[i]=rhs.table_columns[i];
  445. }
  446. for(short i=0;i<rhs.total_primary_key_columns;i++)
  447. {
  448. this->primary_key_columns[i]=rhs.primary_key_columns[i];
  449. }
  450. for(short i=0;i<rhs.total_foreign_key_columns;i++)
  451. {
  452. this->foreign_key_columns[i]=rhs.foreign_key_columns[i];
  453. }
  454. this->statement_handle=rhs.statement_handle;
  455. this->table_data=rhs.table_data;
  456. this->is_primary_keys_set=rhs.is_primary_keys_set;
  457. this->is_foreign_keys_set=rhs.is_foreign_keys_set;
  458. }
  459. return *this;
  460. }
  461. brw::Archive& DBTable::operator&(brw::Archive& ar)
  462. {
  463. switch(ar.getFileVersion())
  464. {
  465. case FILE_VERSION:
  466. {
  467. break;
  468. }
  469. default:
  470. {
  471. break;
  472. }
  473. }
  474. return ar;
  475. }
  476. DBRow DBTable::newRow() const
  477. {
  478. DBRow new_row=DBRow(reinterpret_cast<uintptr_t>(this),0);
  479. return new_row;
  480. }
  481. DBRow DBTable::getRow(const UINT& row_index) const
  482. {
  483. DBRow row=DBRow(reinterpret_cast<uintptr_t>(this),row_index);
  484. for(short i=0;i<total_columns;i++)
  485. {
  486. CellData value;
  487. getValue(row_index,i,value);
  488. row.setValue(i,value);
  489. }
  490. return row;
  491. }
  492. void DBTable::addRow(UINT& new_row_index)
  493. {
  494. RowData row_data=RowData(total_columns);
  495. for(short i=0;i<total_columns;i++)
  496. {
  497. CellData value;
  498. value.buffer_size=table_columns[i].column_buffer_length;
  499. value.buffer=new SQLCHAR[table_columns[i].column_buffer_length];
  500. row_data[i]=value;
  501. }
  502. table_data.push_back(row_data);
  503. new_row_index=total_rows;
  504. total_rows++;
  505. }
  506. void DBTable::addRow(const DBRow& new_row)
  507. {
  508. RowData row_data=RowData(total_columns);
  509. for(short i=0;i<total_columns;i++)
  510. {
  511. CellData value;
  512. new_row.getValue(i,value);
  513. row_data[i]=value;
  514. }
  515. table_data.push_back(row_data);
  516. total_rows++;
  517. }
  518. void* DBTable::getValue(const UINT& row_index,const short& column_index) const
  519. {
  520. if((total_columns==0) || (total_rows==0))
  521. {
  522. return nullptr;
  523. }
  524. CellData value=table_data[row_index][column_index];
  525. if(!value.buffer)
  526. {
  527. return nullptr;
  528. }
  529. long len=value.buffer_size;
  530. switch(table_columns[column_index].column_type)
  531. {
  532. case SQL_BIT:
  533. {
  534. break;
  535. }
  536. case SQL_CHAR:
  537. {
  538. char data1[len+1];
  539. for(long i=0;i<len;i++)
  540. {
  541. data1[i]=(char)value.buffer[i];
  542. }
  543. data1[len]='\0';
  544. static std::string value1;
  545. value1=std::string(data1);
  546. return &value1;
  547. }
  548. case SQL_VARCHAR:
  549. {
  550. char* data2=new char[len+1];
  551. for(long i=0;i<len;i++)
  552. {
  553. data2[i]=(char)value.buffer[i];
  554. }
  555. data2[len]='\0';
  556. static std::string value2;
  557. value2=std::string(data2);
  558. return &value2;
  559. }
  560. case SQL_LONGVARCHAR:
  561. {
  562. break;
  563. }
  564. case SQL_WCHAR:
  565. {
  566. break;
  567. }
  568. case SQL_WVARCHAR:
  569. {
  570. break;
  571. }
  572. case SQL_WLONGVARCHAR:
  573. {
  574. break;
  575. }
  576. case SQL_TINYINT:
  577. {
  578. PSQLCHAR data7=reinterpret_cast<PSQLCHAR>(value.buffer);
  579. static unsigned char value7;
  580. value7=(unsigned char)(*data7);
  581. return &value7;
  582. }
  583. case SQL_SMALLINT:
  584. {
  585. short* data8=reinterpret_cast<short*>(value.buffer);
  586. static short value8;
  587. value8=(short)(*data8);
  588. return &value8;
  589. }
  590. case SQL_INTEGER:
  591. {
  592. int* data9=reinterpret_cast<int*>(value.buffer);
  593. static int value9;
  594. value9=(int)(*data9);
  595. return &value9;
  596. break;
  597. }
  598. case SQL_BIGINT:
  599. {
  600. long* data10=reinterpret_cast<long*>(value.buffer);
  601. static long value10;
  602. value10=long(*data10);
  603. return &value10;
  604. }
  605. case SQL_DECIMAL:
  606. {
  607. break;
  608. }
  609. case SQL_NUMERIC:
  610. {
  611. break;
  612. }
  613. case SQL_REAL:
  614. {
  615. break;
  616. }
  617. case SQL_FLOAT:
  618. {
  619. float* data14=reinterpret_cast<float*>(value.buffer);
  620. static float value14;
  621. value14=float(*data14);
  622. return &value14;
  623. }
  624. case SQL_DOUBLE:
  625. {
  626. double* data15=reinterpret_cast<double*>(value.buffer);
  627. static double value15;
  628. value15=double(*data15);
  629. return &value15;
  630. }
  631. case SQL_DATE:
  632. {
  633. break;
  634. }
  635. case SQL_TIME:
  636. {
  637. break;
  638. }
  639. case SQL_TYPE_TIMESTAMP:
  640. {
  641. PTIMESTAMP buffer18=reinterpret_cast<PTIMESTAMP>(value.buffer);
  642. tm data18;
  643. data18.tm_year=buffer18->year;
  644. data18.tm_mon=buffer18->month;
  645. data18.tm_mday=buffer18->day;
  646. data18.tm_hour=buffer18->hour;
  647. data18.tm_min=buffer18->minute;
  648. data18.tm_sec=buffer18->second;
  649. tm timeinfo = {};
  650. timeinfo.tm_year = data18.tm_year - 1900;
  651. timeinfo.tm_mon = data18.tm_mon - 1;
  652. timeinfo.tm_mday = data18.tm_mday;
  653. mktime(&timeinfo);
  654. data18.tm_yday = timeinfo.tm_yday;
  655. data18.tm_wday=timeinfo.tm_wday;
  656. static tm value18;
  657. value18=data18;
  658. return &value18;
  659. }
  660. case SQL_BINARY:
  661. {
  662. break;
  663. }
  664. case SQL_VARBINARY:
  665. {
  666. break;
  667. }
  668. case SQL_LONGVARBINARY:
  669. {
  670. break;
  671. }
  672. default:
  673. {
  674. }
  675. }
  676. return nullptr;
  677. }
  678. void DBTable::getValue
  679. (
  680. const UINT& row_index,
  681. const short& column_index,
  682. CellData& value
  683. ) const
  684. {
  685. CellData cell=table_data[row_index][column_index];
  686. if(!cell.buffer)
  687. {
  688. value.buffer=nullptr;
  689. value.buffer_size=0;
  690. }
  691. else
  692. {
  693. value.buffer_size=cell.buffer_size;
  694. value.buffer=new SQLCHAR[cell.buffer_size];
  695. memcpy(value.buffer,cell.buffer,cell.buffer_size);
  696. }
  697. }
  698. void DBTable::setValue
  699. (
  700. const UINT& row_index,
  701. const short& column_index,
  702. void* value,
  703. const long& value_length
  704. )
  705. {
  706. CellData cell_value;
  707. if(!value)
  708. {
  709. cell_value.buffer=nullptr;
  710. cell_value.buffer_size=0;
  711. }
  712. else
  713. {
  714. long len;
  715. switch(table_columns[column_index].column_type)
  716. {
  717. case SQL_BIT:
  718. {
  719. break;
  720. }
  721. case SQL_CHAR:
  722. {
  723. char* buffer1=reinterpret_cast<char*>(value);
  724. len=sizeof(char);
  725. cell_value.buffer=new SQLCHAR[len];
  726. cell_value.buffer_size=len;
  727. memcpy(cell_value.buffer,buffer1,len);
  728. break;
  729. }
  730. case SQL_VARCHAR:
  731. {
  732. char* buffer2=reinterpret_cast<char*>(value);
  733. len=value_length;
  734. cell_value.buffer=new SQLCHAR[len];
  735. cell_value.buffer_size=len;
  736. memcpy(cell_value.buffer,buffer2,len);
  737. break;
  738. }
  739. case SQL_LONGVARCHAR:
  740. {
  741. break;
  742. }
  743. case SQL_WCHAR:
  744. {
  745. break;
  746. }
  747. case SQL_WVARCHAR:
  748. {
  749. break;
  750. }
  751. case SQL_WLONGVARCHAR:
  752. {
  753. break;
  754. }
  755. case SQL_TINYINT:
  756. {
  757. unsigned char* buffer7=reinterpret_cast<unsigned char*>(value);
  758. len=sizeof(unsigned char);
  759. cell_value.buffer=new SQLCHAR[len];
  760. cell_value.buffer_size=len;
  761. memcpy(cell_value.buffer,buffer7,len);
  762. break;
  763. }
  764. case SQL_SMALLINT:
  765. {
  766. short* buffer8=reinterpret_cast<short*>(value);
  767. len=sizeof(short);
  768. cell_value.buffer=new SQLCHAR[len];
  769. cell_value.buffer_size=len;
  770. memcpy(cell_value.buffer,buffer8,len);
  771. break;
  772. }
  773. case SQL_INTEGER:
  774. {
  775. int* buffer9=reinterpret_cast<int*>(value);
  776. len=sizeof(int);
  777. cell_value.buffer=new SQLCHAR[len];
  778. cell_value.buffer_size=len;
  779. memcpy(cell_value.buffer,buffer9,len);
  780. break;
  781. }
  782. case SQL_BIGINT:
  783. {
  784. long* buffer10=reinterpret_cast<long*>(value);
  785. len=sizeof(long);
  786. cell_value.buffer=new SQLCHAR[len];
  787. cell_value.buffer_size=len;
  788. memcpy(cell_value.buffer,buffer10,len);
  789. break;
  790. }
  791. case SQL_DECIMAL:
  792. {
  793. break;
  794. }
  795. case SQL_NUMERIC:
  796. {
  797. break;
  798. }
  799. case SQL_REAL:
  800. {
  801. break;
  802. }
  803. case SQL_FLOAT:
  804. {
  805. float* buffer14=reinterpret_cast<float*>(value);
  806. len=sizeof(float);
  807. cell_value.buffer=new SQLCHAR[len];
  808. cell_value.buffer_size=len;
  809. memcpy(cell_value.buffer,buffer14,len);
  810. break;
  811. }
  812. case SQL_DOUBLE:
  813. {
  814. double* buffer15=reinterpret_cast<double*>(value);
  815. len=sizeof(double);
  816. cell_value.buffer=new SQLCHAR[len];
  817. cell_value.buffer_size=len;
  818. memcpy(cell_value.buffer,buffer15,len);
  819. break;
  820. }
  821. case SQL_DATE:
  822. {
  823. break;
  824. }
  825. case SQL_TIME:
  826. {
  827. break;
  828. }
  829. case SQL_TYPE_TIMESTAMP:
  830. {
  831. PTIMESTAMP buffer18=reinterpret_cast<PTIMESTAMP>(value);
  832. len=sizeof(SQL_TIMESTAMP_STRUCT);
  833. cell_value.buffer=new SQLCHAR[len];
  834. cell_value.buffer_size=len;
  835. memcpy(cell_value.buffer,buffer18,len);
  836. break;
  837. }
  838. case SQL_BINARY:
  839. {
  840. break;
  841. }
  842. case SQL_VARBINARY:
  843. {
  844. break;
  845. }
  846. case SQL_LONGVARBINARY:
  847. {
  848. break;
  849. }
  850. default:
  851. {
  852. break;
  853. }
  854. }
  855. }
  856. table_data[row_index][column_index]=cell_value;
  857. }
  858. void DBTable::setValue
  859. (
  860. const UINT& row_index,
  861. const short& column_index,
  862. const CellData& value
  863. )
  864. {
  865. CellData cell;
  866. if(!value.buffer)
  867. {
  868. cell.buffer=nullptr;
  869. cell.buffer_size=0;
  870. }
  871. else
  872. {
  873. cell.buffer_size=value.buffer_size;
  874. cell.buffer=new SQLCHAR[value.buffer_size];
  875. memcpy(cell.buffer,value.buffer,value.buffer_size);
  876. }
  877. table_data[row_index][column_index]=cell;
  878. }
  879. bool DBTable::findRow
  880. (
  881. const short& key_column_index,
  882. const CellData& value,
  883. const UINT& starting_row_index,
  884. DBRow& row
  885. )
  886. {
  887. if(total_columns==0 || total_rows==0)
  888. {
  889. return false;
  890. }
  891. for(UINT i=starting_row_index;i<total_rows;i++)
  892. {
  893. if(memcmp
  894. (
  895. table_data[i][key_column_index].buffer,
  896. value.buffer,
  897. value.buffer_size
  898. )==0)
  899. {
  900. row=getRow(i);
  901. return true;
  902. }
  903. }
  904. return false;
  905. }
  906. bool DBTable::findRowPattern
  907. (
  908. const short& key_column_index,
  909. const std::string& value,
  910. const UINT& starting_row_index,
  911. DBRow& row
  912. ) const
  913. {
  914. if(total_columns==0 || total_rows==0)
  915. {
  916. return false;
  917. }
  918. const char* pattern;
  919. CellData cell;
  920. std::string::size_type pos=value.find_first_of('%');
  921. if(pos==std::string::npos)//When search is an exact search
  922. {
  923. pattern=new char[value.size()];
  924. memcpy((char*)pattern,value.c_str(),value.size());
  925. for(UINT i=starting_row_index;i<total_rows;i++)
  926. {
  927. cell=table_data[i][key_column_index];
  928. if(cell.buffer)
  929. {
  930. if(std::strcmp(reinterpret_cast<char*>(cell.buffer),pattern)==0)
  931. {
  932. row=getRow(i);
  933. return true;
  934. }
  935. }
  936. }
  937. }
  938. else if(pos==0 && value.find_last_of('%')==(value.size()-1))//When search pattern is of the form %pattern%
  939. {
  940. std::string::size_type len=value.size()-2;
  941. pattern=new char[len];
  942. memcpy((char*)pattern,value.substr(1,len).c_str(),len);
  943. for(UINT i=starting_row_index;i<total_rows;i++)
  944. {
  945. cell=table_data[i][key_column_index];
  946. if(cell.buffer)
  947. {
  948. if(std::strstr(reinterpret_cast<char*>(cell.buffer),pattern))
  949. {
  950. row=getRow(i);
  951. return true;
  952. }
  953. }
  954. }
  955. }
  956. else if(pos==0)//When search pattern is of the form %pattern
  957. {
  958. std::string::size_type len=value.size()-1;
  959. pattern=new char[len];
  960. memcpy((char*)pattern,value.substr(1,len).c_str(),len);
  961. char* match;
  962. for(UINT i=starting_row_index;i<total_rows;i++)
  963. {
  964. cell=table_data[i][key_column_index];
  965. if(cell.buffer)
  966. {
  967. if(cell.buffer_size>=(long)len)
  968. {
  969. match=std::strstr(reinterpret_cast<char*>(cell.buffer),pattern);
  970. if(match)
  971. {
  972. if((match-reinterpret_cast<char*>(cell.buffer))==
  973. (long)(cell.buffer_size-len))
  974. {
  975. row=getRow(i);
  976. return true;
  977. }
  978. }
  979. }
  980. }
  981. }
  982. }
  983. else//When search pattern is of the form pattern%
  984. {
  985. std::string::size_type len=value.size()-1;
  986. pattern=new char[len];
  987. memcpy((char*)pattern,value.substr(0,len).c_str(),len);
  988. char* match;
  989. for(UINT i=starting_row_index;i<total_rows;i++)
  990. {
  991. cell=table_data[i][key_column_index];
  992. if(cell.buffer)
  993. {
  994. if(cell.buffer_size>=(long)len)
  995. {
  996. match=std::strstr(reinterpret_cast<char*>(cell.buffer),pattern);
  997. if(match)
  998. {
  999. if((match-reinterpret_cast<char*>(cell.buffer))==0)
  1000. {
  1001. row=getRow(i);
  1002. return true;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. }
  1008. }
  1009. return false;
  1010. }
  1011. bool DBTable::getPrimaryKeys
  1012. (
  1013. short*& primary_keys,
  1014. short& total_primary_keys,
  1015. std::string& message
  1016. )
  1017. {
  1018. if(!is_primary_keys_set)
  1019. {
  1020. DBKeyColumn* table_primary_keys;
  1021. if(!DBGetPrimaryKeys
  1022. (
  1023. *this,
  1024. table_primary_keys,
  1025. total_primary_key_columns,
  1026. message
  1027. ))
  1028. {
  1029. return false;
  1030. }
  1031. primary_key_columns=new short[total_primary_key_columns];
  1032. for(short i=0;i<total_primary_key_columns;i++)
  1033. {
  1034. primary_key_columns[i]=table_primary_keys[i].key_ordinal;
  1035. }
  1036. }
  1037. total_primary_keys=total_primary_key_columns;
  1038. primary_keys=new short[total_primary_key_columns];
  1039. for(short i=0;i<total_primary_key_columns;i++)
  1040. {
  1041. primary_keys[i]=primary_key_columns[i];
  1042. }
  1043. is_primary_keys_set=true;
  1044. return true;
  1045. }
  1046. bool DBTable::getForeignKeys
  1047. (
  1048. short*& foreign_keys,
  1049. short& total_foreign_keys,
  1050. std::string& message
  1051. )
  1052. {
  1053. if(!is_foreign_keys_set)
  1054. {
  1055. DBKeyColumn* table_foreign_keys;
  1056. if(!DBGetPrimaryKeys
  1057. (
  1058. *this,
  1059. table_foreign_keys,
  1060. total_foreign_key_columns,
  1061. message
  1062. ))
  1063. {
  1064. return false;
  1065. }
  1066. foreign_key_columns=new short[total_foreign_key_columns];
  1067. for(short i=0;i<total_primary_key_columns;i++)
  1068. {
  1069. foreign_key_columns[i]=table_foreign_keys[i].key_ordinal;
  1070. }
  1071. }
  1072. total_foreign_keys=total_foreign_key_columns;
  1073. foreign_keys=new short[total_foreign_key_columns];
  1074. for(short i=0;i<total_foreign_key_columns;i++)
  1075. {
  1076. foreign_keys[i]=foreign_key_columns[i];
  1077. }
  1078. is_foreign_keys_set=true;
  1079. return true;
  1080. }
  1081. DBTable DBTable::cloneTable()
  1082. {
  1083. DBTable table;
  1084. table.sql_statement=sql_statement;
  1085. table.database_name=database_name;
  1086. table.catalog_name=catalog_name;
  1087. table.schema_name=schema_name;
  1088. table.table_name=table_name;
  1089. table.total_columns=total_columns;
  1090. table.total_primary_key_columns=total_primary_key_columns;
  1091. table.total_rows=total_rows;
  1092. table.table_columns=new DBColumn[total_columns];
  1093. table.primary_key_columns=new short[total_columns];
  1094. for(short i=0;i<total_columns;i++)
  1095. {
  1096. table.table_columns[i]=DBColumn(table_columns[i]);
  1097. table.primary_key_columns[i]=primary_key_columns[i];
  1098. }
  1099. table.table_columns=table_columns;
  1100. table.statement_handle=nullptr;
  1101. table.table_data=TableData(table_data);
  1102. return table;
  1103. }
  1104. DBTable DBTable::cloneSchema()
  1105. {
  1106. DBTable table;
  1107. table.sql_statement=sql_statement;
  1108. table.database_name=database_name;
  1109. table.catalog_name=catalog_name;
  1110. table.schema_name=schema_name;
  1111. table.table_name=table_name;
  1112. table.total_columns=total_columns;
  1113. table.total_primary_key_columns=total_primary_key_columns;
  1114. table.total_rows=total_rows;
  1115. table.table_columns=new DBColumn[total_columns];
  1116. table.primary_key_columns=new short[total_columns];
  1117. for(short i=0;i<total_columns;i++)
  1118. {
  1119. table.table_columns[i]=DBColumn(table_columns[i]);
  1120. table.primary_key_columns[i]=primary_key_columns[i];
  1121. }
  1122. table.statement_handle=nullptr;
  1123. table.table_data=TableData();
  1124. return table;
  1125. }
  1126. DBTable DBTable::getSubTable
  1127. (
  1128. const short columns_indices[],
  1129. const short& total_sub_columns
  1130. )
  1131. {
  1132. DBColumn* columns;
  1133. DBTable table;
  1134. UINT n;
  1135. CellData value;
  1136. columns=new DBColumn[total_sub_columns];
  1137. for(short i=0;i<total_sub_columns;i++)
  1138. {
  1139. columns[i]=table_columns[columns_indices[i]];
  1140. }
  1141. table=DBTable(total_sub_columns,columns);
  1142. for(UINT i=0;i<total_rows;i++)
  1143. {
  1144. table.addRow(n);
  1145. for(short j=0;j<total_sub_columns;j++)
  1146. {
  1147. getValue(i,columns_indices[j],value);
  1148. table.setValue(n,j,value);
  1149. }
  1150. }
  1151. return table;
  1152. }
  1153. void DBTable::splitPKFKDC
  1154. (
  1155. DBTable& primary_keys,
  1156. DBTable& foreign_keys,
  1157. DBTable& data_columns,
  1158. bool& has_primary_keys,
  1159. bool& has_foreign_keys
  1160. )
  1161. {
  1162. if(!is_primary_keys_set)
  1163. {
  1164. short* pk_indices;
  1165. short total_pk;
  1166. std::string message;
  1167. getPrimaryKeys(pk_indices,total_pk,message);
  1168. }
  1169. if(!is_foreign_keys_set)
  1170. {
  1171. short* fk_indices;
  1172. short total_fk;
  1173. std::string message;
  1174. getForeignKeys(fk_indices,total_fk,message);
  1175. }
  1176. UINT n;
  1177. CellData value;
  1178. short* column_iterator;
  1179. short* pk_end=primary_key_columns+total_primary_key_columns;
  1180. short* fk_end=foreign_key_columns+total_foreign_key_columns;
  1181. short pk_count=0;
  1182. short fk_count=0;
  1183. short dc_count=0;
  1184. short total_data_columns=total_columns-total_primary_key_columns
  1185. -total_foreign_key_columns;
  1186. DBColumn* pk_columns=new DBColumn[total_primary_key_columns];
  1187. DBColumn* fk_columns=new DBColumn[total_foreign_key_columns];
  1188. DBColumn* dc_columns=new DBColumn[total_data_columns];
  1189. TABLE_COLUMN_TYPES column_types[total_columns];
  1190. for(short i=0;i<total_columns;i++)
  1191. {
  1192. column_iterator=std::find
  1193. (
  1194. primary_key_columns,
  1195. pk_end,
  1196. i
  1197. );
  1198. if(column_iterator!=pk_end)
  1199. {
  1200. column_types[i]=TABLE_COLUMN_TYPES::PRIMARY_KEY;
  1201. pk_columns[pk_count]=table_columns[i];
  1202. pk_count++;
  1203. }
  1204. else
  1205. {
  1206. column_iterator=std::find
  1207. (
  1208. foreign_key_columns,
  1209. fk_end,
  1210. i
  1211. );
  1212. if(column_iterator!=fk_end)
  1213. {
  1214. column_types[i]=TABLE_COLUMN_TYPES::FOREIGN_KEY;
  1215. fk_columns[fk_count]=table_columns[i];
  1216. fk_count++;
  1217. }
  1218. else
  1219. {
  1220. column_types[i]=TABLE_COLUMN_TYPES::DATA_COLUMN;
  1221. dc_columns[dc_count]=table_columns[i];
  1222. dc_count++;
  1223. }
  1224. }
  1225. }
  1226. if(pk_count>0)
  1227. {
  1228. primary_keys=DBTable(pk_count,pk_columns);
  1229. has_primary_keys=true;
  1230. }
  1231. else
  1232. {
  1233. has_primary_keys=false;
  1234. }
  1235. if(fk_count>0)
  1236. {
  1237. foreign_keys=DBTable(fk_count,fk_columns);
  1238. has_foreign_keys=true;
  1239. }
  1240. else
  1241. {
  1242. has_foreign_keys=false;
  1243. }
  1244. if(dc_count>0)
  1245. {
  1246. data_columns=DBTable(dc_count,dc_columns);
  1247. }
  1248. pk_count=0;
  1249. fk_count=0;
  1250. dc_count=0;
  1251. for(short j=0;j<total_columns;j++)
  1252. {
  1253. switch(column_types[j])
  1254. {
  1255. case TABLE_COLUMN_TYPES::PRIMARY_KEY:
  1256. {
  1257. for(UINT i=0;i<total_rows;i++)
  1258. {
  1259. getValue(i,j,value);
  1260. primary_keys.addRow(n);
  1261. primary_keys.setValue(n,pk_count,value);
  1262. }
  1263. pk_count++;
  1264. break;
  1265. }
  1266. case TABLE_COLUMN_TYPES::FOREIGN_KEY:
  1267. {
  1268. for(UINT i=0;i<total_rows;i++)
  1269. {
  1270. getValue(i,j,value);
  1271. foreign_keys.addRow(n);
  1272. foreign_keys.setValue(n,fk_count,value);
  1273. }
  1274. fk_count++;
  1275. break;
  1276. }
  1277. case TABLE_COLUMN_TYPES::DATA_COLUMN:
  1278. {
  1279. for(UINT i=0;i<total_rows;i++)
  1280. {
  1281. getValue(i,j,value);
  1282. data_columns.addRow(n);
  1283. data_columns.setValue(n,dc_count,value);
  1284. }
  1285. dc_count++;
  1286. break;
  1287. }
  1288. }
  1289. }
  1290. }
  1291. SQLHSTMT& getStatementHandle(DBTable& table)
  1292. {
  1293. return table.statement_handle;
  1294. }
  1295. void setStatementHandle(DBTable& table,const SQLHSTMT handle)
  1296. {
  1297. table.statement_handle=handle;
  1298. }
  1299. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1300. //DBDataSet DEFINITIONS
  1301. DBDataSet::DBDataSet():
  1302. data_connection(),data_tables(),total_data_tables(0)
  1303. {
  1304. total_data_tables=0;
  1305. }
  1306. DBDataSet::DBDataSet
  1307. (
  1308. const std::string& sql_statement,
  1309. const std::string& driver,
  1310. const std::string& server,
  1311. const std::string& user,
  1312. const std::string& password
  1313. ):
  1314. data_connection(),data_tables(),total_data_tables(0)
  1315. {
  1316. DBConnect(data_connection,driver,server,user,password);
  1317. }
  1318. DBDataSet::~DBDataSet()
  1319. {}
  1320. std::vector<DBTable>::iterator DBDataSet::begin()
  1321. {
  1322. return data_tables.begin();
  1323. }
  1324. std::vector<DBTable>::iterator DBDataSet::end()
  1325. {
  1326. return data_tables.end();
  1327. }
  1328. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1329. //PROCEDURES DEFINITIONS
  1330. bool DBConnect
  1331. (
  1332. DBConnection& connection,
  1333. const std::string& driver,
  1334. const std::string& server,
  1335. const std::string& user,
  1336. const std::string& password
  1337. )
  1338. {
  1339. SQLHWND app_handle;
  1340. SQLRETURN rcode;
  1341. int nstr;
  1342. char* msg;
  1343. #ifdef __linux__
  1344. app_handle=nullptr;
  1345. #endif // __linux__
  1346. #ifdef __windows__
  1347. app_handle=GetDesktopWindow();
  1348. #endif // __windows__
  1349. //Allocate environment handle
  1350. rcode=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&connection.environment_handle);
  1351. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1352. {
  1353. connection.environment_handle_allocated=false;
  1354. connection.last_message="\n[DBConnect] Error allocating handle in \
  1355. SQLAllocHandle!";
  1356. return false;
  1357. }
  1358. connection.environment_handle_allocated=true;
  1359. //Set ODBC version environmet attribute
  1360. rcode=SQLSetEnvAttr
  1361. (
  1362. connection.environment_handle,
  1363. SQL_ATTR_ODBC_VERSION,
  1364. (SQLPOINTER)SQL_OV_ODBC3,
  1365. 0
  1366. );
  1367. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1368. {
  1369. connection.last_message="\n[DBConnect] Error setting environment attribute in \
  1370. SQLSetEnvAttr with SQL_ATTR_ODBC_VERSION attribute!";
  1371. return false;
  1372. }
  1373. //Allocate database connection handle
  1374. rcode=SQLAllocHandle
  1375. (
  1376. SQL_HANDLE_DBC,
  1377. connection.environment_handle,
  1378. &connection.database_connection_handle
  1379. );
  1380. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1381. {
  1382. connection.connection_handle_allocated=false;
  1383. connection.last_message="\n[DBConnect] Error allocating connection handle in \
  1384. SQLAllocHandle!";
  1385. return false;
  1386. }
  1387. PSQLCHAR input_connection_string;
  1388. SQLSMALLINT input_connection_string_length;//(SQLSMALLINT)(sizeof(inConStr)/sizeof(SQLCHAR));
  1389. SQLSMALLINT output_connection_string_buffer_length=1024;//Applications should allocate at least 1,024 characters for this buffer
  1390. SQLCHAR output_connection_string[output_connection_string_buffer_length];
  1391. SQLSMALLINT output_connection_string_length;
  1392. //===========================================================================================================================================================================
  1393. //VERY SENSITIVE PART OF THE APPLICATION
  1394. //AN EXAMPLE OF CONNECTION STRING THAT WORKS IS "DRIVER={Oracle73 Ver 2.5};UID=DAVALILLOCM;ASY=ON;DBQ=OCCP05;PWD=DAVALILLOCM&PDV;SAVEFILE=CONSTR.dsn;Trusted_Connection=YES;"
  1395. //AN EXAMPLE OF FILEDSN THAT WORKS IS "FILEDSN=d:\\Documents and Settings\\davalillocm\\Escritorio\\CONNECTION.dsn;";
  1396. nstr=0;
  1397. connection.connection_string="DRIVER={DRIVERPAR};UID=UIDPAR;ASY=ON;DBQ=SERVERPAR;\
  1398. PWD=PWDPAR;SAVEFILE=CONSTR.dsn;Trusted_Connection=YES;";
  1399. //Replace driver parameter
  1400. connection.connection_string=
  1401. connection.connection_string.replace
  1402. (
  1403. connection.connection_string.find("DRIVERPAR",nstr),
  1404. 9,
  1405. driver
  1406. );
  1407. nstr+=driver.length();
  1408. //Replace user id parameter
  1409. connection.connection_string=
  1410. connection.connection_string.replace
  1411. (
  1412. connection.connection_string.find("UIDPAR",nstr),
  1413. 6,
  1414. user
  1415. );
  1416. nstr+=user.length();
  1417. //Replace server parameter
  1418. connection.connection_string=
  1419. connection.connection_string.replace
  1420. (
  1421. connection.connection_string.find("SERVERPAR",nstr),
  1422. 9,
  1423. server
  1424. );
  1425. nstr+=server.length();
  1426. //Replace password parameter
  1427. connection.connection_string=
  1428. connection.connection_string.replace
  1429. (
  1430. connection.connection_string.find("PWDPAR",nstr),
  1431. 6,
  1432. password
  1433. );
  1434. nstr+=password.length();
  1435. //===========================================================================================================================================================================
  1436. input_connection_string=(PSQLCHAR)connection.connection_string.c_str();
  1437. input_connection_string_length=(SQLSMALLINT)connection.connection_string.length();
  1438. //(SQLSMALLINT)(sizeof(inConStr)/sizeof(SQLCHAR));
  1439. rcode=SQLDriverConnect
  1440. (
  1441. connection.database_connection_handle,
  1442. app_handle,
  1443. input_connection_string,
  1444. input_connection_string_length,
  1445. output_connection_string,
  1446. output_connection_string_buffer_length,
  1447. &output_connection_string_length,
  1448. SQL_DRIVER_NOPROMPT
  1449. );//SQL_DRIVER_NOPROMPT
  1450. if(rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO)
  1451. {
  1452. msg=new char[output_connection_string_length+1];
  1453. memcpy
  1454. (
  1455. msg,
  1456. (char*)output_connection_string,
  1457. output_connection_string_buffer_length
  1458. );
  1459. connection.last_message="\n[DBConnect] ";
  1460. connection.last_message+=msg;
  1461. connection.last_message+=DBGetErrorMsg
  1462. (
  1463. connection.database_connection_handle,
  1464. SQL_HANDLE_DBC
  1465. );
  1466. connection.flag=(int)input_connection_string_length;//(int)rcode;
  1467. delete[] msg;
  1468. return false;
  1469. }
  1470. msg=new char[output_connection_string_length+1];
  1471. memcpy(msg,(char*)output_connection_string,output_connection_string_length);
  1472. connection.last_message=std::string(msg);
  1473. connection.is_connected=true;
  1474. connection.is_open=true;
  1475. connection.connection_string="";
  1476. connection.server_string=server;
  1477. connection.user_string=user;
  1478. connection.password_string=password;
  1479. connection.flag=0;
  1480. return true;
  1481. }
  1482. bool DBDisconnect(DBConnection& connection)
  1483. {
  1484. if(SQLDisconnect(connection.database_connection_handle)==SQL_SUCCESS)
  1485. {
  1486. return true;
  1487. }
  1488. return false;
  1489. }
  1490. VECSTR DBGetDrivers(DBConnection& connection)
  1491. {
  1492. SQLRETURN rcode;
  1493. SQLCHAR driverName[SQL_MAX_DSN_LENGTH];
  1494. SQLSMALLINT driverNameLength;
  1495. SQLCHAR driverAttr[1024];
  1496. SQLSMALLINT driverAttrLength;
  1497. bool odbcsucceed;
  1498. int n;
  1499. int m;
  1500. VECSTR drivers=VECSTR();
  1501. odbcsucceed=true;
  1502. while(odbcsucceed)
  1503. {
  1504. rcode=SQLDrivers
  1505. (
  1506. connection.environment_handle,
  1507. SQL_FETCH_NEXT,
  1508. driverName,
  1509. SQL_MAX_DSN_LENGTH,
  1510. &driverNameLength,
  1511. driverAttr,
  1512. 1024,
  1513. &driverAttrLength
  1514. );
  1515. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1516. {
  1517. odbcsucceed=false;
  1518. }
  1519. else
  1520. {
  1521. n=(int)driverNameLength+1;
  1522. m=(int)driverAttrLength+1;
  1523. char DN[n];
  1524. char DNAttrs[m];
  1525. memcpy(DN,(char*)driverName,n);
  1526. memcpy(DNAttrs,(char*)driverAttr,m);
  1527. drivers.push_back(std::string(DN));
  1528. drivers.push_back(std::string(DNAttrs));
  1529. }
  1530. }
  1531. return drivers;
  1532. }
  1533. VECSTR DBGetDataSources(DBConnection& connection)
  1534. {
  1535. SQLRETURN rcode;
  1536. SQLSMALLINT bufferLengthSN=SQL_MAX_DSN_LENGTH;
  1537. SQLCHAR sourceName[bufferLengthSN];
  1538. SQLSMALLINT sourceNameLength;
  1539. SQLCHAR sourceNameDesc[1024];
  1540. SQLSMALLINT sourceNameDescLength;
  1541. bool odbcsucceed;
  1542. int n;
  1543. int m;
  1544. VECSTR dataSources=VECSTR();
  1545. rcode=SQLDataSources
  1546. (
  1547. connection.environment_handle,
  1548. SQL_FETCH_FIRST,
  1549. sourceName,
  1550. bufferLengthSN,
  1551. &sourceNameLength,
  1552. sourceNameDesc,
  1553. 1024,
  1554. &sourceNameDescLength
  1555. );
  1556. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1557. {
  1558. return dataSources;
  1559. }
  1560. n=(int)sourceNameLength+1;
  1561. m=(int)sourceNameDescLength+1;
  1562. char SN[n];
  1563. char SNDesc[m];
  1564. memcpy(SN,(char*)sourceName,n);
  1565. memcpy(SNDesc,(char*)sourceNameDesc,m);
  1566. dataSources.push_back(std::string(SN));
  1567. dataSources.push_back(std::string(SNDesc));
  1568. odbcsucceed=true;
  1569. while(odbcsucceed)
  1570. {
  1571. rcode=SQLDataSources
  1572. (
  1573. connection.environment_handle,
  1574. SQL_FETCH_NEXT,
  1575. sourceName,
  1576. bufferLengthSN,
  1577. &sourceNameLength,
  1578. sourceNameDesc,
  1579. 1024,
  1580. &sourceNameDescLength
  1581. );
  1582. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1583. {
  1584. odbcsucceed=false;
  1585. }
  1586. else
  1587. {
  1588. n=(int)sourceNameLength+1;
  1589. m=(int)sourceNameDescLength+1;
  1590. char SNI[n];
  1591. char SNIDesc[m];
  1592. memcpy(SNI,(char*)sourceName,n);
  1593. memcpy(SNIDesc,(char*)sourceNameDesc,m);
  1594. dataSources.push_back(std::string(SNI));
  1595. dataSources.push_back(std::string(SNIDesc));
  1596. }
  1597. }
  1598. return dataSources;
  1599. }
  1600. bool DBSelect(DBConnection& connection,const std::string& sqlcmd,DBTable& select_table)
  1601. {
  1602. //Prevents go any further if the connection is closed
  1603. if(!connection.is_open)
  1604. {
  1605. connection.last_message="\n[DBSelect] Connection not established or closed!";
  1606. return false;
  1607. }
  1608. SQLHSTMT statement_handle;
  1609. //Prepare the SQL statement
  1610. if(!DBPrepareSelect(connection,statement_handle,sqlcmd))
  1611. {
  1612. return false;
  1613. }
  1614. SQLRETURN rcode;
  1615. SQLSMALLINT stmt_columns=0;
  1616. DBColumn* sql_columns=nullptr;
  1617. SQLSMALLINT i;
  1618. SQLCHAR sql_command_text[MAX_COMMAND_LENGTH];
  1619. SQLINTEGER sql_command_length;
  1620. //==================================================================
  1621. //EXECUTE STATEMENT
  1622. rcode=SQLExecDirect
  1623. (
  1624. statement_handle,
  1625. (PSQLCHAR)sqlcmd.c_str(),
  1626. (SQLINTEGER)sqlcmd.length()
  1627. );
  1628. while(rcode==SQL_STILL_EXECUTING)
  1629. {
  1630. rcode=SQLExecDirect
  1631. (
  1632. statement_handle,
  1633. (PSQLCHAR)sqlcmd.c_str(),
  1634. (SQLINTEGER)sqlcmd.length()
  1635. );
  1636. }
  1637. if(rcode==SQL_ERROR && rcode!=SQL_SUCCESS_WITH_INFO)
  1638. {
  1639. connection.last_message="\n[DBSelect] SQLExecDirect error!";
  1640. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1641. return false;
  1642. }
  1643. else if(rcode==SQL_NEED_DATA)
  1644. {
  1645. connection.last_message="\n[DBSelect] SQLExecDirect execution requires \
  1646. data!";
  1647. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1648. return false;
  1649. }
  1650. //cout << "SQLExecDirect execution succeed!" << endl;
  1651. //==================================================================
  1652. //==================================================================
  1653. //SHOW EXECUTED SQL COMMAND
  1654. rcode=SQLNativeSql
  1655. (
  1656. connection.database_connection_handle,
  1657. (PSQLCHAR)sqlcmd.c_str(),
  1658. (SQLINTEGER)sqlcmd.length(),
  1659. sql_command_text,
  1660. MAX_COMMAND_LENGTH,
  1661. &sql_command_length
  1662. );
  1663. if(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  1664. {
  1665. std::string sended_command;
  1666. sended_command=std::string((size_t)sql_command_length,'\0');
  1667. std::copy
  1668. (
  1669. sql_command_text,
  1670. sql_command_text+sql_command_length,
  1671. sended_command.begin()
  1672. );
  1673. //cout << "\n \n Command executed \n \n " << endl;
  1674. //cout << sended_command << " \n \n " << endl;
  1675. }
  1676. else
  1677. {
  1678. connection.last_message="\n[DBSelect] SQLNativeSql error requesting sent \
  1679. statement!";
  1680. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1681. return false;
  1682. }
  1683. //==================================================================
  1684. //==================================================================
  1685. //GET NUMBER OF COLUMNS
  1686. //After be prepared the total number of columns must be retrieved
  1687. //but before the statement execution is performed
  1688. rcode=SQLNumResultCols(statement_handle,&stmt_columns);
  1689. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1690. {
  1691. connection.last_message="\n[DBSelect] SQLNumResultCols error getting the \
  1692. total number of columns!";
  1693. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1694. return false;
  1695. }
  1696. //==================================================================
  1697. //==================================================================
  1698. //CREATE COLUMNS AND BIND THEM
  1699. if(!DBGetColumnsAndBind(connection,statement_handle,stmt_columns,sql_columns))
  1700. {
  1701. return false;
  1702. }
  1703. select_table=DBTable(stmt_columns,sql_columns);
  1704. //==================================================================
  1705. //==================================================================
  1706. //FETCH VALUES
  1707. select_table.total_rows=0;
  1708. UINT row_index;
  1709. //Call SQLFetch function
  1710. rcode=SQL_SUCCESS;
  1711. while(rcode==SQL_SUCCESS)
  1712. {
  1713. DBSELECT_FETCH:
  1714. rcode=SQLFetch(statement_handle);
  1715. if(rcode==SQL_STILL_EXECUTING)
  1716. {
  1717. goto DBSELECT_FETCH;
  1718. }
  1719. if(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  1720. {
  1721. select_table.addRow(row_index);//Add an empty row
  1722. for(i=0;i<stmt_columns;i++)
  1723. {
  1724. CellData value;
  1725. if(sql_columns[i].data_length_indicator==SQL_NULL_DATA)
  1726. {
  1727. value.buffer=nullptr;
  1728. value.buffer_size=0;
  1729. //cout << "row field is NULL " << endl;
  1730. }
  1731. else
  1732. {
  1733. value.buffer=new SQLCHAR[sql_columns[i].data_length_indicator];
  1734. value.buffer_size=sql_columns[i].data_length_indicator;
  1735. memcpy
  1736. (
  1737. value.buffer,
  1738. sql_columns[i].column_buffer,
  1739. sql_columns[i].data_length_indicator
  1740. );
  1741. }
  1742. select_table.setValue(row_index,i,value);
  1743. }
  1744. if(rcode==SQL_SUCCESS_WITH_INFO)
  1745. {
  1746. //Show state
  1747. connection.last_message+="\n Row state ";
  1748. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1749. //cout << connection.last_message << endl;
  1750. }
  1751. }
  1752. }
  1753. switch(rcode)
  1754. {
  1755. case SQL_SUCCESS_WITH_INFO:
  1756. {
  1757. //Show state
  1758. connection.last_message+="\n";
  1759. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1760. //cout << connection.last_message << endl;
  1761. break;
  1762. }
  1763. case SQL_NO_DATA:
  1764. {
  1765. //Show state
  1766. connection.last_message+="\n[DBSelect] All rows fetched!";
  1767. //cout << connection.last_message << endl;
  1768. break;
  1769. }
  1770. case SQL_ERROR:
  1771. {
  1772. //Show error
  1773. connection.last_message+="\n[DBSelect] Error in SQLFetch ";
  1774. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1775. //cout << "Error setting cursor's position!" << endl;
  1776. return false;
  1777. }
  1778. case SQL_INVALID_HANDLE:
  1779. {
  1780. connection.last_message+="\n[DBSelect] Invalid statement handle!";
  1781. //cout << "Invalid statement handle!" << endl;
  1782. return false;
  1783. }
  1784. default:
  1785. {
  1786. break;
  1787. }
  1788. }
  1789. //==================================================================
  1790. //cout << "Total rows " << select_table.total_rows << endl;
  1791. setStatementHandle(select_table,statement_handle);
  1792. //==================================================================
  1793. //TO SET TABLE NAME, CATALOG NAME AND SCHEMA NAME
  1794. select_table.catalog_name=std::string
  1795. (
  1796. (char*)select_table.table_columns[0].catalog_name
  1797. );
  1798. select_table.schema_name=std::string
  1799. (
  1800. (char*)select_table.table_columns[0].schema_name
  1801. );
  1802. select_table.table_name=std::string
  1803. (
  1804. (char*)select_table.table_columns[0].table_name
  1805. );
  1806. //==================================================================
  1807. //Close the cursor
  1808. rcode=SQLCloseCursor(statement_handle);
  1809. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1810. {
  1811. connection.last_message="\n[DBSelect] SQLCloseCursor error closing cursor!";
  1812. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1813. return false;
  1814. }
  1815. rcode=SQLFreeStmt(statement_handle,SQL_RESET_PARAMS);
  1816. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1817. {
  1818. connection.last_message="\n[DBSelect] SQLFreeStmt error resetting parameters!";
  1819. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1820. return false;
  1821. }
  1822. return true;
  1823. }
  1824. bool DBInsert
  1825. (
  1826. DBConnection& connection,
  1827. const std::string& sqlcmd,
  1828. const DBTable& rows_to_insert,
  1829. DBTable& rows_rejected
  1830. )
  1831. {
  1832. //Prevents go any further if the connection is closed
  1833. if(!connection.is_open)
  1834. {
  1835. connection.last_message="\n[DBInsert] Connection not established or closed!";
  1836. return false;
  1837. }
  1838. SQLRETURN rcode;
  1839. SQLHSTMT statement_handle;
  1840. DBColumn* sql_columns=new DBColumn[rows_to_insert.total_columns];
  1841. for(short i=0;i<rows_to_insert.total_columns;i++)
  1842. {
  1843. sql_columns[i]=rows_to_insert.table_columns[i];
  1844. }
  1845. //Prepare the SQL statement
  1846. if(!DBPrepareInsert(connection,statement_handle,sqlcmd))
  1847. {
  1848. return false;
  1849. }
  1850. if(!DBBindInsertParameters
  1851. (
  1852. connection,
  1853. statement_handle,
  1854. rows_to_insert.total_columns,
  1855. sql_columns
  1856. ))
  1857. {
  1858. return false;
  1859. }
  1860. //cout << "SQL parameters bounded!" << endl;
  1861. //Prepare SQl command
  1862. rcode=SQLPrepare
  1863. (
  1864. statement_handle,
  1865. (PSQLCHAR)sqlcmd.c_str(),
  1866. (SQLINTEGER)strlen(sqlcmd.c_str())
  1867. );
  1868. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1869. {
  1870. connection.sql_command_prepared=false;
  1871. connection.last_message="\n[DBInsert] Can't prepare SQL statement!";
  1872. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1873. return false;
  1874. }
  1875. connection.sql_command_prepared=true;
  1876. //cout << "SQL Insert prepared!" << endl;
  1877. rows_rejected=DBTable(rows_to_insert.total_columns,rows_to_insert.table_columns);
  1878. for(UINT i=0;i<rows_to_insert.total_rows;i++)
  1879. {
  1880. //Set data to bounded buffer
  1881. for(short j=0;j<rows_to_insert.total_columns;j++)
  1882. {
  1883. CellData value;
  1884. rows_to_insert.getValue(i,j,value);
  1885. if(!value.buffer)
  1886. {
  1887. sql_columns[j].column_buffer_length=0;
  1888. sql_columns[j].data_length_indicator=SQL_NULL_DATA;
  1889. }
  1890. else
  1891. {
  1892. memcpy(sql_columns[j].column_buffer,value.buffer,value.buffer_size);
  1893. sql_columns[j].data_length_indicator=value.buffer_size;
  1894. }
  1895. }
  1896. rcode=SQLExecute(statement_handle);
  1897. if(rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO)
  1898. {
  1899. DBRow rejected;
  1900. rejected=rows_to_insert.getRow(i);
  1901. rows_rejected.addRow(rejected);
  1902. //cout << "Row " << i << " rejected" << endl;
  1903. //cout << DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT) << endl;
  1904. }
  1905. }
  1906. rcode=SQLFreeStmt(statement_handle,SQL_RESET_PARAMS);
  1907. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1908. {
  1909. connection.last_message="\n[DBInsert] SQLFreeStmt error resetting parameters!";
  1910. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1911. return false;
  1912. }
  1913. return true;
  1914. }
  1915. bool DBUpdate
  1916. (
  1917. DBConnection& connection,
  1918. const std::string& sqlcmd,
  1919. const DBTable& rows_to_update,
  1920. const DBTable& primary_keys_values,
  1921. DBTable& rows_rejected
  1922. )
  1923. {
  1924. //Prevents go any further if the connection is closed
  1925. if(!connection.is_open)
  1926. {
  1927. connection.last_message="\n[DBUpdate] Connection not established or closed!";
  1928. return false;
  1929. }
  1930. SQLRETURN rcode;
  1931. SQLHSTMT statement_handle;
  1932. DBColumn* sql_columns=new DBColumn[rows_to_update.total_columns];
  1933. DBColumn* pk_columns=new DBColumn[primary_keys_values.total_columns];
  1934. CellData value;
  1935. for(short i=0;i<rows_to_update.total_columns;i++)
  1936. {
  1937. sql_columns[i]=rows_to_update.table_columns[i];
  1938. }
  1939. for(short i=0;i<primary_keys_values.total_columns;i++)
  1940. {
  1941. pk_columns[i]=primary_keys_values.table_columns[i];
  1942. }
  1943. //Prepare the SQL statement
  1944. if(!DBPrepareUpdate(connection,statement_handle,sqlcmd))
  1945. {
  1946. return false;
  1947. }
  1948. if(!DBBindUpdateParameters
  1949. (
  1950. connection,
  1951. statement_handle,
  1952. rows_to_update.total_columns,
  1953. primary_keys_values.total_columns,
  1954. sql_columns,
  1955. pk_columns
  1956. ))
  1957. {
  1958. return false;
  1959. }
  1960. //cout << "SQL parameters bounded!" << endl;
  1961. //Prepare SQl command
  1962. rcode=SQLPrepare
  1963. (
  1964. statement_handle,
  1965. (PSQLCHAR)sqlcmd.c_str(),
  1966. (SQLINTEGER)strlen(sqlcmd.c_str())
  1967. );
  1968. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  1969. {
  1970. connection.sql_command_prepared=false;
  1971. connection.last_message="\n[DBUpdate] Can't prepare SQL statement!";
  1972. connection.last_message+="";
  1973. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  1974. return false;
  1975. }
  1976. connection.sql_command_prepared=true;
  1977. //cout << "SQL Update prepared!" << endl;
  1978. rows_rejected=DBTable(rows_to_update.total_columns,rows_to_update.table_columns);
  1979. for(UINT i=0;i<rows_to_update.total_rows;i++)
  1980. {
  1981. //Set data to bounded buffer
  1982. for(short j=0;j<rows_to_update.total_columns;j++)
  1983. {
  1984. rows_to_update.getValue(i,j,value);
  1985. if(!value.buffer)
  1986. {
  1987. sql_columns[j].column_buffer_length=0;
  1988. sql_columns[j].data_length_indicator=SQL_NULL_DATA;
  1989. }
  1990. else
  1991. {
  1992. sql_columns[j].column_buffer_length=value.buffer_size;
  1993. sql_columns[j].data_length_indicator=value.buffer_size;
  1994. memcpy(sql_columns[j].column_buffer,value.buffer,value.buffer_size);
  1995. }
  1996. }
  1997. for(short j=0;j<primary_keys_values.total_columns;j++)
  1998. {
  1999. primary_keys_values.getValue(i,j,value);
  2000. pk_columns[j].column_buffer_length=value.buffer_size;
  2001. pk_columns[j].data_length_indicator=value.buffer_size;
  2002. memcpy(pk_columns[j].column_buffer,value.buffer,value.buffer_size);
  2003. }
  2004. rcode=SQLExecute(statement_handle);
  2005. if(rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO)
  2006. {
  2007. DBRow rejected;
  2008. rejected=rows_to_update.getRow(i);
  2009. rows_rejected.addRow(rejected);
  2010. //cout << "Row " << i << " rejected" << endl;
  2011. //cout << DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT) << endl;
  2012. }
  2013. }
  2014. return true;
  2015. }
  2016. bool DBDelete
  2017. (
  2018. DBConnection& connection,
  2019. const std::string& sqlcmd,
  2020. const DBTable& primary_keys_values,
  2021. DBTable& rows_rejected
  2022. )
  2023. {
  2024. //Prevents go any further if the connection is closed
  2025. if(!connection.is_open)
  2026. {
  2027. connection.last_message="\n[DBDelete] Connection not established or closed!";
  2028. return false;
  2029. }
  2030. SQLRETURN rcode;
  2031. SQLHSTMT statement_handle;
  2032. DBColumn* pk_columns=new DBColumn[primary_keys_values.total_columns];
  2033. CellData value;
  2034. for(short i=0;i<primary_keys_values.total_columns;i++)
  2035. {
  2036. pk_columns[i]=primary_keys_values.table_columns[i];
  2037. }
  2038. //Prepare the SQL statement
  2039. if(!DBPrepareDelete(connection,statement_handle,sqlcmd))
  2040. {
  2041. return false;
  2042. }
  2043. if(!DBBindDeleteParameters
  2044. (
  2045. connection,
  2046. statement_handle,
  2047. primary_keys_values.total_columns,
  2048. pk_columns
  2049. ))
  2050. {
  2051. return false;
  2052. }
  2053. //cout << "SQL parameters bounded!" << endl;
  2054. //Prepare SQl command
  2055. rcode=SQLPrepare
  2056. (
  2057. statement_handle,
  2058. (PSQLCHAR)sqlcmd.c_str(),
  2059. (SQLINTEGER)strlen(sqlcmd.c_str())
  2060. );
  2061. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  2062. {
  2063. connection.sql_command_prepared=false;
  2064. connection.last_message="\n[DBDelete] Can't prepare SQL statement!";
  2065. connection.last_message+="";
  2066. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2067. return false;
  2068. }
  2069. connection.sql_command_prepared=true;
  2070. //cout << "SQL Delete prepared!" << endl;
  2071. rows_rejected=DBTable
  2072. (
  2073. primary_keys_values.total_columns,
  2074. primary_keys_values.table_columns
  2075. );
  2076. for(UINT i=0;i<primary_keys_values.total_rows;i++)
  2077. {
  2078. for(short j=0;j<primary_keys_values.total_columns;j++)
  2079. {
  2080. primary_keys_values.getValue(i,j,value);
  2081. pk_columns[j].column_buffer_length=value.buffer_size;
  2082. pk_columns[j].data_length_indicator=value.buffer_size;
  2083. memcpy(pk_columns[j].column_buffer,value.buffer,value.buffer_size);
  2084. }
  2085. rcode=SQLExecute(statement_handle);
  2086. if(rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO)
  2087. {
  2088. DBRow rejected;
  2089. rejected=primary_keys_values.getRow(i);
  2090. rows_rejected.addRow(rejected);
  2091. //cout << "Row " << i << " rejected" << endl;
  2092. //cout << DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT) << endl;
  2093. }
  2094. }
  2095. return true;
  2096. }
  2097. bool DBGetPrimaryKeys
  2098. (
  2099. DBTable& table,
  2100. DBKeyColumn*& primary_keys,
  2101. short& total_primary_keys,
  2102. std::string& message
  2103. )
  2104. {
  2105. SQLRETURN rcode;
  2106. HSTMT handle=getStatementHandle(table);
  2107. PSQLCHAR table_catalog_name=(PSQLCHAR)table.catalog_name.c_str();
  2108. PSQLCHAR table_schema_name=(PSQLCHAR)table.schema_name.c_str();
  2109. PSQLCHAR table_name=(PSQLCHAR)table.table_name.c_str();
  2110. SQLSMALLINT table_catalog_name_length=(SQLSMALLINT)table.catalog_name.size();
  2111. SQLSMALLINT table_schema_name_length=(SQLSMALLINT)table.schema_name.size();
  2112. SQLSMALLINT table_name_length=(SQLSMALLINT)table.table_name.size();
  2113. SQLSMALLINT key_ordinal;
  2114. SQLSMALLINT k;
  2115. std::vector<DBKeyColumn> table_primary_keys;
  2116. SQLBindCol(handle,6,SQL_C_SSHORT,(SQLPOINTER)&key_ordinal,sizeof(SQLSMALLINT),NULL);
  2117. rcode=SQLPrimaryKeys
  2118. (
  2119. handle,
  2120. table_catalog_name,
  2121. table_catalog_name_length,
  2122. table_schema_name,
  2123. table_schema_name_length,
  2124. table_name,
  2125. table_name_length
  2126. );
  2127. while(rcode==SQL_STILL_EXECUTING)
  2128. {
  2129. rcode=SQLPrimaryKeys
  2130. (
  2131. handle,
  2132. table_catalog_name,
  2133. table_catalog_name_length,
  2134. table_schema_name,
  2135. table_schema_name_length,
  2136. table_name,
  2137. table_name_length
  2138. );
  2139. }
  2140. if(rcode==SQL_ERROR)
  2141. {
  2142. message="\n[DBGetPrimaryKeys] Error executing SQLPrimaryKeys!\n";
  2143. message+=DBGetErrorMsg(handle,SQL_HANDLE_STMT);
  2144. return false;
  2145. }
  2146. while(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  2147. {
  2148. rcode=SQLFetch(handle);
  2149. while(rcode==SQL_STILL_EXECUTING)
  2150. {
  2151. rcode=SQLFetch(handle);
  2152. }
  2153. if(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  2154. {
  2155. DBKeyColumn key;
  2156. memcpy
  2157. (
  2158. key.key_catalog_name,
  2159. table_catalog_name,
  2160. table_catalog_name_length
  2161. );
  2162. memcpy
  2163. (
  2164. key.key_schema_name,
  2165. table_schema_name,
  2166. table_schema_name_length
  2167. );
  2168. memcpy
  2169. (
  2170. key.key_table_name,
  2171. table_name,
  2172. table_name_length
  2173. );
  2174. k=key_ordinal;
  2175. memcpy
  2176. (
  2177. key.key_column_name,
  2178. table.table_columns[k].column_name,
  2179. table.table_columns[k].column_name_length
  2180. );
  2181. key.key_ordinal=key_ordinal;
  2182. key.key_catalog_name_length=table_catalog_name_length;
  2183. key.key_schema_name_length=table_schema_name_length;
  2184. key.key_table_name_length=table_name_length;
  2185. key.key_column_name_length=table.table_columns[k].column_name_length;
  2186. key.key_name_length=0;
  2187. table_primary_keys.push_back(key);
  2188. }
  2189. }
  2190. primary_keys=new DBKeyColumn[table_primary_keys.size()];
  2191. for(size_t i=0;i<table_primary_keys.size();i++)
  2192. {
  2193. primary_keys[i]=table_primary_keys[i];
  2194. }
  2195. total_primary_keys=(short)table_primary_keys.size();
  2196. rcode=SQLFreeStmt(handle,SQL_RESET_PARAMS);
  2197. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  2198. {
  2199. message="\n[DBGetPrimaryKeys] SQLFreeStmt error resetting parameters!";
  2200. message+=DBGetErrorMsg(handle,SQL_HANDLE_STMT);
  2201. return false;
  2202. }
  2203. return true;
  2204. }
  2205. bool DBGetForeignKeys
  2206. (
  2207. DBTable& table,
  2208. DBKeyColumn*& foreign_keys,
  2209. short& total_foreign_keys,
  2210. std::string& message
  2211. )
  2212. {
  2213. SQLRETURN rcode;
  2214. HSTMT handle=getStatementHandle(table);
  2215. PSQLCHAR table_catalog_name=(PSQLCHAR)table.catalog_name.c_str();
  2216. PSQLCHAR table_schema_name=(PSQLCHAR)table.schema_name.c_str();
  2217. PSQLCHAR table_name=(PSQLCHAR)table.table_name.c_str();
  2218. SQLSMALLINT table_catalog_name_length=(SQLSMALLINT)table.catalog_name.size();
  2219. SQLSMALLINT table_schema_name_length=(SQLSMALLINT)table.schema_name.size();
  2220. SQLSMALLINT table_name_length=(SQLSMALLINT)table.table_name.size();
  2221. SQLSMALLINT key_ordinal;
  2222. SQLSMALLINT k;
  2223. std::vector<DBKeyColumn> table_foreign_keys;
  2224. SQLBindCol(handle,6,SQL_C_SSHORT,(SQLPOINTER)&key_ordinal,sizeof(SQLSMALLINT),NULL);
  2225. rcode=SQLForeignKeys
  2226. (
  2227. handle,
  2228. NULL,
  2229. 0,
  2230. NULL,
  2231. 0,
  2232. NULL,
  2233. 0,
  2234. table_catalog_name,
  2235. table_catalog_name_length,
  2236. table_schema_name,
  2237. table_schema_name_length,
  2238. table_name,
  2239. table_name_length
  2240. );
  2241. while(rcode==SQL_STILL_EXECUTING)
  2242. {
  2243. rcode=SQLForeignKeys
  2244. (
  2245. handle,
  2246. NULL,
  2247. 0,
  2248. NULL,
  2249. 0,
  2250. NULL,
  2251. 0,
  2252. table_catalog_name,
  2253. table_catalog_name_length,
  2254. table_schema_name,
  2255. table_schema_name_length,
  2256. table_name,
  2257. table_name_length
  2258. );
  2259. }
  2260. if(rcode==SQL_ERROR)
  2261. {
  2262. message="\n[DBGetPrimaryKeys] Error executing SQLPrimaryKeys!\n";
  2263. message+=DBGetErrorMsg(handle,SQL_HANDLE_STMT);
  2264. return false;
  2265. }
  2266. while(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  2267. {
  2268. rcode=SQLFetch(handle);
  2269. while(rcode==SQL_STILL_EXECUTING)
  2270. {
  2271. rcode=SQLFetch(handle);
  2272. }
  2273. if(rcode==SQL_SUCCESS || rcode==SQL_SUCCESS_WITH_INFO)
  2274. {
  2275. DBKeyColumn key;
  2276. memcpy
  2277. (
  2278. key.key_catalog_name,
  2279. table_catalog_name,
  2280. table_catalog_name_length
  2281. );
  2282. memcpy
  2283. (
  2284. key.key_schema_name,
  2285. table_schema_name,
  2286. table_schema_name_length
  2287. );
  2288. memcpy
  2289. (
  2290. key.key_table_name,
  2291. table_name,
  2292. table_name_length
  2293. );
  2294. k=key_ordinal;
  2295. memcpy
  2296. (
  2297. key.key_column_name,
  2298. table.table_columns[k].column_name,
  2299. table.table_columns[k].column_name_length
  2300. );
  2301. key.key_ordinal=key_ordinal;
  2302. key.key_catalog_name_length=table_catalog_name_length;
  2303. key.key_schema_name_length=table_schema_name_length;
  2304. key.key_table_name_length=table_name_length;
  2305. key.key_column_name_length=table.table_columns[k].column_name_length;
  2306. key.key_name_length=0;
  2307. table_foreign_keys.push_back(key);
  2308. }
  2309. }
  2310. foreign_keys=new DBKeyColumn[table_foreign_keys.size()];
  2311. for(size_t i=0;i<table_foreign_keys.size();i++)
  2312. {
  2313. foreign_keys[i]=table_foreign_keys[i];
  2314. }
  2315. total_foreign_keys=(short)table_foreign_keys.size();
  2316. rcode=SQLFreeStmt(handle,SQL_RESET_PARAMS);
  2317. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  2318. {
  2319. message="\n[DBGetForeignKeys] SQLFreeStmt error resetting parameters!";
  2320. message+=DBGetErrorMsg(handle,SQL_HANDLE_STMT);
  2321. return false;
  2322. }
  2323. return true;
  2324. }
  2325. short DBGetNumberOfColumns(SQLHSTMT& statement_handle)
  2326. {
  2327. SQLRETURN rcode;
  2328. SQLSMALLINT total_columns;
  2329. rcode=SQLNumResultCols(statement_handle,&total_columns);
  2330. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  2331. {
  2332. return -1;
  2333. }
  2334. return (short)total_columns;
  2335. }
  2336. UINT DBGetNumberOfRows(SQLHSTMT& statement_handle)
  2337. {
  2338. SQLRETURN rcode;
  2339. SQLLEN total_rows;
  2340. rcode=SQLRowCount(statement_handle,&total_rows);
  2341. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  2342. {
  2343. return -1;
  2344. }
  2345. return (UINT)total_rows;
  2346. }
  2347. std::string DBGetErrorMsg(SQLHANDLE handle,SQLSMALLINT handle_type)
  2348. {
  2349. std::string msg="";
  2350. std::string error_message;
  2351. std::string error_message_code;
  2352. SQLSMALLINT total_messages=1;
  2353. SQLRETURN rcode;
  2354. SQLCHAR sql_state[6];
  2355. SQLCHAR sql_error_message[SQL_MAX_MESSAGE_LENGTH];
  2356. SQLINTEGER sql_native_error;
  2357. SQLSMALLINT sql_error_message_length;
  2358. SQLSMALLINT handle_type_enum;
  2359. switch(handle_type)
  2360. {
  2361. case SQL_HANDLE_DBC:
  2362. {
  2363. handle_type_enum=SQL_HANDLE_DBC;
  2364. break;
  2365. }
  2366. case SQL_HANDLE_DESC:
  2367. {
  2368. handle_type_enum=SQL_HANDLE_DESC;
  2369. break;
  2370. }
  2371. case SQL_HANDLE_ENV:
  2372. {
  2373. handle_type_enum=SQL_HANDLE_ENV;
  2374. break;
  2375. }
  2376. case SQL_HANDLE_STMT:
  2377. {
  2378. handle_type_enum=SQL_HANDLE_STMT;
  2379. break;
  2380. }
  2381. default:
  2382. break;
  2383. }
  2384. while(true)
  2385. {
  2386. rcode = SQLGetDiagRec
  2387. (
  2388. handle_type_enum,
  2389. handle,
  2390. total_messages,
  2391. sql_state,
  2392. &sql_native_error,
  2393. sql_error_message,
  2394. SQL_MAX_MESSAGE_LENGTH,
  2395. &sql_error_message_length
  2396. );
  2397. if(rcode==SQL_SUCCESS)
  2398. {
  2399. error_message=std::string((size_t)sql_error_message_length,'\0');
  2400. std::copy
  2401. (
  2402. sql_error_message,
  2403. sql_error_message+sql_error_message_length,
  2404. error_message.begin()
  2405. );
  2406. error_message_code="\n["+std::string((char*)sql_state)+"]";
  2407. msg+=error_message_code+error_message+"";
  2408. total_messages++;
  2409. if(total_messages>MAX_ERROR_MESSAGES)
  2410. {
  2411. break;
  2412. }
  2413. }
  2414. else
  2415. {
  2416. break;
  2417. }
  2418. }
  2419. if(!(msg.compare("")==0))
  2420. {
  2421. msg+="";
  2422. }
  2423. return msg;
  2424. }
  2425. std::string GetSQLTypeName(const short sql_type_id,bool& is_type_variable)
  2426. {
  2427. std::string type_name;
  2428. is_type_variable=false;
  2429. switch(sql_type_id)
  2430. {
  2431. case SQL_BIT:
  2432. {
  2433. type_name="SQL_BIT";
  2434. break;
  2435. }
  2436. case SQL_CHAR:
  2437. {
  2438. type_name="SQL_CHAR";
  2439. break;
  2440. }
  2441. case SQL_VARCHAR:
  2442. {
  2443. type_name="SQL_VARCHAR";
  2444. break;
  2445. }
  2446. case SQL_LONGVARCHAR:
  2447. {
  2448. type_name="SQL_LONGVARCHAR";
  2449. break;
  2450. }
  2451. case SQL_WCHAR:
  2452. {
  2453. type_name="SQL_WCHAR";
  2454. is_type_variable=true;
  2455. break;
  2456. }
  2457. case SQL_WVARCHAR:
  2458. {
  2459. type_name="SQL_WVARCHAR";
  2460. is_type_variable=true;
  2461. break;
  2462. }
  2463. case SQL_WLONGVARCHAR:
  2464. {
  2465. type_name="SQL_WLONGVARCHAR";
  2466. is_type_variable=true;
  2467. break;
  2468. }
  2469. case SQL_TINYINT:
  2470. {
  2471. type_name="SQL_TINYINT";
  2472. break;
  2473. }
  2474. case SQL_SMALLINT:
  2475. {
  2476. type_name="SQL_SMALLINT";
  2477. break;
  2478. }
  2479. case SQL_INTEGER:
  2480. {
  2481. type_name="SQL_INTEGER";
  2482. break;
  2483. }
  2484. case SQL_BIGINT:
  2485. {
  2486. type_name="SQL_BIGINT";
  2487. break;
  2488. }
  2489. case SQL_DECIMAL:
  2490. {
  2491. type_name="SQL_DECIMAL";
  2492. break;
  2493. }
  2494. case SQL_NUMERIC:
  2495. {
  2496. type_name="SQL_NUMERIC";
  2497. break;
  2498. }
  2499. case SQL_REAL:
  2500. {
  2501. type_name="SQL_REAL";
  2502. break;
  2503. }
  2504. case SQL_FLOAT:
  2505. {
  2506. type_name="SQL_FLOAT";
  2507. break;
  2508. }
  2509. case SQL_DOUBLE:
  2510. {
  2511. type_name="SQL_DOUBLE";
  2512. break;
  2513. }
  2514. case SQL_DATE:
  2515. {
  2516. type_name="SQL_DATE";
  2517. break;
  2518. }
  2519. case SQL_TIME:
  2520. {
  2521. type_name="SQL_TIME";
  2522. break;
  2523. }
  2524. case SQL_TIMESTAMP:
  2525. {
  2526. type_name="SQL_TIMESTAMP";
  2527. break;
  2528. }
  2529. case SQL_BINARY:
  2530. {
  2531. type_name="SQL_BINARY";
  2532. is_type_variable=true;
  2533. break;
  2534. }
  2535. case SQL_VARBINARY:
  2536. {
  2537. type_name="SQL_VARBINARY";
  2538. is_type_variable=true;
  2539. break;
  2540. }
  2541. case SQL_LONGVARBINARY:
  2542. {
  2543. type_name="SQL_LONGVARBINARY";
  2544. is_type_variable=true;
  2545. break;
  2546. }
  2547. default:
  2548. {
  2549. type_name="SQL_INTEGER";
  2550. break;
  2551. }
  2552. }
  2553. return type_name;
  2554. }
  2555. //==========================================================================================
  2556. //METHODS FOR INTEROPERABILITY WITH EXCEL LIBREOFFICE MACRO
  2557. bool DBGetColumnsAndBind
  2558. (
  2559. DBConnection& connection,
  2560. SQLHSTMT& statement_handle,
  2561. const short& total_columns,
  2562. DBColumn*& columns
  2563. )
  2564. {
  2565. SQLRETURN rcode;
  2566. SQLSMALLINT type_enum;
  2567. short i,j;
  2568. long column_type;
  2569. long column_length;
  2570. columns=new DBColumn[total_columns];
  2571. for(i=0;i<total_columns;i++)
  2572. {
  2573. j=i+1;
  2574. //some drivers may only write the lower 32-bit or 16-bit of a buffer and leave
  2575. //the higher-order bit unchanged. Therefore, applications should initialize the
  2576. //value to 0 before calling SQLColAttribute
  2577. column_type=0;
  2578. column_length=0;
  2579. //Get the column's type
  2580. rcode=SQLColAttribute
  2581. (
  2582. statement_handle,
  2583. j,
  2584. SQL_DESC_CONCISE_TYPE,
  2585. NULL,
  2586. 0,
  2587. NULL,
  2588. &column_type
  2589. );
  2590. if(rcode!=SQL_SUCCESS)
  2591. {
  2592. //Show state
  2593. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2594. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2595. //cout << connection.last_message << endl;
  2596. return false;
  2597. }
  2598. columns[i].column_type=(short)(column_type);
  2599. //Get the column's byte length
  2600. rcode=SQLColAttribute
  2601. (
  2602. statement_handle,
  2603. j,
  2604. SQL_COLUMN_LENGTH,
  2605. NULL,
  2606. 0,
  2607. NULL,
  2608. &column_length
  2609. );
  2610. if(rcode!=SQL_SUCCESS)
  2611. {
  2612. //Show state
  2613. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2614. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2615. //cout << connection.last_message << endl;
  2616. return false;
  2617. }
  2618. columns[i].column_buffer_length=column_length;
  2619. //Get column's name
  2620. rcode=SQLColAttribute
  2621. (
  2622. statement_handle,
  2623. j,
  2624. SQL_DESC_NAME,
  2625. columns[i].column_name,
  2626. SQL_MAX_COLUMN_NAME_LEN,
  2627. &columns[i].column_name_length,
  2628. NULL
  2629. );
  2630. if(rcode!=SQL_SUCCESS)
  2631. {
  2632. //Show state
  2633. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2634. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2635. //cout << connection.last_message << endl;
  2636. return false;
  2637. }
  2638. //Get table name that contains the column
  2639. rcode=SQLColAttribute
  2640. (
  2641. statement_handle,
  2642. j,
  2643. SQL_COLUMN_TABLE_NAME,
  2644. columns[i].table_name,
  2645. SQL_MAX_TABLE_NAME_LEN,
  2646. &columns[i].table_name_length,
  2647. NULL
  2648. );
  2649. if(rcode!=SQL_SUCCESS)
  2650. {
  2651. //Show state
  2652. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2653. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2654. //cout << connection.last_message << endl;
  2655. return false;
  2656. }
  2657. //Get column's type name
  2658. rcode=SQLColAttribute
  2659. (
  2660. statement_handle,
  2661. j,
  2662. SQL_DESC_TYPE_NAME,
  2663. columns[i].column_type_name,
  2664. MAX_COL_TYPE_NAME_LENGTH,
  2665. &columns[i].column_type_name_length,
  2666. NULL
  2667. );
  2668. if(rcode!=SQL_SUCCESS)
  2669. {
  2670. //Show state
  2671. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2672. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2673. //cout << connection.last_message << endl;
  2674. return false;
  2675. }
  2676. //Get column's catalog name
  2677. rcode=SQLColAttribute
  2678. (
  2679. statement_handle,
  2680. j,
  2681. SQL_DESC_CATALOG_NAME,
  2682. columns[i].catalog_name,
  2683. SQL_MAX_CATALOG_NAME_LEN,
  2684. &columns[i].catalog_name_length,
  2685. NULL
  2686. );
  2687. if(rcode!=SQL_SUCCESS)
  2688. {
  2689. //Show state
  2690. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2691. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2692. //cout << connection.last_message << endl;
  2693. return false;
  2694. }
  2695. //Get column's schema name
  2696. rcode=SQLColAttribute
  2697. (
  2698. statement_handle,
  2699. j,
  2700. SQL_DESC_SCHEMA_NAME,
  2701. columns[i].schema_name,
  2702. SQL_MAX_SCHEMA_NAME_LEN,
  2703. &columns[i].schema_name_length,
  2704. NULL
  2705. );
  2706. if(rcode!=SQL_SUCCESS)
  2707. {
  2708. //Show state
  2709. connection.last_message+="\n[DBGetColumnsAndBind] SQLColAttribute error!";
  2710. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2711. //cout << connection.last_message << endl;
  2712. return false;
  2713. }
  2714. columns[i].column_buffer=new SQLCHAR[column_length];
  2715. switch(columns[i].column_type)
  2716. {
  2717. case SQL_BIT:
  2718. {
  2719. break;
  2720. }
  2721. case SQL_CHAR:
  2722. {
  2723. type_enum=SQL_C_CHAR;
  2724. break;
  2725. }
  2726. case SQL_VARCHAR:
  2727. {
  2728. type_enum=SQL_C_CHAR;
  2729. break;
  2730. }
  2731. case SQL_LONGVARCHAR:
  2732. {
  2733. break;
  2734. }
  2735. case SQL_WCHAR:
  2736. {
  2737. break;
  2738. }
  2739. case SQL_WVARCHAR:
  2740. {
  2741. break;
  2742. }
  2743. case SQL_WLONGVARCHAR:
  2744. {
  2745. break;
  2746. }
  2747. case SQL_TINYINT:
  2748. {
  2749. type_enum=SQL_C_TINYINT;
  2750. break;
  2751. }
  2752. case SQL_SMALLINT:
  2753. {
  2754. type_enum=SQL_C_SHORT;
  2755. break;
  2756. }
  2757. case SQL_INTEGER:
  2758. {
  2759. type_enum=SQL_C_LONG;
  2760. break;
  2761. }
  2762. case SQL_BIGINT:
  2763. {
  2764. type_enum=SQL_C_SBIGINT;
  2765. break;
  2766. }
  2767. case SQL_DECIMAL:
  2768. {
  2769. break;
  2770. }
  2771. case SQL_NUMERIC:
  2772. {
  2773. break;
  2774. }
  2775. case SQL_REAL:
  2776. {
  2777. break;
  2778. }
  2779. case SQL_FLOAT:
  2780. {
  2781. type_enum=SQL_C_FLOAT;
  2782. break;
  2783. }
  2784. case SQL_DOUBLE:
  2785. {
  2786. type_enum=SQL_C_DOUBLE;
  2787. break;
  2788. }
  2789. case SQL_DATE:
  2790. {
  2791. break;
  2792. }
  2793. case SQL_TIME:
  2794. {
  2795. break;
  2796. }
  2797. case SQL_TYPE_TIMESTAMP:
  2798. {
  2799. type_enum=SQL_C_TYPE_TIMESTAMP;
  2800. break;
  2801. }
  2802. case SQL_BINARY:
  2803. {
  2804. break;
  2805. }
  2806. case SQL_VARBINARY:
  2807. {
  2808. break;
  2809. }
  2810. case SQL_LONGVARBINARY:
  2811. {
  2812. break;
  2813. }
  2814. default:
  2815. {
  2816. break;
  2817. }
  2818. }
  2819. rcode=SQLBindCol
  2820. (
  2821. statement_handle,
  2822. j,
  2823. type_enum,
  2824. columns[i].column_buffer,
  2825. columns[i].column_buffer_length,
  2826. &columns[i].data_length_indicator
  2827. );
  2828. if(rcode!=SQL_SUCCESS)
  2829. {
  2830. //Show state
  2831. connection.last_message+="\n[DBGetColumnsAndBind] SQLBindCol error!";
  2832. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2833. return false;
  2834. }
  2835. }
  2836. return true;
  2837. }
  2838. bool DBBindInsertParameters
  2839. (
  2840. DBConnection& connection,
  2841. SQLHSTMT& statement_handle,
  2842. const short& total_columns,
  2843. DBColumn*& columns
  2844. )
  2845. {
  2846. SQLRETURN rcode;
  2847. SQLSMALLINT type_enum;
  2848. SQLSMALLINT format_size=0;
  2849. short i,j;
  2850. for(i=0;i<total_columns;i++)
  2851. {
  2852. j=i+1;
  2853. switch(columns[i].column_type)
  2854. {
  2855. case SQL_BIT:
  2856. {
  2857. break;
  2858. }
  2859. case SQL_CHAR:
  2860. {
  2861. type_enum=SQL_C_CHAR;
  2862. columns[i].data_length_indicator=sizeof(char);
  2863. break;
  2864. }
  2865. case SQL_VARCHAR:
  2866. {
  2867. type_enum=SQL_C_CHAR;
  2868. columns[i].data_length_indicator=SQL_NTS;
  2869. break;
  2870. }
  2871. case SQL_LONGVARCHAR:
  2872. {
  2873. break;
  2874. }
  2875. case SQL_WCHAR:
  2876. {
  2877. break;
  2878. }
  2879. case SQL_WVARCHAR:
  2880. {
  2881. break;
  2882. }
  2883. case SQL_WLONGVARCHAR:
  2884. {
  2885. break;
  2886. }
  2887. case SQL_TINYINT:
  2888. {
  2889. type_enum=SQL_C_TINYINT;
  2890. columns[i].data_length_indicator=sizeof(unsigned char);
  2891. break;
  2892. }
  2893. case SQL_SMALLINT:
  2894. {
  2895. type_enum=SQL_C_SHORT;
  2896. columns[i].data_length_indicator=sizeof(short);
  2897. break;
  2898. }
  2899. case SQL_INTEGER:
  2900. {
  2901. type_enum=SQL_C_LONG;
  2902. columns[i].data_length_indicator=sizeof(int);
  2903. break;
  2904. }
  2905. case SQL_BIGINT:
  2906. {
  2907. type_enum=SQL_C_SBIGINT;
  2908. columns[i].data_length_indicator=sizeof(long);
  2909. break;
  2910. }
  2911. case SQL_DECIMAL:
  2912. {
  2913. break;
  2914. }
  2915. case SQL_NUMERIC:
  2916. {
  2917. break;
  2918. }
  2919. case SQL_REAL:
  2920. {
  2921. break;
  2922. }
  2923. case SQL_FLOAT:
  2924. {
  2925. type_enum=SQL_C_FLOAT;
  2926. format_size=9;
  2927. columns[i].data_length_indicator=sizeof(float);
  2928. break;
  2929. }
  2930. case SQL_DOUBLE:
  2931. {
  2932. type_enum=SQL_C_DOUBLE;
  2933. columns[i].data_length_indicator=sizeof(double);
  2934. format_size=16;
  2935. break;
  2936. }
  2937. case SQL_DATE:
  2938. {
  2939. break;
  2940. }
  2941. case SQL_TIME:
  2942. {
  2943. break;
  2944. }
  2945. case SQL_TYPE_TIMESTAMP:
  2946. {
  2947. type_enum=SQL_C_TYPE_TIMESTAMP;
  2948. format_size=4;
  2949. columns[i].data_length_indicator=sizeof(SQL_TIMESTAMP_STRUCT);
  2950. break;
  2951. }
  2952. case SQL_BINARY:
  2953. {
  2954. break;
  2955. }
  2956. case SQL_VARBINARY:
  2957. {
  2958. break;
  2959. }
  2960. case SQL_LONGVARBINARY:
  2961. {
  2962. break;
  2963. }
  2964. default:
  2965. {
  2966. break;
  2967. }
  2968. }
  2969. rcode = SQLBindParameter
  2970. (
  2971. statement_handle,
  2972. j,
  2973. SQL_PARAM_INPUT,
  2974. type_enum,
  2975. columns[i].column_type,
  2976. columns[i].column_buffer_length,
  2977. format_size,
  2978. columns[i].column_buffer,
  2979. columns[i].column_buffer_length,
  2980. &columns[i].data_length_indicator
  2981. );
  2982. if(rcode!=SQL_SUCCESS)
  2983. {
  2984. //Show state
  2985. connection.last_message+="\n[DBBindInsertParameters] ";
  2986. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  2987. //cout << connection.last_message << endl;
  2988. return false;
  2989. }
  2990. }
  2991. return true;
  2992. }
  2993. bool DBBindUpdateParameters
  2994. (
  2995. DBConnection& connection,
  2996. SQLHSTMT& statement_handle,
  2997. const short& total_data_columns,
  2998. const short& total_primary_keys,
  2999. DBColumn*& data_columns,
  3000. DBColumn*& primary_keys
  3001. )
  3002. {
  3003. SQLRETURN rcode;
  3004. SQLSMALLINT type_enum;
  3005. SQLSMALLINT format_size=0;
  3006. short i;
  3007. short parameter_count=0;
  3008. for(i=0;i<total_data_columns;i++)
  3009. {
  3010. parameter_count++;
  3011. switch(data_columns[i].column_type)
  3012. {
  3013. case SQL_BIT:
  3014. {
  3015. break;
  3016. }
  3017. case SQL_CHAR:
  3018. {
  3019. type_enum=SQL_C_CHAR;
  3020. data_columns[i].data_length_indicator=sizeof(char);
  3021. break;
  3022. }
  3023. case SQL_VARCHAR:
  3024. {
  3025. type_enum=SQL_C_CHAR;
  3026. data_columns[i].data_length_indicator=SQL_NTS;
  3027. break;
  3028. }
  3029. case SQL_LONGVARCHAR:
  3030. {
  3031. break;
  3032. }
  3033. case SQL_WCHAR:
  3034. {
  3035. break;
  3036. }
  3037. case SQL_WVARCHAR:
  3038. {
  3039. break;
  3040. }
  3041. case SQL_WLONGVARCHAR:
  3042. {
  3043. break;
  3044. }
  3045. case SQL_TINYINT:
  3046. {
  3047. type_enum=SQL_C_TINYINT;
  3048. data_columns[i].data_length_indicator=sizeof(unsigned char);
  3049. break;
  3050. }
  3051. case SQL_SMALLINT:
  3052. {
  3053. type_enum=SQL_C_SHORT;
  3054. data_columns[i].data_length_indicator=sizeof(short);
  3055. break;
  3056. }
  3057. case SQL_INTEGER:
  3058. {
  3059. type_enum=SQL_C_LONG;
  3060. data_columns[i].data_length_indicator=sizeof(int);
  3061. break;
  3062. }
  3063. case SQL_BIGINT:
  3064. {
  3065. type_enum=SQL_C_SBIGINT;
  3066. data_columns[i].data_length_indicator=sizeof(long);
  3067. break;
  3068. }
  3069. case SQL_DECIMAL:
  3070. {
  3071. break;
  3072. }
  3073. case SQL_NUMERIC:
  3074. {
  3075. break;
  3076. }
  3077. case SQL_REAL:
  3078. {
  3079. break;
  3080. }
  3081. case SQL_FLOAT:
  3082. {
  3083. type_enum=SQL_C_FLOAT;
  3084. format_size=9;
  3085. data_columns[i].data_length_indicator=sizeof(float);
  3086. break;
  3087. }
  3088. case SQL_DOUBLE:
  3089. {
  3090. type_enum=SQL_C_DOUBLE;
  3091. data_columns[i].data_length_indicator=sizeof(double);
  3092. format_size=16;
  3093. break;
  3094. }
  3095. case SQL_DATE:
  3096. {
  3097. break;
  3098. }
  3099. case SQL_TIME:
  3100. {
  3101. break;
  3102. }
  3103. case SQL_TYPE_TIMESTAMP:
  3104. {
  3105. type_enum=SQL_C_TYPE_TIMESTAMP;
  3106. format_size=4;
  3107. data_columns[i].data_length_indicator=sizeof(SQL_TIMESTAMP_STRUCT);
  3108. break;
  3109. }
  3110. case SQL_BINARY:
  3111. {
  3112. break;
  3113. }
  3114. case SQL_VARBINARY:
  3115. {
  3116. break;
  3117. }
  3118. case SQL_LONGVARBINARY:
  3119. {
  3120. break;
  3121. }
  3122. default:
  3123. {
  3124. break;
  3125. }
  3126. }
  3127. rcode = SQLBindParameter
  3128. (
  3129. statement_handle,
  3130. parameter_count,
  3131. SQL_PARAM_INPUT,
  3132. type_enum,
  3133. data_columns[i].column_type,
  3134. data_columns[i].data_length_indicator,
  3135. format_size,
  3136. data_columns[i].column_buffer,
  3137. data_columns[i].column_buffer_length,
  3138. &data_columns[i].data_length_indicator
  3139. );
  3140. if(rcode!=SQL_SUCCESS)
  3141. {
  3142. //Show state
  3143. connection.last_message+="\n[DBBindUpdateParameters] error executing \
  3144. SQLBindParameter at columns!\n";
  3145. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3146. //cout << connection.last_message << endl;
  3147. return false;
  3148. }
  3149. }
  3150. for(i=0;i<total_primary_keys;i++)
  3151. {
  3152. parameter_count++;
  3153. switch(primary_keys[i].column_type)
  3154. {
  3155. case SQL_BIT:
  3156. {
  3157. break;
  3158. }
  3159. case SQL_CHAR:
  3160. {
  3161. type_enum=SQL_C_CHAR;
  3162. primary_keys[i].data_length_indicator=sizeof(char);
  3163. break;
  3164. }
  3165. case SQL_VARCHAR:
  3166. {
  3167. type_enum=SQL_C_CHAR;
  3168. primary_keys[i].data_length_indicator=SQL_NTS;
  3169. break;
  3170. }
  3171. case SQL_LONGVARCHAR:
  3172. {
  3173. break;
  3174. }
  3175. case SQL_WCHAR:
  3176. {
  3177. break;
  3178. }
  3179. case SQL_WVARCHAR:
  3180. {
  3181. break;
  3182. }
  3183. case SQL_WLONGVARCHAR:
  3184. {
  3185. break;
  3186. }
  3187. case SQL_TINYINT:
  3188. {
  3189. type_enum=SQL_C_TINYINT;
  3190. primary_keys[i].data_length_indicator=sizeof(unsigned char);
  3191. break;
  3192. }
  3193. case SQL_SMALLINT:
  3194. {
  3195. type_enum=SQL_C_SHORT;
  3196. primary_keys[i].data_length_indicator=sizeof(short);
  3197. break;
  3198. }
  3199. case SQL_INTEGER:
  3200. {
  3201. type_enum=SQL_C_LONG;
  3202. primary_keys[i].data_length_indicator=sizeof(int);
  3203. break;
  3204. }
  3205. case SQL_BIGINT:
  3206. {
  3207. type_enum=SQL_C_SBIGINT;
  3208. primary_keys[i].data_length_indicator=sizeof(long);
  3209. break;
  3210. }
  3211. case SQL_DECIMAL:
  3212. {
  3213. break;
  3214. }
  3215. case SQL_NUMERIC:
  3216. {
  3217. break;
  3218. }
  3219. case SQL_REAL:
  3220. {
  3221. break;
  3222. }
  3223. case SQL_FLOAT:
  3224. {
  3225. type_enum=SQL_C_FLOAT;
  3226. format_size=9;
  3227. primary_keys[i].data_length_indicator=sizeof(float);
  3228. break;
  3229. }
  3230. case SQL_DOUBLE:
  3231. {
  3232. type_enum=SQL_C_DOUBLE;
  3233. primary_keys[i].data_length_indicator=sizeof(double);
  3234. format_size=16;
  3235. break;
  3236. }
  3237. case SQL_DATE:
  3238. {
  3239. break;
  3240. }
  3241. case SQL_TIME:
  3242. {
  3243. break;
  3244. }
  3245. case SQL_TYPE_TIMESTAMP:
  3246. {
  3247. type_enum=SQL_C_TYPE_TIMESTAMP;
  3248. format_size=4;
  3249. primary_keys[i].data_length_indicator=sizeof(SQL_TIMESTAMP_STRUCT);
  3250. break;
  3251. }
  3252. case SQL_BINARY:
  3253. {
  3254. break;
  3255. }
  3256. case SQL_VARBINARY:
  3257. {
  3258. break;
  3259. }
  3260. case SQL_LONGVARBINARY:
  3261. {
  3262. break;
  3263. }
  3264. default:
  3265. {
  3266. break;
  3267. }
  3268. }
  3269. rcode = SQLBindParameter
  3270. (
  3271. statement_handle,
  3272. parameter_count,
  3273. SQL_PARAM_INPUT,
  3274. type_enum,
  3275. primary_keys[i].column_type,
  3276. primary_keys[i].data_length_indicator,
  3277. format_size,
  3278. primary_keys[i].column_buffer,
  3279. primary_keys[i].column_buffer_length,
  3280. &primary_keys[i].data_length_indicator
  3281. );
  3282. if(rcode!=SQL_SUCCESS)
  3283. {
  3284. //Show state
  3285. connection.last_message+="\n[DBBindUpdateParameters] error executing \
  3286. SQLBindParameter at primary keys!\n";
  3287. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3288. //cout << connection.last_message << endl;
  3289. return false;
  3290. }
  3291. }
  3292. return true;
  3293. }
  3294. bool DBBindDeleteParameters
  3295. (
  3296. DBConnection& connection,
  3297. SQLHSTMT& statement_handle,
  3298. const short& total_primary_keys,
  3299. DBColumn*& primary_keys
  3300. )
  3301. {
  3302. SQLRETURN rcode;
  3303. SQLSMALLINT type_enum;
  3304. SQLSMALLINT format_size=0;
  3305. short i;
  3306. short parameter_count=0;
  3307. for(i=0;i<total_primary_keys;i++)
  3308. {
  3309. parameter_count++;
  3310. switch(primary_keys[i].column_type)
  3311. {
  3312. case SQL_BIT:
  3313. {
  3314. break;
  3315. }
  3316. case SQL_CHAR:
  3317. {
  3318. type_enum=SQL_C_CHAR;
  3319. primary_keys[i].data_length_indicator=sizeof(char);
  3320. break;
  3321. }
  3322. case SQL_VARCHAR:
  3323. {
  3324. type_enum=SQL_C_CHAR;
  3325. primary_keys[i].data_length_indicator=SQL_NTS;
  3326. break;
  3327. }
  3328. case SQL_LONGVARCHAR:
  3329. {
  3330. break;
  3331. }
  3332. case SQL_WCHAR:
  3333. {
  3334. break;
  3335. }
  3336. case SQL_WVARCHAR:
  3337. {
  3338. break;
  3339. }
  3340. case SQL_WLONGVARCHAR:
  3341. {
  3342. break;
  3343. }
  3344. case SQL_TINYINT:
  3345. {
  3346. type_enum=SQL_C_TINYINT;
  3347. primary_keys[i].data_length_indicator=sizeof(unsigned char);
  3348. break;
  3349. }
  3350. case SQL_SMALLINT:
  3351. {
  3352. type_enum=SQL_C_SHORT;
  3353. primary_keys[i].data_length_indicator=sizeof(short);
  3354. break;
  3355. }
  3356. case SQL_INTEGER:
  3357. {
  3358. type_enum=SQL_C_LONG;
  3359. primary_keys[i].data_length_indicator=sizeof(int);
  3360. break;
  3361. }
  3362. case SQL_BIGINT:
  3363. {
  3364. type_enum=SQL_C_SBIGINT;
  3365. primary_keys[i].data_length_indicator=sizeof(long);
  3366. break;
  3367. }
  3368. case SQL_DECIMAL:
  3369. {
  3370. break;
  3371. }
  3372. case SQL_NUMERIC:
  3373. {
  3374. break;
  3375. }
  3376. case SQL_REAL:
  3377. {
  3378. break;
  3379. }
  3380. case SQL_FLOAT:
  3381. {
  3382. type_enum=SQL_C_FLOAT;
  3383. format_size=9;
  3384. primary_keys[i].data_length_indicator=sizeof(float);
  3385. break;
  3386. }
  3387. case SQL_DOUBLE:
  3388. {
  3389. type_enum=SQL_C_DOUBLE;
  3390. primary_keys[i].data_length_indicator=sizeof(double);
  3391. format_size=16;
  3392. break;
  3393. }
  3394. case SQL_DATE:
  3395. {
  3396. break;
  3397. }
  3398. case SQL_TIME:
  3399. {
  3400. break;
  3401. }
  3402. case SQL_TYPE_TIMESTAMP:
  3403. {
  3404. type_enum=SQL_C_TYPE_TIMESTAMP;
  3405. format_size=4;
  3406. primary_keys[i].data_length_indicator=sizeof(SQL_TIMESTAMP_STRUCT);
  3407. break;
  3408. }
  3409. case SQL_BINARY:
  3410. {
  3411. break;
  3412. }
  3413. case SQL_VARBINARY:
  3414. {
  3415. break;
  3416. }
  3417. case SQL_LONGVARBINARY:
  3418. {
  3419. break;
  3420. }
  3421. default:
  3422. {
  3423. break;
  3424. }
  3425. }
  3426. rcode = SQLBindParameter
  3427. (
  3428. statement_handle,
  3429. parameter_count,
  3430. SQL_PARAM_INPUT,
  3431. type_enum,
  3432. primary_keys[i].column_type,
  3433. primary_keys[i].data_length_indicator,
  3434. format_size,
  3435. primary_keys[i].column_buffer,
  3436. primary_keys[i].column_buffer_length,
  3437. &primary_keys[i].data_length_indicator
  3438. );
  3439. if(rcode!=SQL_SUCCESS)
  3440. {
  3441. //Show state
  3442. connection.last_message+="\n[DBBindDeleteParameters] error executing \
  3443. SQLBindParameter at primary keys!\n";
  3444. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3445. //cout << connection.last_message << endl;
  3446. return false;
  3447. }
  3448. }
  3449. return true;
  3450. }
  3451. bool DBPrepareSelect
  3452. (
  3453. DBConnection& connection,
  3454. SQLHSTMT& statement_handle,
  3455. const std::string& sqlcmd
  3456. )
  3457. {
  3458. SQLRETURN rcode;
  3459. //Allocate statement handle
  3460. rcode=SQLAllocHandle
  3461. (
  3462. SQL_HANDLE_STMT,
  3463. connection.database_connection_handle,
  3464. &statement_handle
  3465. );
  3466. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3467. {
  3468. connection.last_message="\n[DBPrepareSelect] Can't allocate statement handle!";
  3469. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3470. return false;
  3471. }
  3472. //Set cursor statement attribute
  3473. rcode=SQLSetStmtAttr
  3474. (
  3475. statement_handle,
  3476. SQL_ATTR_CURSOR_TYPE,
  3477. (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
  3478. 0
  3479. );
  3480. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3481. {
  3482. connection.last_message="\n[DBPrepareSelect] Can't set cursor attribute!";
  3483. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3484. return false;
  3485. }
  3486. //Set cursor row size statement attribute
  3487. rcode=SQLSetStmtAttr
  3488. (
  3489. statement_handle,
  3490. SQL_ATTR_ROW_ARRAY_SIZE,
  3491. (SQLPOINTER)1,
  3492. SQL_IS_UINTEGER
  3493. );
  3494. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3495. {
  3496. connection.last_message="\n[DBPrepareSelect] Can't set cursor size attribute!";
  3497. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3498. return false;
  3499. }
  3500. //Set concurrency statement attribute
  3501. rcode=SQLSetStmtAttr
  3502. (
  3503. statement_handle,
  3504. SQL_ATTR_CONCURRENCY,
  3505. (SQLPOINTER)SQL_CONCUR_READ_ONLY,
  3506. 0
  3507. );
  3508. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3509. {
  3510. connection.last_message="\n[DBPrepareSelect] Can't set concurrency attribute!";
  3511. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3512. return false;
  3513. }
  3514. //Prepare SQl command
  3515. rcode=SQLPrepare
  3516. (
  3517. statement_handle,
  3518. (PSQLCHAR)sqlcmd.c_str(),
  3519. (SQLINTEGER)strlen(sqlcmd.c_str())
  3520. );
  3521. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3522. {
  3523. connection.sql_command_prepared=false;
  3524. connection.last_message="\n[DBPrepareSelect] Can't prepare SQL statement!";
  3525. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3526. return false;
  3527. }
  3528. connection.sql_command_prepared=true;
  3529. //THE ASYNCHRONOUS SUPPORT FOR NOW IS NOT USED GIVEN THAT DM (DRIVER MANAGER)
  3530. //IS A TOO OLD VERSION THAT NOT SUPPORT ASKING FOR ASYNCHRONOUS TASKS TO FINISH
  3531. //FOR NOW THIS PROBLEM CANNOT BE HANDLED
  3532. //Set asynchronous support statement attribute
  3533. //rcode=SQLSetStmtAttr(connection.statement_handle,SQL_ATTR_ASYNC_ENABLE,(SQLPOINTER)SQL_ASYNC_ENABLE_ON,0);
  3534. //if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3535. //{
  3536. // connection.last_message="\n[DBPrepareStatement]Can't set asynchronous support attribute!";
  3537. // connection.last_message+="";
  3538. // connection.last_message+=DBGetErrorMsg(connection,SQL_HANDLE_STMT);
  3539. // return false;
  3540. //}
  3541. return true;
  3542. }
  3543. bool DBPrepareInsert
  3544. (
  3545. DBConnection& connection,
  3546. SQLHSTMT& statement_handle,
  3547. const std::string& sqlcmd
  3548. )
  3549. {
  3550. SQLRETURN rcode;
  3551. //Allocate statement handle
  3552. rcode=SQLAllocHandle
  3553. (
  3554. SQL_HANDLE_STMT,
  3555. connection.database_connection_handle,
  3556. &statement_handle
  3557. );
  3558. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3559. {
  3560. connection.last_message="\n[DBPrepareInsert] Can't allocate statement handle!";
  3561. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3562. return false;
  3563. }
  3564. //Set cursor statement attribute
  3565. rcode=SQLSetStmtAttr
  3566. (
  3567. statement_handle,
  3568. SQL_ATTR_CURSOR_TYPE,
  3569. (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
  3570. 0
  3571. );
  3572. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3573. {
  3574. connection.last_message="\n[DBPrepareInsert] Can't set cursor attribute!";
  3575. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3576. return false;
  3577. }
  3578. //Set cursor row size statement attribute
  3579. rcode=SQLSetStmtAttr
  3580. (
  3581. statement_handle,
  3582. SQL_ATTR_ROW_ARRAY_SIZE,
  3583. (SQLPOINTER)1,
  3584. SQL_IS_UINTEGER
  3585. );
  3586. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3587. {
  3588. connection.last_message="\n[DBPrepareInsert] Can't set cursor size attribute!";
  3589. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3590. return false;
  3591. }
  3592. //Set concurrency statement attribute
  3593. rcode=SQLSetStmtAttr
  3594. (
  3595. statement_handle,
  3596. SQL_ATTR_CONCURRENCY,
  3597. (SQLPOINTER)SQL_CONCUR_DEFAULT,
  3598. 0
  3599. );
  3600. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3601. {
  3602. connection.last_message="\n[DBPrepareInsert] Can't set concurrency attribute!";
  3603. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3604. return false;
  3605. }
  3606. //To indicate column binding
  3607. rcode=SQLSetStmtAttr
  3608. (
  3609. statement_handle,
  3610. SQL_ATTR_PARAM_BIND_TYPE,
  3611. SQL_PARAM_BIND_BY_COLUMN,
  3612. 0
  3613. );
  3614. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3615. {
  3616. connection.last_message="\n[DBPrepareInsert] Can't set parameter binding type \
  3617. attribute!";
  3618. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3619. return false;
  3620. }
  3621. //To indicate the number of parameters to bind
  3622. SQLUSMALLINT total_parameters;
  3623. size_t n=std::count(sqlcmd.begin(), sqlcmd.end(),'?');
  3624. if(n>0)
  3625. {
  3626. total_parameters=(SQLUSMALLINT)n;
  3627. }
  3628. else
  3629. {
  3630. connection.last_message="\n[DBPrepareInsert] Bad SQL command!";
  3631. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3632. return false;
  3633. }
  3634. rcode=SQLSetStmtAttr
  3635. (
  3636. statement_handle,
  3637. SQL_ATTR_PARAMSET_SIZE,
  3638. (SQLPOINTER)(&total_parameters),
  3639. 0
  3640. );
  3641. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3642. {
  3643. connection.last_message="\n[DBPrepareInsert] Can't set the number of parameters \
  3644. binding attribute!";
  3645. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3646. return false;
  3647. }
  3648. //To indicate the rows per parameter set
  3649. rcode=SQLSetStmtAttr
  3650. (
  3651. statement_handle,
  3652. SQL_ATTR_PARAMSET_SIZE,
  3653. (SQLPOINTER)1,
  3654. 0
  3655. );
  3656. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3657. {
  3658. connection.last_message="\n[DBPrepareInsert] Can't set parameter binding type \
  3659. attribute!";
  3660. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3661. return false;
  3662. }
  3663. // //Prepare SQl command
  3664. // rcode=SQLPrepare(connection.statement_handle,(PSQLCHAR)sqlcmd.c_str(),
  3665. // (SQLINTEGER)strlen(sqlcmd.c_str()));
  3666. // if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3667. // {
  3668. // connection.sql_command_prepared=false;
  3669. // connection.last_message="\n[DBPrepareInsert] Can't prepare SQL statement!";
  3670. // connection.last_message+="";
  3671. // connection.last_message+=DBGetErrorMsg(connection,SQL_HANDLE_STMT);
  3672. // return false;
  3673. // }
  3674. // connection.sql_command_prepared=true;
  3675. return true;
  3676. }
  3677. bool DBPrepareUpdate
  3678. (
  3679. DBConnection& connection,
  3680. SQLHSTMT& statement_handle,
  3681. const std::string& sqlcmd
  3682. )
  3683. {
  3684. SQLRETURN rcode;
  3685. //Allocate statement handle
  3686. rcode=SQLAllocHandle
  3687. (
  3688. SQL_HANDLE_STMT,
  3689. connection.database_connection_handle,
  3690. &statement_handle
  3691. );
  3692. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3693. {
  3694. connection.last_message="\n[DBPrepareUpdate] Can't allocate statement handle!";
  3695. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3696. return false;
  3697. }
  3698. //Set cursor statement attribute
  3699. rcode=SQLSetStmtAttr
  3700. (
  3701. statement_handle,
  3702. SQL_ATTR_CURSOR_TYPE,
  3703. (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
  3704. 0
  3705. );
  3706. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3707. {
  3708. connection.last_message="\n[DBPrepareUpdate] Can't set cursor attribute!";
  3709. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3710. return false;
  3711. }
  3712. //Set cursor row size statement attribute
  3713. rcode=SQLSetStmtAttr
  3714. (
  3715. statement_handle,
  3716. SQL_ATTR_ROW_ARRAY_SIZE,
  3717. (SQLPOINTER)1,
  3718. SQL_IS_UINTEGER
  3719. );
  3720. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3721. {
  3722. connection.last_message="\n[DBPrepareUpdate] Can't set cursor size attribute!";
  3723. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3724. return false;
  3725. }
  3726. //Set concurrency statement attribute
  3727. rcode=SQLSetStmtAttr
  3728. (
  3729. statement_handle,
  3730. SQL_ATTR_CONCURRENCY,
  3731. (SQLPOINTER)SQL_CONCUR_DEFAULT,
  3732. 0
  3733. );
  3734. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3735. {
  3736. connection.last_message="\n[DBPrepareUpdate] Can't set concurrency attribute!";
  3737. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3738. return false;
  3739. }
  3740. //To indicate column binding
  3741. rcode=SQLSetStmtAttr
  3742. (
  3743. statement_handle,
  3744. SQL_ATTR_PARAM_BIND_TYPE,
  3745. SQL_PARAM_BIND_BY_COLUMN,
  3746. 0
  3747. );
  3748. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3749. {
  3750. connection.last_message="\n[DBPrepareUpdate] Can't set parameter binding type \
  3751. attribute!";
  3752. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3753. return false;
  3754. }
  3755. return true;
  3756. }
  3757. bool DBPrepareDelete
  3758. (
  3759. DBConnection& connection,
  3760. SQLHSTMT& statement_handle,
  3761. const std::string& sqlcmd
  3762. )
  3763. {
  3764. SQLRETURN rcode;
  3765. //Allocate statement handle
  3766. rcode=SQLAllocHandle
  3767. (
  3768. SQL_HANDLE_STMT,
  3769. connection.database_connection_handle,
  3770. &statement_handle
  3771. );
  3772. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3773. {
  3774. connection.last_message="\n[DBPrepareDelete] Can't allocate statement handle!";
  3775. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3776. return false;
  3777. }
  3778. //Set cursor statement attribute
  3779. rcode=SQLSetStmtAttr
  3780. (
  3781. statement_handle,
  3782. SQL_ATTR_CURSOR_TYPE,
  3783. (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,
  3784. 0
  3785. );
  3786. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3787. {
  3788. connection.last_message="\n[DBPrepareDelete] Can't set cursor attribute!";
  3789. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3790. return false;
  3791. }
  3792. //Set cursor row size statement attribute
  3793. rcode=SQLSetStmtAttr
  3794. (
  3795. statement_handle,
  3796. SQL_ATTR_ROW_ARRAY_SIZE,
  3797. (SQLPOINTER)1,
  3798. SQL_IS_UINTEGER
  3799. );
  3800. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3801. {
  3802. connection.last_message="\n[DBPrepareDelete] Can't set cursor size attribute!";
  3803. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3804. return false;
  3805. }
  3806. //Set concurrency statement attribute
  3807. rcode=SQLSetStmtAttr
  3808. (
  3809. statement_handle,
  3810. SQL_ATTR_CONCURRENCY,
  3811. (SQLPOINTER)SQL_CONCUR_DEFAULT,
  3812. 0
  3813. );
  3814. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3815. {
  3816. connection.last_message="\n[DBPrepareDelete] Can't set concurrency attribute!";
  3817. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3818. return false;
  3819. }
  3820. //To indicate column binding
  3821. rcode=SQLSetStmtAttr
  3822. (
  3823. statement_handle,
  3824. SQL_ATTR_PARAM_BIND_TYPE,
  3825. SQL_PARAM_BIND_BY_COLUMN,
  3826. 0
  3827. );
  3828. if(rcode!=SQL_SUCCESS && rcode!=SQL_SUCCESS_WITH_INFO)
  3829. {
  3830. connection.last_message="\n[DBPrepareDelete] Can't set parameter binding type \
  3831. attribute!";
  3832. connection.last_message+=DBGetErrorMsg(statement_handle,SQL_HANDLE_STMT);
  3833. return false;
  3834. }
  3835. return true;
  3836. }
  3837. }//odbc_database_operations namespace
  3838. }//databases namespace

comments powered by Disqus