transactd 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (306) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +46 -67
  3. data/BUILD_WIN-JA +106 -63
  4. data/CMakeLists.txt +40 -15
  5. data/README +219 -75
  6. data/README-JA +207 -76
  7. data/README_ORMSRCGEN +118 -0
  8. data/README_ORMSRCGEN-JA +115 -0
  9. data/bin/common/tdclc_32_2_0.dll +0 -0
  10. data/bin/common/tdclc_64_2_0.dll +0 -0
  11. data/build/common/check_for_link_iconv.cmake +18 -14
  12. data/build/common/create_symlink.cmake.in +25 -0
  13. data/build/common/get_boost_libs.cmake +23 -23
  14. data/build/common/options.cmake +0 -66
  15. data/build/common/smart_install.cmake +3 -3
  16. data/build/common/transactd.rc.in +15 -5
  17. data/build/common/transactd_cl_common.cmake +37 -18
  18. data/build/common/transactd_cl_output.cmake +55 -13
  19. data/build/common/transactd_common.cmake +108 -31
  20. data/build/swig/php/generate.cmake.in +15 -17
  21. data/build/swig/php/generate.cmd.in +15 -9
  22. data/build/swig/php/php.swg +124 -82
  23. data/build/swig/php/transactd.no_yield.php +4494 -0
  24. data/build/swig/php/transactd.no_yield.php.git.patch +685 -0
  25. data/build/swig/php/transactd.no_yield.php.patch +685 -0
  26. data/build/swig/php/transactd.yield.php +4461 -0
  27. data/build/swig/php/transactd.yield.php.git.patch +652 -0
  28. data/build/swig/php/transactd.yield.php.patch +652 -0
  29. data/build/swig/referencecounter.h +79 -0
  30. data/build/swig/ruby/ruby.swg +226 -76
  31. data/build/swig/ruby/threadBlockRegionWrapper.h +71 -0
  32. data/build/swig/ruby/without_gvl.swg +87 -0
  33. data/build/swig/tdcl.i +659 -170
  34. data/build/swig/validatablepointer.h +91 -0
  35. data/build/tdclc/CMakeLists.txt +49 -34
  36. data/build/tdclc/{tdclc_64.cbproj → tdclc.cbproj} +65 -20
  37. data/build/tdclc/tdclc.rc +0 -0
  38. data/build/tdclcpp/CMakeLists.txt +84 -20
  39. data/build/tdclcpp/tdclcpp.rc +0 -0
  40. data/build/tdclcpp/{tdclcpp_bcb_64.cbproj → tdclcpp_bc.cbproj} +168 -44
  41. data/build/tdclrb/CMakeLists.txt +84 -66
  42. data/build/tdclrb/bldgem/extconf.rb +28 -3
  43. data/build/tdclrb/gem/helper.rb +11 -1
  44. data/build/tdclrb/gem_output.cmake +20 -16
  45. data/index_ja.html +15 -0
  46. data/source/bzs/db/IBlobBuffer.h +15 -17
  47. data/source/bzs/db/blobBuffer.h +186 -140
  48. data/source/bzs/db/blobStructs.h +37 -37
  49. data/source/bzs/db/engine/mysql/IReadRecords.h +34 -34
  50. data/source/bzs/db/engine/mysql/bookmark.h +150 -147
  51. data/source/bzs/db/engine/mysql/database.cpp +1721 -1526
  52. data/source/bzs/db/engine/mysql/database.h +608 -370
  53. data/source/bzs/db/engine/mysql/dbManager.cpp +213 -201
  54. data/source/bzs/db/engine/mysql/dbManager.h +115 -104
  55. data/source/bzs/db/engine/mysql/errorMessage.cpp +49 -50
  56. data/source/bzs/db/engine/mysql/errorMessage.h +25 -26
  57. data/source/bzs/db/engine/mysql/fieldAccess.h +55 -61
  58. data/source/bzs/db/engine/mysql/mydebuglog.cpp +326 -292
  59. data/source/bzs/db/engine/mysql/mydebuglog.h +63 -55
  60. data/source/bzs/db/engine/mysql/mysqlInternal.h +182 -125
  61. data/source/bzs/db/engine/mysql/mysqlThd.cpp +121 -121
  62. data/source/bzs/db/engine/mysql/mysqlThd.h +20 -20
  63. data/source/bzs/db/engine/mysql/percentageKey.h +241 -228
  64. data/source/bzs/db/protocol/ICommandExecuter.h +18 -17
  65. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +543 -514
  66. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +155 -158
  67. data/source/bzs/db/protocol/tdap/btrDate.cpp +213 -180
  68. data/source/bzs/db/protocol/tdap/btrDate.h +39 -37
  69. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +173 -0
  70. data/source/bzs/db/protocol/tdap/client/activeTable.h +165 -0
  71. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +370 -0
  72. data/source/bzs/db/protocol/tdap/client/bulkInsert.h +13 -23
  73. data/source/bzs/db/protocol/tdap/client/client.cpp +81 -68
  74. data/source/bzs/db/protocol/tdap/client/client.h +361 -320
  75. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +17 -22
  76. data/source/bzs/db/protocol/tdap/client/connMgr.h +17 -19
  77. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +243 -0
  78. data/source/bzs/db/protocol/tdap/client/connectionPool.h +109 -0
  79. data/source/bzs/db/protocol/tdap/client/database.cpp +327 -219
  80. data/source/bzs/db/protocol/tdap/client/database.h +141 -118
  81. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +60 -62
  82. data/source/bzs/db/protocol/tdap/client/databaseManager.h +255 -0
  83. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +315 -202
  84. data/source/bzs/db/protocol/tdap/client/dbDef.h +40 -32
  85. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +390 -371
  86. data/source/bzs/db/protocol/tdap/client/errorMessage.cpp +148 -56
  87. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +149 -57
  88. data/source/bzs/db/protocol/tdap/client/export.h +35 -0
  89. data/source/bzs/db/protocol/tdap/client/field.cpp +1985 -0
  90. data/source/bzs/db/protocol/tdap/client/field.h +393 -0
  91. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +14 -14
  92. data/source/bzs/db/protocol/tdap/client/fieldDDF.h +11 -14
  93. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +123 -0
  94. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +58 -0
  95. data/source/bzs/db/protocol/tdap/client/fields.h +178 -0
  96. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +13 -16
  97. data/source/bzs/db/protocol/tdap/client/fileDDF.h +11 -17
  98. data/source/bzs/db/protocol/tdap/client/filter.h +423 -259
  99. data/source/bzs/db/protocol/tdap/client/groupComp.h +117 -0
  100. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +818 -0
  101. data/source/bzs/db/protocol/tdap/client/groupQuery.h +281 -0
  102. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +14 -17
  103. data/source/bzs/db/protocol/tdap/client/indexDDF.h +11 -14
  104. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +231 -0
  105. data/source/bzs/db/protocol/tdap/client/memRecord.h +145 -0
  106. data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +448 -0
  107. data/source/bzs/db/protocol/tdap/client/memRecordset.h +159 -0
  108. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +300 -173
  109. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +53 -36
  110. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +171 -128
  111. data/source/bzs/db/protocol/tdap/client/nsTable.h +121 -87
  112. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +173 -0
  113. data/source/bzs/db/protocol/tdap/client/recordset.cpp +209 -0
  114. data/source/bzs/db/protocol/tdap/client/recordset.h +86 -0
  115. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +596 -0
  116. data/source/bzs/db/protocol/tdap/client/request.h +227 -170
  117. data/source/bzs/db/protocol/tdap/client/serializer.cpp +1288 -0
  118. data/source/bzs/db/protocol/tdap/client/serializer.h +295 -0
  119. data/source/bzs/db/protocol/tdap/client/sharedData.cpp +9 -12
  120. data/source/bzs/db/protocol/tdap/client/sharedData.h +18 -16
  121. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +494 -473
  122. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +51 -53
  123. data/source/bzs/db/protocol/tdap/client/stringConverter.h +214 -148
  124. data/source/bzs/db/protocol/tdap/client/table.cpp +929 -1665
  125. data/source/bzs/db/protocol/tdap/client/table.h +413 -87
  126. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +642 -534
  127. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +25 -40
  128. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +11 -15
  129. data/source/bzs/db/protocol/tdap/client/trdormapi.h +378 -437
  130. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +1 -1
  131. data/source/bzs/db/protocol/tdap/fieldComp.h +127 -0
  132. data/source/bzs/db/protocol/tdap/myDateTime.cpp +352 -345
  133. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +75 -78
  134. data/source/bzs/db/protocol/tdap/mysql/characterset.h +18 -19
  135. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +216 -199
  136. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +23 -14
  137. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +354 -314
  138. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +57 -47
  139. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +905 -739
  140. data/source/bzs/db/protocol/tdap/mysql/request.h +152 -159
  141. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +1044 -879
  142. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +87 -81
  143. data/source/bzs/db/protocol/tdap/tdapRequest.h +162 -130
  144. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +368 -166
  145. data/source/bzs/db/protocol/tdap/tdapSchema.h +702 -566
  146. data/source/bzs/db/protocol/tdap/tdapcapi.h +387 -353
  147. data/source/bzs/db/transactd/appBuilderImple.h +21 -20
  148. data/source/bzs/db/transactd/appModule.cpp +350 -98
  149. data/source/bzs/db/transactd/appModule.h +31 -37
  150. data/source/bzs/db/transactd/connManager.cpp +138 -135
  151. data/source/bzs/db/transactd/connManager.h +28 -21
  152. data/source/bzs/db/transactd/connectionRecord.h +39 -39
  153. data/source/bzs/db/transactd/transactd.cpp +217 -203
  154. data/source/bzs/env/boost_bcb_link.h +131 -0
  155. data/source/bzs/env/compiler.h +136 -79
  156. data/source/bzs/env/crosscompile.cpp +57 -57
  157. data/source/bzs/env/crosscompile.h +130 -115
  158. data/source/bzs/env/fileopen.h +7 -8
  159. data/source/bzs/env/mbcswchrLinux.cpp +4 -9
  160. data/source/bzs/env/mbcswchrLinux.h +37 -34
  161. data/source/bzs/env/tcharMinGW.h +59 -0
  162. data/source/bzs/env/tstring.h +90 -95
  163. data/source/bzs/example/changeSchema.cpp +22 -23
  164. data/source/bzs/example/changeSchema_c.cpp +22 -24
  165. data/source/bzs/example/connection_pool_c.cpp +49 -104
  166. data/source/bzs/example/createDatabase.cpp +40 -47
  167. data/source/bzs/example/createDatabase_c.cpp +38 -43
  168. data/source/bzs/example/deleteRecords.cpp +10 -15
  169. data/source/bzs/example/deleteRecords_c.cpp +10 -14
  170. data/source/bzs/example/dropDatabase.cpp +3 -9
  171. data/source/bzs/example/dropDatabase_c.cpp +5 -6
  172. data/source/bzs/example/insertRecords.cpp +37 -29
  173. data/source/bzs/example/insertRecords_c.cpp +19 -25
  174. data/source/bzs/example/ormap_c.cpp +621 -0
  175. data/source/bzs/example/queryData.cpp +371 -0
  176. data/source/bzs/example/queryData.h +16 -0
  177. data/source/bzs/example/query_c.cpp +109 -0
  178. data/source/bzs/example/readRecords.cpp +27 -27
  179. data/source/bzs/example/readRecords_c.cpp +25 -23
  180. data/source/bzs/example/updateRecords.cpp +16 -21
  181. data/source/bzs/example/updateRecords_c.cpp +8 -12
  182. data/source/bzs/example/update_with_transaction.cpp +21 -24
  183. data/source/bzs/example/update_with_transaction_c.cpp +12 -15
  184. data/source/bzs/example/useORMRecord.cpp +177 -0
  185. data/source/bzs/netsvc/client/tcpClient.cpp +167 -156
  186. data/source/bzs/netsvc/client/tcpClient.h +541 -489
  187. data/source/bzs/netsvc/server/IAppModule.h +119 -32
  188. data/source/bzs/netsvc/server/iserver.h +21 -23
  189. data/source/bzs/netsvc/server/serverCpt.cpp +421 -391
  190. data/source/bzs/netsvc/server/serverCpt.h +41 -43
  191. data/source/bzs/netsvc/server/serverPipe.cpp +580 -565
  192. data/source/bzs/netsvc/server/serverPipe.h +44 -45
  193. data/source/bzs/netsvc/server/serverTpool.cpp +333 -303
  194. data/source/bzs/netsvc/server/serverTpool.h +38 -43
  195. data/source/bzs/rtl/benchmark.cpp +91 -31
  196. data/source/bzs/rtl/benchmark.h +76 -22
  197. data/source/bzs/rtl/datetime.cpp +231 -233
  198. data/source/bzs/rtl/datetime.h +16 -16
  199. data/source/bzs/rtl/debuglog.cpp +48 -51
  200. data/source/bzs/rtl/debuglog.h +55 -44
  201. data/source/bzs/rtl/exception.h +55 -48
  202. data/source/bzs/rtl/stl_uty.cpp +27 -28
  203. data/source/bzs/rtl/stl_uty.h +28 -29
  204. data/source/bzs/rtl/stringBuffers.cpp +8 -6
  205. data/source/bzs/rtl/stringBuffers.h +16 -9
  206. data/source/bzs/rtl/strtrim.cpp +90 -91
  207. data/source/bzs/rtl/strtrim.h +14 -16
  208. data/source/bzs/test/tdclatl/bench_query_atl.js +647 -0
  209. data/source/bzs/test/tdclatl/bench_tdclatl.js +303 -303
  210. data/source/bzs/test/tdclatl/test_query_atl.js +669 -0
  211. data/source/bzs/test/tdclphp/bench.php +357 -0
  212. data/source/bzs/test/tdclphp/transactd_Test.php +907 -303
  213. data/source/bzs/test/tdclphp/transactd_blob_Test.php +21 -49
  214. data/source/bzs/test/tdclphp/transactd_datetime_Test.php +41 -75
  215. data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +23 -37
  216. data/source/bzs/test/tdclphp/transactd_pool_Test.php +120 -0
  217. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +4 -6
  218. data/source/bzs/test/tdclrb/prepare.rb +15 -12
  219. data/source/bzs/test/tdclrb/transactd_blob_spec.rb +29 -32
  220. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +0 -29
  221. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +18 -19
  222. data/source/bzs/test/tdclrb/transactd_pool_spec.rb +107 -0
  223. data/source/bzs/test/tdclrb/transactd_spec.rb +734 -142
  224. data/source/bzs/test/transactdBench/query_bench.cpp +156 -0
  225. data/source/bzs/test/transactdBench/scaling_bench.cpp +265 -0
  226. data/source/bzs/test/transactdBench/transactdBench.cpp +107 -83
  227. data/source/bzs/test/transactdBench/transactdBench2.cpp +122 -83
  228. data/source/bzs/test/transactdBench/workerBase.cpp +5 -0
  229. data/source/bzs/test/transactdBench/workerBase.h +88 -0
  230. data/source/bzs/test/transactdBench/workerMySQLImple.h +333 -0
  231. data/source/bzs/test/transactdBench/workerTransactdImple.h +201 -0
  232. data/source/bzs/test/trdclengn/test_blob.cpp +121 -73
  233. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1244 -426
  234. data/source/global/ormsrcgen/confParam.h +80 -0
  235. data/source/global/ormsrcgen/fieldName.cpp +77 -0
  236. data/source/global/ormsrcgen/fieldName.h +43 -0
  237. data/source/global/ormsrcgen/main.cpp +196 -0
  238. data/source/global/ormsrcgen/srcgen.cpp +763 -0
  239. data/source/global/ormsrcgen/srcgen.h +72 -0
  240. data/source/global/ormsrcgen/template/fieldNameList_sample.txt +2 -0
  241. data/source/global/ormsrcgen/template/ormDataClass_template.cpp +48 -0
  242. data/source/global/ormsrcgen/template/ormDataClass_template.h +34 -0
  243. data/source/global/ormsrcgen/template/ormMapClass_template.cpp +51 -0
  244. data/source/global/ormsrcgen/template/ormMapClass_template.h +62 -0
  245. data/source/global/ormsrcgen/template/template.cnf +38 -0
  246. data/source/global/querystmts/querystmts.cpp +237 -0
  247. data/source/global/tdclatl/ConnectParams.cpp +77 -0
  248. data/source/global/tdclatl/ConnectParams.h +70 -0
  249. data/source/global/tdclatl/Database.cpp +132 -128
  250. data/source/global/tdclatl/Database.h +60 -49
  251. data/source/global/tdclatl/DbDef.cpp +68 -64
  252. data/source/global/tdclatl/DbDef.h +36 -36
  253. data/source/global/tdclatl/Field.cpp +12 -17
  254. data/source/global/tdclatl/Field.h +15 -12
  255. data/source/global/tdclatl/FieldDef.cpp +75 -36
  256. data/source/global/tdclatl/FieldDef.h +38 -19
  257. data/source/global/tdclatl/FieldDefs.cpp +74 -0
  258. data/source/global/tdclatl/FieldDefs.h +56 -0
  259. data/source/global/tdclatl/FieldNames.cpp +99 -0
  260. data/source/global/tdclatl/FieldNames.h +66 -0
  261. data/source/global/tdclatl/Flags.cpp +75 -37
  262. data/source/global/tdclatl/Flags.h +13 -12
  263. data/source/global/tdclatl/GroupQuery.cpp +119 -0
  264. data/source/global/tdclatl/GroupQuery.h +65 -0
  265. data/source/global/tdclatl/KeyDef.cpp +15 -14
  266. data/source/global/tdclatl/KeyDef.h +20 -17
  267. data/source/global/tdclatl/KeySegment.cpp +13 -12
  268. data/source/global/tdclatl/PooledDbManager.cpp +223 -0
  269. data/source/global/tdclatl/PooledDbManager.h +76 -0
  270. data/source/global/tdclatl/QueryBase.cpp +206 -127
  271. data/source/global/tdclatl/QueryBase.h +55 -59
  272. data/source/global/tdclatl/Record.cpp +214 -0
  273. data/source/global/tdclatl/Record.h +96 -0
  274. data/source/global/tdclatl/Recordset.cpp +278 -0
  275. data/source/global/tdclatl/Recordset.h +83 -0
  276. data/source/global/tdclatl/RecordsetQuery.cpp +118 -0
  277. data/source/global/tdclatl/RecordsetQuery.h +126 -0
  278. data/source/global/tdclatl/Table.cpp +57 -60
  279. data/source/global/tdclatl/Table.h +32 -29
  280. data/source/global/tdclatl/TableDef.cpp +63 -62
  281. data/source/global/tdclatl/TableDef.h +20 -22
  282. data/source/global/tdclatl/TdVersion.cpp +3 -3
  283. data/source/global/tdclatl/TdVersion.h +15 -11
  284. data/source/global/tdclatl/_IDatabaseEvents_CP.h +99 -92
  285. data/source/global/tdclatl/activeTable.cpp +355 -0
  286. data/source/global/tdclatl/activeTable.h +79 -0
  287. data/source/global/tdclatl/dllmain.cpp +4 -3
  288. data/source/global/tdclatl/dllmain.h +7 -6
  289. data/source/global/tdclatl/keySegment.h +22 -18
  290. data/source/global/tdclatl/resource.h +0 -0
  291. data/source/global/tdclatl/stdafx.h +6 -4
  292. data/source/global/tdclatl/targetver.h +0 -1
  293. data/source/global/tdclatl/tdclatl.cpp +10 -5
  294. data/source/global/tdclatl/tdclatl.idl +530 -14
  295. data/source/linux/charsetConvert.h +78 -79
  296. data/source/linux/linuxTypes.h +9 -12
  297. data/source/linux/tchar.h +168 -166
  298. data/transactd.gemspec +24 -16
  299. metadata +98 -12
  300. data/bin/common/tdclc_32_1_2.dll +0 -0
  301. data/bin/common/tdclc_64_1_2.dll +0 -0
  302. data/build/tdclc/tdclc_32.cbproj +0 -173
  303. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +0 -232
  304. data/build/tdclrb/GEM_VERSION +0 -3
  305. data/source/bzs/db/protocol/tdap/client/filter.cpp +0 -43
  306. data/source/bzs/example/useORM.cpp +0 -585
@@ -16,32 +16,24 @@
16
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
17
  02111-1307, USA.
18
18
  ================================================================= */
19
- #include <bzs/env/tstring.h>
20
- #pragma hdrstop
21
19
 
22
20
  #include "table.h"
21
+ #include "field.h"
22
+ #include "fields.h"
23
23
  #include "filter.h"
24
24
  #include "database.h"
25
25
  #include "bulkInsert.h"
26
- #include "stringConverter.h"
27
26
  #include <bzs/rtl/strtrim.h>
28
- #include <bzs/rtl/stringBuffers.h>
29
27
  #include <bzs/db/protocol/tdap/myDateTime.cpp>
30
28
  #include <bzs/db/blobStructs.h>
31
- #include <vector>
32
- #include <algorithm>
29
+ #include <bzs/rtl/stringBuffers.h>
30
+ #include "stringConverter.h"
33
31
  #include <boost/timer.hpp>
34
- #include <boost/shared_array.hpp>
35
32
 
36
33
  #pragma package(smart_init)
37
34
 
38
- #ifdef __BCPLUSPLUS__
39
- #define _strupr strupr
40
- #endif
41
-
42
35
  using namespace bzs::db;
43
36
  using namespace bzs::rtl;
44
- using namespace bzs::db::protocol::tdap;
45
37
 
46
38
  namespace bzs
47
39
  {
@@ -64,32 +56,20 @@ namespace client
64
56
  #define EXEC_CODEPAGE CP_UTF8
65
57
  #endif
66
58
 
67
-
68
- class CFiledNameIndex
69
- {
70
-
71
- public:
72
- CFiledNameIndex(short i, std::_tstring n);
73
- bool operator < (const CFiledNameIndex& rt) const ;
74
-
75
- short index;
76
-
77
- std::_tstring name;
78
- };
79
-
80
59
  class recordCache;
81
60
 
82
-
83
61
  struct tbimpl
84
62
  {
85
- stringConverter* cv;
63
+
86
64
  void* bookMarks;
65
+ client::fields fields;
87
66
  filter* filterPtr;
88
67
  recordCache* rc;
68
+ multiRecordAlocator* mraPtr;
89
69
  void* dataBak;
90
70
  void* smartUpDate;
91
71
  void* bfAtcPtr;
92
- void* optionalData;
72
+ void* optionalData;
93
73
  int bookMarksMemSize;
94
74
  int maxBookMarkedCount;
95
75
  char keybuf[MAX_KEYLEN];
@@ -99,31 +79,22 @@ struct tbimpl
99
79
 
100
80
  struct
101
81
  {
102
- unsigned char exBookMarking : 1;
103
- unsigned char myDateTimeValueByBtrv: 1;
104
- unsigned char trimPadChar: 1;
105
- unsigned char usePadChar: 1;
106
- unsigned char smartUpDateFlag: 1;
107
- unsigned char logicalToString: 1;
108
- unsigned char dataPacked: 1;
82
+ unsigned char exBookMarking : 1;
83
+ unsigned char smartUpDateFlag : 1;
84
+ unsigned char dataPacked : 1;
109
85
  };
110
86
 
111
- std::vector<boost::shared_array<char> >blobs;
112
- ::bzs::rtl::stringBuffer strBufs;
113
- std::vector<CFiledNameIndex>fields;
114
-
115
- tbimpl() : strBufs(4096), bookMarks(NULL),bfAtcPtr(NULL), maxBookMarkedCount(0), bookMarksMemSize(0),
116
- filterPtr(NULL), rc(NULL), dataBak(NULL), optionalData(NULL),myDateTimeValueByBtrv(true), trimPadChar(true),
117
- usePadChar(true), smartUpDate(NULL), smartUpDateFlag(false)
118
- , logicalToString(false),dataPacked(false)
87
+ tbimpl(table& tb)
88
+ : bookMarks(NULL), fields(tb), filterPtr(NULL), rc(NULL), mraPtr(NULL),
89
+ dataBak(NULL), smartUpDate(NULL), bfAtcPtr(NULL), optionalData(NULL),
90
+ bookMarksMemSize(0), maxBookMarkedCount(0), smartUpDateFlag(false),
91
+ dataPacked(false)
119
92
  {
120
93
  memset(&keyNumIndex[0], 0, 128);
121
-
122
94
  }
123
95
 
124
96
  ~tbimpl()
125
97
  {
126
-
127
98
  if (dataBak)
128
99
  free(dataBak);
129
100
  if (smartUpDate)
@@ -139,7 +110,7 @@ struct tbimpl
139
110
  // class recordCache
140
111
  // ---------------------------------------------------------------------------
141
112
 
142
- unsigned int hash(const char *s, int len)
113
+ unsigned int hash(const char* s, int len)
143
114
  {
144
115
  unsigned int h = 0;
145
116
  for (int i = 0; i < len; i++)
@@ -156,13 +127,17 @@ class recordCache
156
127
  unsigned int m_unpackLen;
157
128
  unsigned int m_rowCount;
158
129
  bookmark_td m_bookmark;
159
- char* m_ptr;
160
- char* m_tmpPtr;
130
+ uchar_td* m_ptr;
131
+ uchar_td* m_tmpPtr;
161
132
  blobHeader* m_hd;
162
133
  short_td m_seekMultiStat;
134
+ int m_memblockType;
163
135
 
164
136
  public:
165
- inline recordCache(table* tb) : m_tb(tb) {reset();}
137
+ inline recordCache(table* tb) : m_tb(tb), m_memblockType(mra_first)
138
+ {
139
+ reset();
140
+ }
166
141
 
167
142
  inline void reset()
168
143
  {
@@ -172,66 +147,140 @@ public:
172
147
  m_ptr = NULL;
173
148
  m_len = 0;
174
149
  m_tmpPtr = NULL;
150
+ m_memblockType = mra_first;
151
+ }
152
+
153
+ inline void setMemblockType(int v) { m_memblockType = v; }
154
+
155
+ inline void hasManyJoin(int rowCount, uchar_td* data)
156
+ {
157
+ int rowOffset = 0;
158
+ int row = 0; // zero start
159
+ int count = 0;
160
+ char* ptr = (char*)data + DATASIZE_BYTE; // rowCount
161
+ unsigned short len = 0;
162
+ for (int i = 0; i < (int)rowCount; ++i)
163
+ {
164
+ ptr += len;
165
+ len = *((unsigned short*)ptr);
166
+ ptr += DATASIZE_BYTE;
167
+
168
+ // get sequential number
169
+ int tmp = *((int*)(ptr));
170
+ ptr += sizeof(int);
171
+ // If len == 0 then next first record read error
172
+ if ((len == 0) || (tmp != row))
173
+ {
174
+ if (count)
175
+ {
176
+ m_tb->m_impl->mraPtr->duplicateRow(row + rowOffset, count);
177
+ rowOffset += count;
178
+ }
179
+ ++row;
180
+ count = 0;
181
+ }
182
+ else if (i != 0)
183
+ ++count;
184
+ }
185
+ if (count)
186
+ m_tb->m_impl->mraPtr->duplicateRow(row + rowOffset, count);
175
187
  }
176
188
 
177
- inline void reset(filter* p, char* data, unsigned int totalSize, const blobHeader* hd)
189
+ inline void reset(filter* p, uchar_td* data, unsigned int totalSize,
190
+ const blobHeader* hd)
178
191
  {
179
192
  m_pFilter = p;
180
193
  m_row = 0;
181
194
  m_rowCount = *((unsigned short*)data);
182
195
  m_ptr = data + DATASIZE_BYTE;
183
- m_len = m_unpackLen = *((unsigned short*)m_ptr); // Not include bookmark and size bytes.
196
+ m_len = m_unpackLen =
197
+ *((unsigned short*)m_ptr); // Not include bookmark and size bytes.
184
198
  m_ptr += DATASIZE_BYTE;
185
- m_bookmark = *((bookmark_td*)(m_ptr));
186
- m_ptr += BOOKMARK_SIZE;
199
+ if (m_pFilter->bookmarkSize())
200
+ {
201
+ m_bookmark = *((bookmark_td*)(m_ptr));
202
+ m_ptr += m_pFilter->bookmarkSize();
203
+ }
187
204
  m_tmpPtr = data + totalSize;
205
+ if (m_tb->m_impl->mraPtr)
206
+ {
207
+ if (m_pFilter->hasManyJoin())
208
+ hasManyJoin(m_rowCount, data);
209
+ size_t recordLen = m_pFilter->fieldSelected()
210
+ ? m_pFilter->totalFieldLen()
211
+ : m_tb->tableDef()->maxRecordLen;
212
+ m_tb->m_impl->mraPtr->init(m_rowCount, recordLen, m_memblockType,
213
+ m_tb);
214
+ }
188
215
  m_hd = const_cast<blobHeader*>(hd);
189
216
  }
190
217
 
191
- inline const char* moveRow(int count)
218
+ inline const uchar_td* moveRow(int count)
192
219
  {
220
+ // move row data address pointer in result buffer
193
221
  for (int i = 0; i < count; i++)
194
222
  {
195
223
  m_ptr += m_len;
196
224
  m_len = m_unpackLen = *((unsigned short*)m_ptr);
197
225
  m_ptr += DATASIZE_BYTE;
198
- m_bookmark = *((bookmark_td*)(m_ptr));
199
- m_ptr += BOOKMARK_SIZE;
226
+ if (m_pFilter->bookmarkSize())
227
+ {
228
+ m_bookmark = *((bookmark_td*)(m_ptr));
229
+ m_ptr += m_pFilter->bookmarkSize();
230
+ }
200
231
  }
201
232
  if (m_hd)
202
233
  {
203
- //blob pointer is allready point to next row
234
+ // blob pointer is allready point to next row
204
235
  while (m_row - m_hd->curRow)
205
236
  {
206
- for(int j=0;j<m_hd->fieldCount;++j)
237
+ for (int j = 0; j < m_hd->fieldCount; ++j)
207
238
  m_hd->nextField = (blobField*)m_hd->nextField->next();
208
239
  ++m_hd->curRow;
209
240
  }
210
241
  }
211
242
 
212
- m_tb->m_impl->strBufs.clear();
243
+ multiRecordAlocator* mra = m_tb->m_impl->mraPtr;
213
244
 
214
- if ((m_len==0) && m_pFilter->isSeeksMode() && m_pFilter->fieldCount())
245
+ m_tb->m_fddefs->strBufs()->clear();
246
+
247
+ if ((m_len == 0) && m_pFilter->isSeeksMode() && m_pFilter->fieldCount())
215
248
  {
216
249
  /*seek error*/
217
- m_seekMultiStat = m_bookmark;
218
- m_bookmark = 0;
219
- memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
250
+ m_seekMultiStat = STATUS_NOT_FOUND_TI;
251
+ if (mra)
252
+ {
253
+ m_tmpPtr = mra->ptr(m_row, mra_current_block);
254
+ mra->setInvalidRecord(m_row, true);
255
+ }
256
+ else
257
+ memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
220
258
  return m_tmpPtr;
221
- }else
259
+ }
260
+ else
222
261
  m_seekMultiStat = 0;
223
262
 
263
+ if (mra)
264
+ m_tmpPtr = mra->ptr(m_row, mra_current_block);
265
+
224
266
  if (m_pFilter->fieldSelected())
225
267
  {
226
- int offset = 0;
227
- memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
268
+ int resultOffset = 0;
269
+ uchar_td* fieldPtr = m_ptr;
270
+ if (!mra)
271
+ memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
228
272
  for (int i = 0; i < m_pFilter->fieldCount(); i++)
229
273
  {
230
- memcpy((char*)m_tmpPtr + m_pFilter->fieldOffset(i), m_ptr + offset,
231
- m_pFilter->fieldLen(i));
232
- offset += m_pFilter->fieldLen(i);
274
+ const fielddef& fd =
275
+ m_tb->tableDef()
276
+ ->fieldDefs[m_pFilter->selectFieldIndexes()[i]];
277
+ if (!mra)
278
+ resultOffset = fd.pos;
279
+ fieldPtr += fd.unPackCopy(m_tmpPtr + resultOffset, fieldPtr);
280
+ if (mra)
281
+ resultOffset += fd.len;
233
282
  }
234
- m_tb->setBlobFieldPointer(m_tmpPtr, m_hd);
283
+ m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
235
284
  return m_tmpPtr;
236
285
  }
237
286
  else if (m_tb->valiableFormatType())
@@ -239,17 +288,24 @@ public:
239
288
  memset(m_tmpPtr, 0, m_tb->tableDef()->maxRecordLen);
240
289
  memcpy(m_tmpPtr, m_ptr, m_len);
241
290
  m_unpackLen = m_tb->unPack((char*)m_tmpPtr, m_len);
242
- m_tb->setBlobFieldPointer(m_tmpPtr, m_hd);
291
+ m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
243
292
  return m_tmpPtr;
244
293
  }
245
294
  else
246
295
  {
247
- m_tb->setBlobFieldPointer(m_ptr, m_hd);
296
+ if (mra)
297
+ {
298
+ memcpy(m_tmpPtr, m_ptr, m_len);
299
+ m_tb->setBlobFieldPointer((char*)m_tmpPtr, m_hd);
300
+ return m_tmpPtr;
301
+ }
302
+ else
303
+ m_tb->setBlobFieldPointer((char*)m_ptr, m_hd);
248
304
  return m_ptr;
249
305
  }
250
306
  }
251
307
 
252
- inline const char* setRow(unsigned int rowNum)
308
+ inline const uchar_td* setRow(unsigned int rowNum)
253
309
  {
254
310
  if (rowNum < m_rowCount)
255
311
  {
@@ -260,125 +316,26 @@ public:
260
316
  return NULL;
261
317
  }
262
318
 
263
- inline unsigned int len() const {return m_unpackLen;};
264
- inline bookmark_td bookmarkCurRow() const {return m_bookmark;};
265
- inline int row() const {return m_row;}
266
-
267
- inline int rowCount() const {return m_rowCount;}
268
- inline bool isEndOfRow(unsigned int row) const {return (m_rowCount && (row == m_rowCount));}
269
- inline bool withinCache(unsigned int row) const {return (row < m_rowCount);}
270
- inline short_td seekMultiStat(){return m_seekMultiStat;}
271
- };
272
-
273
- // ---------------------------------------------------------------------------
274
- // class CFiledNameIndex
275
- // ---------------------------------------------------------------------------
276
- CFiledNameIndex::CFiledNameIndex(short i, std::_tstring n) : index(i), name(n)
277
- {
278
-
279
- }
280
-
281
- bool CFiledNameIndex:: operator < (const CFiledNameIndex& rt) const
282
- {
283
- return name < rt.name;
284
- };
285
-
319
+ inline unsigned int len() const { return m_unpackLen; };
320
+ inline bookmark_td bookmarkCurRow() const { return m_bookmark; };
321
+ inline int row() const { return m_row; }
286
322
 
287
- inline __int64 getValue64(const fielddef& fd, const uchar_td* ptr)
288
- {
289
- __int64 ret = 0;
290
- switch (fd.type)
323
+ inline int rowCount() const { return m_rowCount; }
324
+ inline bool isEndOfRow(unsigned int row) const
291
325
  {
292
- case ft_integer:
293
- case ft_autoinc:
294
- switch (fd.len)
295
- {
296
- case 1: ret = *((char*)(ptr + fd.pos));
297
- break;
298
- case 2: ret = *((short*)(ptr + fd.pos));
299
- break;
300
- case 4: ret = *((int*)(ptr + fd.pos));
301
- break;
302
- case 8: ret = *((__int64*)(ptr + fd.pos));
303
- break;
304
- }
305
- case ft_autoIncUnsigned:
306
- case ft_uinteger:
307
- case ft_logical:
308
- case ft_bit:
309
- case ft_currency:
310
- case ft_date:
311
- case ft_time:
312
- case ft_timestamp:
313
- case ft_mydate:
314
- case ft_mytime:
315
- case ft_mydatetime:
316
- case ft_mytimestamp:
317
- switch (fd.len)
318
- {
319
- case 1: ret = *((unsigned char*)(ptr + fd.pos));
320
- break;
321
- case 2: ret = *((unsigned short*)(ptr + fd.pos));
322
- break;
323
- case 4: ret = *((unsigned int*)(ptr + fd.pos));
324
- break;
325
- case 3:
326
- case 5:
327
- case 6:
328
- case 7: memcpy(&ret, ptr + fd.pos, fd.len);
329
- break;
330
- case 8: ret = *((__int64*)(ptr + fd.pos));
331
- break;
332
- }
326
+ return (m_rowCount && (row == m_rowCount));
333
327
  }
334
- return ret;
335
- }
336
-
337
- inline void setValue(const fielddef& fd, uchar_td* ptr, __int64 value)
338
- {
339
- switch (fd.type)
328
+ inline bool withinCache(unsigned int row) const
340
329
  {
341
- case ft_integer:
342
- case ft_autoinc:
343
- {
344
- switch (fd.len)
345
- {
346
- case 1: *((char*)(ptr + fd.pos)) = (char)value;
347
- break;
348
- case 2: *((short*)(ptr + fd.pos)) = (short)value;
349
- break;
350
- case 4: *((int*)(ptr + fd.pos)) = (int)value;
351
- break;
352
- case 8: *((__int64*)(ptr + fd.pos)) = value;
353
- break;
354
- }
355
- }
356
- case ft_autoIncUnsigned:
357
- case ft_uinteger:
358
- case ft_logical:
359
- case ft_bit:
360
- case ft_currency:
361
- case ft_date:
362
- case ft_time:
363
- case ft_timestamp:
364
- case ft_mytime:
365
- case ft_mydate:
366
- case ft_mydatetime:
367
- case ft_mytimestamp:
368
- memcpy(ptr + fd.pos, &value, fd.len);
369
- break;
330
+ return (row < m_rowCount);
370
331
  }
371
- }
372
-
373
-
374
-
375
-
332
+ inline short_td seekMultiStat() { return m_seekMultiStat; }
333
+ };
376
334
 
377
- table::table(nsdatabase *pbe) : nstable(pbe)
335
+ table::table(nsdatabase* pbe) : nstable(pbe)
378
336
  {
379
- m_impl = new tbimpl();
380
-
381
- m_impl->cv = new stringConverter(nsdatabase::execCodePage(), nsdatabase::execCodePage());
337
+ m_fddefs = fielddefs::create();
338
+ m_impl = new tbimpl(*this);
382
339
 
383
340
  m_impl->rc = new recordCache(this);
384
341
 
@@ -386,60 +343,123 @@ table::table(nsdatabase *pbe) : nstable(pbe)
386
343
  m_pdata = NULL;
387
344
  m_keybuf = &m_impl->keybuf[0];
388
345
  m_keynum = 0;
389
-
390
346
  }
391
347
 
392
348
  table::~table()
393
349
  {
394
350
  delete m_impl->rc;
395
- delete m_impl->cv;
351
+ m_fddefs->release();
396
352
  delete m_impl;
353
+ }
354
+
355
+ void table::setMra(multiRecordAlocator* p)
356
+ {
357
+ m_impl->mraPtr = p;
358
+ }
397
359
 
360
+ multiRecordAlocator* table::mra() const
361
+ {
362
+ return m_impl->mraPtr;
398
363
  }
399
364
 
400
- inline uchar_td table::charset() const {return m_tableDef->charsetIndex;};
365
+ uchar_td table::charset() const
366
+ {
367
+ return m_tableDef->charsetIndex;
368
+ };
369
+
370
+ bool table::trimPadChar() const
371
+ {
372
+ return m_fddefs->trimPadChar;
373
+ }
401
374
 
402
- bool table::trimPadChar() const {return m_impl->trimPadChar;}
375
+ void table::setTrimPadChar(bool v)
376
+ {
377
+ m_fddefs->trimPadChar = v;
378
+ }
403
379
 
404
- void table::setTrimPadChar(bool v) {m_impl->trimPadChar = v;}
380
+ bool table::usePadChar() const
381
+ {
382
+ return m_fddefs->usePadChar;
383
+ };
405
384
 
406
- bool table::usePadChar() const {return m_impl->usePadChar;};
385
+ void table::setUsePadChar(bool v)
386
+ {
387
+ m_fddefs->usePadChar = v;
388
+ };
407
389
 
408
- void table::setUsePadChar(bool v) {m_impl->usePadChar = v;};
390
+ void* table::dataBak() const
391
+ {
392
+ return m_impl->dataBak;
393
+ };
409
394
 
410
- void* table::dataBak() const {return m_impl->dataBak;};
395
+ void table::setDataBak(void* v)
396
+ {
397
+ m_impl->dataBak = v;
398
+ };
411
399
 
412
- void table::setDataBak(void* v) {m_impl->dataBak = v;};
400
+ void* table::optionalData() const
401
+ {
402
+ return m_impl->optionalData;
403
+ }
413
404
 
414
- void* table::optionalData() const {return m_impl->optionalData;}
405
+ void table::setOptionalData(void* v)
406
+ {
407
+ m_impl->optionalData = v;
408
+ }
415
409
 
416
- void table::setOptionalData(void* v) {m_impl->optionalData = v;}
410
+ bool table::myDateTimeValueByBtrv() const
411
+ {
412
+ return m_fddefs->myDateTimeValueByBtrv;
413
+ }
417
414
 
418
- bool table::myDateTimeValueByBtrv() const {return m_impl->myDateTimeValueByBtrv;}
415
+ bool table::logicalToString() const
416
+ {
417
+ return m_fddefs->logicalToString;
418
+ };
419
419
 
420
- bool table::logicalToString() const {return m_impl->logicalToString;};
420
+ void table::setLogicalToString(bool v)
421
+ {
422
+ m_fddefs->logicalToString = v;
423
+ }
421
424
 
422
- void table::setLogicalToString(bool v) {m_impl->logicalToString = v;}
425
+ fields& table::fields()
426
+ {
427
+ return m_impl->fields;
428
+ }
423
429
 
424
430
  void table::setBookMarks(int StartId, void* Data, ushort_td Count)
425
431
  {
426
432
  long size = (StartId + Count) * 6;
433
+
434
+ if (!m_impl->bookMarks)
435
+ {
436
+ m_impl->bookMarks = malloc(BOOKMARK_ALLOC_SIZE);
437
+ if (m_impl->bookMarks)
438
+ m_impl->bookMarksMemSize = BOOKMARK_ALLOC_SIZE;
439
+ else
440
+ {
441
+ m_stat = STATUS_CANT_ALLOC_MEMORY;
442
+ return;
443
+ }
444
+ }
445
+
427
446
  if (m_impl->bookMarksMemSize < size)
428
447
  {
429
448
 
430
- m_impl->bookMarks = realloc(m_impl->bookMarks, size + BOOKMARK_ALLOC_SIZE);
449
+ m_impl->bookMarks =
450
+ realloc(m_impl->bookMarks, size + BOOKMARK_ALLOC_SIZE);
431
451
  m_impl->bookMarksMemSize = size + BOOKMARK_ALLOC_SIZE;
432
452
  }
433
453
  if (m_impl->bookMarks)
434
454
  {
435
455
  if (StartId + Count - 1 > m_impl->maxBookMarkedCount)
436
456
  m_impl->maxBookMarkedCount = StartId + Count - 1;
437
- memcpy((void*)((char*)m_impl->bookMarks + ((StartId - 1) * 6)), Data, Count * 6);
457
+ memcpy((void*)((char*)m_impl->bookMarks + ((StartId - 1) * 6)), Data,
458
+ Count * 6);
438
459
  }
439
460
  else
440
461
  m_stat = STATUS_CANT_ALLOC_MEMORY;
441
462
  return;
442
-
443
463
  }
444
464
 
445
465
  inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
@@ -457,16 +477,18 @@ inline short calcNextReadRecordCount(ushort_td curCount, int eTime)
457
477
  return ret;
458
478
  }
459
479
 
460
- uint_td table::doRecordCount(bool estimate, bool fromCurrent, eFindType direction)
480
+ uint_td table::doRecordCount(bool estimate, bool fromCurrent)
461
481
  {
462
482
  uint_td result = 0;
463
483
 
464
484
  if (m_impl->filterPtr)
465
485
  {
466
- short_td op = (direction == findForword) ? TD_KEY_NEXT_MULTI:TD_KEY_PREV_MULTI;
486
+ short_td op = (m_impl->filterPtr->direction() == findForword)
487
+ ? TD_KEY_NEXT_MULTI
488
+ : TD_KEY_PREV_MULTI;
467
489
 
468
490
  if (tableDef()->keyCount == 0)
469
- op += TD_POS_NEXT_MULTI - TD_KEY_NEXT_MULTI;// KEY to POS
491
+ op += TD_POS_NEXT_MULTI - TD_KEY_NEXT_MULTI; // KEY to POS
470
492
  short curStat = m_stat;
471
493
  m_impl->exBookMarking = true;
472
494
  ushort_td recCountOnce = 100;
@@ -496,11 +518,13 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent, eFindType directio
496
518
  boost::timer t;
497
519
  btrvGetExtend(op);
498
520
  int eTime = (int)(t.elapsed() * 1000);
499
- while ((m_stat == 0) || (m_stat == STATUS_LIMMIT_OF_REJECT) || (m_stat == STATUS_EOF)
500
- || (m_stat == STATUS_REACHED_FILTER_COND))
521
+ while ((m_stat == 0) || (m_stat == STATUS_LIMMIT_OF_REJECT) ||
522
+ (m_stat == STATUS_EOF) ||
523
+ (m_stat == STATUS_REACHED_FILTER_COND))
501
524
  {
502
525
  bool Complete = false;
503
- if ((m_stat == STATUS_EOF) || (m_stat == STATUS_REACHED_FILTER_COND))
526
+ if ((m_stat == STATUS_EOF) ||
527
+ (m_stat == STATUS_REACHED_FILTER_COND))
504
528
  {
505
529
  Complete = true;
506
530
  m_stat = STATUS_EOF;
@@ -517,8 +541,9 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent, eFindType directio
517
541
  recCountOnce = calcNextReadRecordCount(recCountOnce, eTime);
518
542
  m_impl->filterPtr->setMaxRows(recCountOnce);
519
543
  result += *((ushort_td*)m_impl->dataBak);
520
- setBookMarks(m_impl->maxBookMarkedCount + 1, (void*)((char*)m_impl->dataBak + 2),
521
- *((ushort_td*)m_impl->dataBak));
544
+ setBookMarks(m_impl->maxBookMarkedCount + 1,
545
+ (void*)((char*)m_impl->dataBak + 2),
546
+ *((ushort_td*)m_impl->dataBak));
522
547
  m_impl->maxBookMarkedCount = result;
523
548
  onRecordCounting(result, Complete);
524
549
  if (Complete)
@@ -542,7 +567,7 @@ uint_td table::doRecordCount(bool estimate, bool fromCurrent, eFindType directio
542
567
  m_stat = 0;
543
568
  }
544
569
  else
545
- return nstable::doRecordCount(estimate, fromCurrent, direction);
570
+ return nstable::doRecordCount(estimate, fromCurrent);
546
571
 
547
572
  return result;
548
573
  }
@@ -561,30 +586,37 @@ void table::btrvGetExtend(ushort_td op)
561
586
  }
562
587
  m_datalen = m_impl->filterPtr->exDataBufLen();
563
588
 
564
- //cacheing direction
565
- if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI)|| (op == TD_POS_PREV_MULTI))
589
+ // cacheing direction
590
+ if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI) ||
591
+ (op == TD_POS_PREV_MULTI))
566
592
  m_impl->filterPtr->setDirection(findBackForword);
567
593
  else
568
594
  m_impl->filterPtr->setDirection(findForword);
569
595
 
570
596
  tdap(op);
597
+ if (m_stat && (m_stat != STATUS_LIMMIT_OF_REJECT) &&
598
+ (m_stat != STATUS_REACHED_FILTER_COND) && (m_stat != STATUS_EOF))
599
+ return;
571
600
  short stat = m_stat;
572
- if (!m_impl->filterPtr->isWriteComleted() && (stat == STATUS_REACHED_FILTER_COND))
601
+ if (!m_impl->filterPtr->isWriteComleted() &&
602
+ (stat == STATUS_REACHED_FILTER_COND))
573
603
  stat = STATUS_LIMMIT_OF_REJECT;
574
604
 
575
- m_impl->rc->reset(m_impl->filterPtr, (char*)m_impl->dataBak, m_datalen, blobFieldUsed() ?
576
- getBlobHeader() : NULL);
605
+ m_impl->rc->reset(m_impl->filterPtr, (uchar_td*)m_impl->dataBak, m_datalen,
606
+ blobFieldUsed() ? getBlobHeader() : NULL);
577
607
 
578
608
  m_stat = stat;
579
609
  m_impl->exSlideStat = m_stat;
580
- //There is the right record.
610
+ // There is the right record.
581
611
  if (m_impl->rc->rowCount() && (!m_impl->exBookMarking))
582
612
  {
583
613
  m_pdata = (void*)m_impl->rc->setRow(0);
584
- m_datalen = tableDef()->maxRecordLen;//m_impl->rc->len();
614
+ m_datalen = tableDef()->maxRecordLen;
585
615
 
586
616
  m_stat = m_impl->rc->seekMultiStat();
587
- }else if ((m_stat == STATUS_LIMMIT_OF_REJECT) && (m_impl->filterPtr->rejectCount()>=1))
617
+ }
618
+ else if ((m_stat == STATUS_LIMMIT_OF_REJECT) &&
619
+ (m_impl->filterPtr->rejectCount() >= 1))
588
620
  m_stat = STATUS_EOF;
589
621
  }
590
622
 
@@ -595,8 +627,10 @@ void table::getRecords(ushort_td op)
595
627
  btrvGetExtend(op);
596
628
  m_impl->filterPtr->setPosTypeNext(true);
597
629
 
598
- }while (m_stat == STATUS_LIMMIT_OF_REJECT && (m_impl->filterPtr->rejectCount()==0));
599
- if ((m_stat == STATUS_REACHED_FILTER_COND) || (m_stat == STATUS_LIMMIT_OF_REJECT))
630
+ } while (m_stat == STATUS_LIMMIT_OF_REJECT &&
631
+ (m_impl->filterPtr->rejectCount() == 0));
632
+ if ((m_stat == STATUS_REACHED_FILTER_COND) ||
633
+ (m_stat == STATUS_LIMMIT_OF_REJECT))
600
634
  m_stat = STATUS_EOF;
601
635
  }
602
636
 
@@ -606,11 +640,112 @@ bookmark_td table::bookmarkFindCurrent() const
606
640
  if (!m_impl->rc->isEndOfRow(m_impl->rc->row()))
607
641
  return m_impl->rc->bookmarkCurRow();
608
642
  return 0;
643
+ }
644
+
645
+ inline bool checkStatus(short v)
646
+ {
647
+ return ((v == STATUS_SUCCESS) || (v == STATUS_NOT_FOUND_TI) ||
648
+ (v == STATUS_EOF));
649
+ }
650
+
651
+ bool table::doSeekMultiAfter(int row)
652
+ {
653
+ const std::vector<short>& fields = m_impl->filterPtr->selectFieldIndexes();
654
+
655
+ if (m_stat == STATUS_SUCCESS)
656
+ onReadAfter();
657
+ else if (!checkStatus(m_stat))
658
+ return false;
659
+ if (m_stat)
660
+ m_impl->mraPtr->setInvalidRecord(row, true);
661
+ else
662
+ {
663
+ uchar_td* dst = m_impl->mraPtr->ptr(row, mra_current_block);
664
+ if (m_impl->filterPtr->fieldSelected())
665
+ {
666
+ int resultOffset = 0;
667
+
668
+ for (int j = 0; j < (int)fields.size(); ++j)
669
+ {
670
+ fielddef* fd = &tableDef()->fieldDefs[fields[j]];
671
+ fd->unPackCopy(dst + resultOffset,
672
+ ((uchar_td*)m_pdata) + fd->pos);
673
+ dst += fd->len;
674
+ }
675
+ }
676
+ else
677
+ memcpy(dst, (uchar_td*)m_pdata, m_datalen);
678
+ }
679
+ return true;
680
+ }
681
+
682
+ void table::btrvSeekMulti()
683
+ {
684
+ const std::vector<client::seek>& seeks = m_impl->filterPtr->seeks();
685
+ const bool transactd = false;
686
+ bool hasManyJoin = m_impl->filterPtr->hasManyJoin();
687
+
688
+ m_impl->rc->reset();
689
+ size_t recordLen = m_impl->filterPtr->fieldSelected()
690
+ ? m_impl->filterPtr->totalSelectFieldLen()
691
+ : tableDef()->maxRecordLen;
692
+ if (!hasManyJoin)
693
+ m_impl->mraPtr->init(seeks.size(), recordLen, mra_first, this);
694
+
695
+ m_keylen = m_keybuflen;
696
+ m_datalen = m_buflen;
697
+ int type = mra_first;
698
+ int rowOffset = 0;
699
+ for (int i = 0; i < (int)seeks.size(); ++i)
700
+ {
701
+ // 100% need allocate each row
702
+ m_impl->mraPtr->init(1, recordLen, type, this);
703
+ type = mra_nextrows;
704
+ seeks[i].writeBuffer((uchar_td*)m_impl->keybuf, false, true, transactd);
705
+ if (hasManyJoin)
706
+ {
707
+ tdap((ushort_td)(TD_KEY_OR_AFTER));
708
+ if (!checkStatus(m_stat))
709
+ return;
609
710
 
711
+ if (memcmp(seeks[i].data, m_impl->keybuf, seeks[i].len) == 0)
712
+ {
713
+ doSeekMultiAfter(0);
714
+ while (m_stat == 0)
715
+ {
716
+ tdap((ushort_td)(TD_KEY_NEXT));
717
+ if (!checkStatus(m_stat))
718
+ return;
719
+ if (memcmp(seeks[i].data, m_impl->keybuf, seeks[i].len) !=
720
+ 0)
721
+ break;
722
+ m_impl->mraPtr->duplicateRow(i + rowOffset, 1);
723
+ ++rowOffset;
724
+ m_impl->mraPtr->removeLastMemBlock(i + rowOffset);
725
+ m_impl->mraPtr->init(1, recordLen, type, this);
726
+ doSeekMultiAfter(0);
727
+ }
728
+ }
729
+ else
730
+ m_impl->mraPtr->setInvalidRecord(0, true);
731
+ }
732
+ else
733
+ {
734
+ tdap((ushort_td)(TD_KEY_SEEK));
735
+ if (!doSeekMultiAfter(i))
736
+ return;
737
+ }
738
+ }
739
+ m_stat = STATUS_EOF;
610
740
  }
611
741
 
612
742
  void table::find(eFindType type)
613
743
  {
744
+ if (!m_impl->filterPtr)
745
+ {
746
+ m_stat = STATUS_FILTERSTRING_ERROR;
747
+ return;
748
+ }
614
749
  ushort_td op;
615
750
 
616
751
  if (m_impl->filterPtr->isSeeksMode())
@@ -619,26 +754,30 @@ void table::find(eFindType type)
619
754
  op = TD_KEY_SEEK_MULTI;
620
755
  }
621
756
  else
622
- op = (type == findForword) ? TD_KEY_GE_NEXT_MULTI:TD_KEY_LE_PREV_MULTI;
757
+ op =
758
+ (type == findForword) ? TD_KEY_GE_NEXT_MULTI : TD_KEY_LE_PREV_MULTI;
623
759
 
624
- if (nsdb()->isUseTransactd())
760
+ if (isUseTransactd())
625
761
  {
626
762
  m_impl->rc->reset();
627
- doFind(op, true/*notIncCurrent*/);
763
+ doFind(op, true /*notIncCurrent*/);
628
764
  }
629
765
  else
630
766
  {
631
-
632
767
  if (op == TD_KEY_SEEK_MULTI)
633
768
  {
634
- //P.SQL not support TD_KEY_SEEK_MULTI
635
- m_stat = STATUS_FILTERSTRING_ERROR;
769
+
770
+ if (m_impl->mraPtr)
771
+ btrvSeekMulti();
772
+ else
773
+ m_stat = STATUS_FILTERSTRING_ERROR; // P.SQL not support
774
+ // TD_KEY_SEEK_MULTI
636
775
  return;
637
776
  }
638
777
  if (type == findForword)
639
- seekGreater(false);
778
+ seekGreater(true);
640
779
  else
641
- seekLessThan(false);
780
+ seekLessThan(true);
642
781
  if (m_stat == 0)
643
782
  {
644
783
  if (type == findForword)
@@ -647,8 +786,6 @@ void table::find(eFindType type)
647
786
  findPrev(false);
648
787
  }
649
788
  }
650
-
651
-
652
789
  }
653
790
 
654
791
  void table::findFirst()
@@ -683,7 +820,7 @@ void table::findLast()
683
820
 
684
821
  bool table::checkFindDirection(ushort_td op)
685
822
  {
686
- bool ret ;
823
+ bool ret;
687
824
  if ((op == TD_KEY_LE_PREV_MULTI) || (op == TD_KEY_PREV_MULTI))
688
825
  ret = (m_impl->filterPtr->direction() == findBackForword);
689
826
  else
@@ -696,62 +833,65 @@ bool table::checkFindDirection(ushort_td op)
696
833
  return ret;
697
834
  }
698
835
 
699
- void table::doFind( ushort_td op, bool notIncCurrent)
836
+ void table::doFind(ushort_td op, bool notIncCurrent)
700
837
  {
701
- /*
702
- First, read from cache.
703
- If whole row readed from cache then select operation by m_impl->exSlideStat
838
+ /*
839
+ First, read from cache.
840
+ If whole row readed from cache then select operation by m_impl->exSlideStat
704
841
 
705
- */
706
- m_stat = 0;
707
- int row = m_impl->rc->row() + 1;
842
+ */
843
+ m_stat = 0;
844
+ int row = m_impl->rc->row() + 1;
708
845
 
709
- if (m_impl->rc->withinCache(row) && (!m_impl->exBookMarking))
710
- { /* read from cache */
846
+ if (m_impl->rc->withinCache(row) && (!m_impl->exBookMarking))
847
+ { /* read from cache */
711
848
 
712
- /*Is direction same */
713
- if (!checkFindDirection(op))
714
- return ;
849
+ /*Is direction same */
850
+ if (!checkFindDirection(op))
851
+ return;
715
852
 
716
- m_pdata = (void*)m_impl->rc->setRow(row);
717
- m_stat = m_impl->rc->seekMultiStat();
853
+ m_pdata = (void*)m_impl->rc->setRow(row);
854
+ m_stat = m_impl->rc->seekMultiStat();
718
855
 
719
- /*set keyvalue for keyValueDescription*/
720
- if (m_stat != 0)
721
- setSeekValueField(row);
856
+ /*set keyvalue for keyValueDescription*/
857
+ if (m_stat != 0)
858
+ setSeekValueField(row);
722
859
 
723
- //m_datalen = m_impl->rc->len();
724
- m_datalen = tableDef()->maxRecordLen;
725
- }
726
- else if (m_impl->rc->isEndOfRow(row))
727
- {
728
- /* whole row readed */
729
- /*Is direction same */
730
- if (!checkFindDirection(op))
731
- return ;
732
- /* A special situation that if rejectCount() == 0 and status = STATUS_LIMMIT_OF_REJECT
860
+ // m_datalen = m_impl->rc->len();
861
+ m_datalen = tableDef()->maxRecordLen;
862
+ }
863
+ else if (m_impl->rc->isEndOfRow(row))
864
+ {
865
+ /* whole row readed */
866
+ /*Is direction same */
867
+ if (!checkFindDirection(op))
868
+ return;
869
+ /* A special situation that if rejectCount() == 0 and status =
870
+ STATUS_LIMMIT_OF_REJECT
733
871
  then it continues . */
734
- if ((m_impl->exSlideStat == 0)
735
- || ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT)
736
- && (m_impl->filterPtr->rejectCount() == 0)))
737
- {
738
- getRecords(op);
739
- return;
740
- }
741
- if ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT) ||
742
- (m_impl->exSlideStat == STATUS_REACHED_FILTER_COND))
743
- m_stat = STATUS_EOF;
744
- else
745
- m_stat = m_impl->exSlideStat;
746
- m_impl->exSlideStat = 0;
747
- }
748
- else
872
+ if ((m_impl->exSlideStat == 0) ||
873
+ ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT) &&
874
+ (m_impl->filterPtr->rejectCount() == 0)))
749
875
  {
750
- m_impl->exNext = ((op == TD_KEY_NEXT_MULTI) || (op == TD_KEY_GE_NEXT_MULTI)) ? 1: -1;
751
- m_impl->filterPtr->setPosTypeNext(notIncCurrent);
876
+ m_impl->rc->setMemblockType(mra_nextrows);
752
877
  getRecords(op);
878
+ return;
753
879
  }
754
-
880
+ if ((m_impl->exSlideStat == STATUS_LIMMIT_OF_REJECT) ||
881
+ (m_impl->exSlideStat == STATUS_REACHED_FILTER_COND))
882
+ m_stat = STATUS_EOF;
883
+ else
884
+ m_stat = m_impl->exSlideStat;
885
+ m_impl->exSlideStat = 0;
886
+ }
887
+ else
888
+ {
889
+ m_impl->exNext =
890
+ ((op == TD_KEY_NEXT_MULTI) || (op == TD_KEY_GE_NEXT_MULTI)) ? 1
891
+ : -1;
892
+ m_impl->filterPtr->setPosTypeNext(notIncCurrent);
893
+ getRecords(op);
894
+ }
755
895
  }
756
896
 
757
897
  void table::findNext(bool notIncCurrent)
@@ -760,7 +900,7 @@ void table::findNext(bool notIncCurrent)
760
900
  if (m_impl->filterPtr)
761
901
  {
762
902
  short op = m_impl->filterPtr->isSeeksMode() ? TD_KEY_SEEK_MULTI
763
- : TD_KEY_NEXT_MULTI;
903
+ : TD_KEY_NEXT_MULTI;
764
904
  doFind(op, notIncCurrent);
765
905
  }
766
906
  else if (notIncCurrent == true)
@@ -773,7 +913,6 @@ void table::findPrev(bool notIncCurrent)
773
913
  doFind(TD_KEY_PREV_MULTI, notIncCurrent);
774
914
  else if (notIncCurrent == true)
775
915
  seekPrev();
776
-
777
916
  }
778
917
 
779
918
  void table::setQuery(const queryBase* query)
@@ -800,49 +939,37 @@ void table::setQuery(const queryBase* query)
800
939
  {
801
940
  m_stat = STATUS_CANT_ALLOC_MEMORY;
802
941
  return;
803
-
942
+ }
943
+ bool ret = false;
944
+ try
945
+ {
946
+ ret = m_impl->filterPtr->setQuery(query);
947
+ }
948
+ catch (...)
949
+ {
804
950
  }
805
951
 
806
- if (!m_impl->filterPtr->setQuery(query))
952
+ if (!ret)
807
953
  {
808
954
  m_stat = STATUS_FILTERSTRING_ERROR;
809
955
  delete m_impl->filterPtr;
810
956
  m_impl->filterPtr = NULL;
811
957
  return;
812
958
  }
813
- if (!m_impl->bookMarks)
814
- {
815
- m_impl->bookMarks = malloc(BOOKMARK_ALLOC_SIZE);
816
- if (m_impl->bookMarks)
817
- m_impl->bookMarksMemSize = BOOKMARK_ALLOC_SIZE;
818
- else
819
- {
820
- m_stat = STATUS_FILTERSTRING_ERROR;
821
- delete m_impl->filterPtr;
822
- m_impl->filterPtr = NULL;
823
- }
824
- }
825
959
  }
826
960
 
827
- void table::setFilter(const _TCHAR* str, ushort_td RejectCount, ushort_td CashCount)
961
+ void table::setFilter(const _TCHAR* str, ushort_td RejectCount,
962
+ ushort_td CashCount, bool autoEscape)
828
963
  {
829
964
  if (!str || (str[0] == 0x00))
830
965
  setQuery(NULL);
831
966
  else
832
967
  {
833
968
  queryBase q;
834
- q.queryString(str).reject(RejectCount).limit(CashCount);
969
+ q.bookmarkAlso(true);
970
+ q.queryString(str, autoEscape).reject(RejectCount).limit(CashCount);
835
971
  setQuery(&q);
836
972
  }
837
-
838
- }
839
-
840
- const _TCHAR* table::filterStr()
841
- {
842
- if (m_impl->filterPtr)
843
- return m_impl->filterPtr->filterStr();
844
- else
845
- return NULL;
846
973
  }
847
974
 
848
975
  void table::clearBuffer()
@@ -850,9 +977,8 @@ void table::clearBuffer()
850
977
  m_impl->rc->reset();
851
978
  m_pdata = m_impl->dataBak;
852
979
  memset(m_pdata, 0x00, m_buflen);
853
- if ((bulkIns()==NULL) && blobFieldUsed())
980
+ if ((bulkIns() == NULL) && blobFieldUsed())
854
981
  resetSendBlob();
855
-
856
982
  }
857
983
 
858
984
  void table::getKeySpec(keySpec* ks, bool SpecifyKeyNum)
@@ -890,17 +1016,19 @@ void table::getKeySpec(keySpec* ks, bool SpecifyKeyNum)
890
1016
  void table::doCreateIndex(bool SpecifyKeyNum)
891
1017
  {
892
1018
  int segmentCount = m_tableDef->keyDefs[m_keynum].segmentCount;
893
- keySpec* ks = new keySpec[segmentCount];
1019
+
1020
+ keySpec* ks = (keySpec*)malloc(sizeof(keySpec) * segmentCount);
1021
+ memset(ks, 0, sizeof(keySpec) * segmentCount);
894
1022
  getKeySpec(ks, SpecifyKeyNum);
895
1023
  m_pdata = ks;
896
1024
  m_datalen = sizeof(keySpec) * segmentCount;
897
1025
  nstable::doCreateIndex(SpecifyKeyNum);
898
1026
  m_pdata = m_impl->dataBak;
899
- delete[]ks;
1027
+ free(ks);
900
1028
  }
901
1029
 
902
1030
  void table::smartUpdate()
903
- {
1031
+ {
904
1032
  if (!m_impl->smartUpDate)
905
1033
  m_impl->smartUpDate = malloc(m_buflen);
906
1034
  if (m_impl->smartUpDate)
@@ -914,7 +1042,7 @@ void table::smartUpdate()
914
1042
 
915
1043
  bool table::isUniqeKey(char_td keynum)
916
1044
  {
917
- if ((keynum>=0) && (keynum < m_tableDef->keyCount))
1045
+ if ((keynum >= 0) && (keynum < m_tableDef->keyCount))
918
1046
  {
919
1047
  keydef* kd = &m_tableDef->keyDefs[m_keynum];
920
1048
  return !(kd->segments[0].flags.bit0);
@@ -924,18 +1052,19 @@ bool table::isUniqeKey(char_td keynum)
924
1052
 
925
1053
  bool table::onUpdateCheck(eUpdateType type)
926
1054
  {
927
- //Check uniqe key
1055
+ // Check uniqe key
928
1056
  if (type == changeInKey)
929
1057
  {
930
1058
  if (!isUniqeKey(m_keynum))
931
1059
  {
932
1060
  m_stat = STATUS_INVALID_KEYNUM;
933
1061
  return false;
934
- }else
1062
+ }
1063
+ else
935
1064
  {
936
- if (nsdb()->isUseTransactd()==false)
1065
+ if (isUseTransactd() == false)
937
1066
  {
938
- //backup update data
1067
+ // backup update data
939
1068
  smartUpdate();
940
1069
  seek();
941
1070
  m_impl->smartUpDateFlag = false;
@@ -964,21 +1093,20 @@ void table::onUpdateAfter(int beforeResult)
964
1093
 
965
1094
  if (valiableFormatType() && m_impl->dataPacked)
966
1095
  m_datalen = unPack((char*)m_pdata, m_datalen);
967
-
968
1096
  }
969
1097
 
970
1098
  bool table::onDeleteCheck(bool inkey)
971
1099
  {
972
- client::database *db = static_cast<client::database*>(nsdb());
1100
+ client::database* db = static_cast<client::database*>(nsdb());
973
1101
  deleteRecordFn func = db->onDeleteRecord();
974
- if (func)
975
- {
976
- if (func(db, this, inkey))
977
- {
978
- m_stat = STATUS_CANT_DEL_FOR_REL;
979
- return false;
980
- }
981
- }
1102
+ if (func)
1103
+ {
1104
+ if (func(db, this, inkey))
1105
+ {
1106
+ m_stat = STATUS_CANT_DEL_FOR_REL;
1107
+ return false;
1108
+ }
1109
+ }
982
1110
  return true;
983
1111
  }
984
1112
 
@@ -1001,7 +1129,7 @@ void table::onInsertAfter(int beforeResult)
1001
1129
  {
1002
1130
  if (valiableFormatType() && m_impl->dataPacked)
1003
1131
  m_datalen = unPack((char*)m_pdata, m_datalen);
1004
- if ((bulkIns()==NULL) && blobFieldUsed())
1132
+ if ((bulkIns() == NULL) && blobFieldUsed())
1005
1133
  addSendBlob(NULL);
1006
1134
  }
1007
1135
 
@@ -1016,8 +1144,8 @@ void* table::attachBuffer(void* NewPtr, bool unpack, size_t size)
1016
1144
  if (len < m_tableDef->maxRecordLen)
1017
1145
  len = m_tableDef->maxRecordLen;
1018
1146
  if (unpack)
1019
- len = unPack((char*)m_pdata, size);
1020
- m_datalen = len;
1147
+ len = unPack((char*)m_pdata, size);
1148
+ m_datalen = len;
1021
1149
  return oldptr;
1022
1150
  }
1023
1151
 
@@ -1026,17 +1154,20 @@ void table::dettachBuffer()
1026
1154
  if (m_impl->bfAtcPtr)
1027
1155
  m_pdata = m_impl->bfAtcPtr;
1028
1156
  m_impl->bfAtcPtr = NULL;
1029
-
1030
1157
  }
1031
1158
 
1032
- void table::init(tabledef* Def, short fnum, bool regularDir) {doInit(Def, fnum, regularDir);}
1159
+ void table::init(tabledef* Def, short fnum, bool regularDir)
1160
+ {
1161
+ doInit(Def, fnum, regularDir);
1162
+ }
1033
1163
 
1034
1164
  void table::doInit(tabledef* Def, short fnum, bool /*regularDir*/)
1035
1165
  {
1036
1166
  m_tableDef = Def;
1167
+ m_fddefs->addAllFileds(m_tableDef);
1037
1168
  ushort_td len;
1038
1169
 
1039
- m_impl->cv->setCodePage(mysql::codePage(m_tableDef->charsetIndex));
1170
+ m_fddefs->cv()->setCodePage(mysql::codePage(m_tableDef->charsetIndex));
1040
1171
 
1041
1172
  if ((len = recordLength()) < m_tableDef->maxRecordLen)
1042
1173
  len = m_tableDef->maxRecordLen;
@@ -1056,7 +1187,7 @@ void table::doInit(tabledef* Def, short fnum, bool /*regularDir*/)
1056
1187
  }
1057
1188
  if (m_impl->dataBak)
1058
1189
  free(m_impl->dataBak);
1059
- m_impl->dataBak = (void*) malloc(len);
1190
+ m_impl->dataBak = (void*)malloc(len);
1060
1191
 
1061
1192
  if (m_impl->dataBak == NULL)
1062
1193
  {
@@ -1070,29 +1201,36 @@ void table::doInit(tabledef* Def, short fnum, bool /*regularDir*/)
1070
1201
  m_buflen = len;
1071
1202
  m_datalen = len;
1072
1203
  setTableid(fnum);
1073
-
1074
1204
  }
1075
1205
 
1076
- keylen_td table::writeKeyData()
1206
+ keylen_td table::writeKeyDataTo(uchar_td* to, int keySize)
1077
1207
  {
1078
1208
  if (m_tableDef->keyCount)
1079
1209
  {
1080
- keydef& keydef = m_tableDef->keyDefs[(short)m_impl->keyNumIndex[m_keynum]];
1081
- uchar_td* to = (uchar_td*)m_impl->keybuf;
1210
+ keydef& keydef =
1211
+ m_tableDef->keyDefs[(short)m_impl->keyNumIndex[m_keynum]];
1212
+ uchar_td* start = to;
1213
+ if (keySize == 0)
1214
+ keySize = keydef.segmentCount;
1082
1215
 
1083
- for (int j = 0; j < keydef.segmentCount; j++)
1216
+ for (int j = 0; j < keySize; j++)
1084
1217
  {
1085
1218
  int fdnum = keydef.segments[j].fieldNum;
1086
1219
  fielddef& fd = m_tableDef->fieldDefs[fdnum];
1087
1220
  uchar_td* from = (uchar_td*)m_pdata + fd.pos;
1088
1221
  to = fd.keyCopy(to, from);
1089
1222
  }
1090
- return (keylen_td)(to - (uchar_td*)m_impl->keybuf);
1223
+ return (keylen_td)(to - start);
1091
1224
  }
1092
1225
  return 0;
1093
1226
  }
1094
1227
 
1095
- uint_td table::pack(char*ptr, size_t size)
1228
+ keylen_td table::writeKeyData()
1229
+ {
1230
+ return writeKeyDataTo((uchar_td*)m_impl->keybuf, 0);
1231
+ }
1232
+
1233
+ uint_td table::pack(char* ptr, size_t size)
1096
1234
  {
1097
1235
  char* pos = ptr;
1098
1236
  char* end = pos + size;
@@ -1100,26 +1238,36 @@ uint_td table::pack(char*ptr, size_t size)
1100
1238
  for (int i = 0; i < m_tableDef->fieldCount; i++)
1101
1239
  {
1102
1240
  fielddef& fd = m_tableDef->fieldDefs[i];
1103
- int blen = fd.varLenBytes();
1104
- int dl = fd.len; // length
1105
- if (blen == 1)
1106
- dl = *((unsigned char*)(pos)) + blen;
1107
- else if (blen == 2)
1108
- dl = *((unsigned short*)(pos)) + blen;
1109
- pos += dl;
1110
- if ((movelen = fd.len - dl) != 0)
1241
+ if (fd.type == ft_myfixedbinary)
1242
+ {
1243
+ memmove(pos + 2, pos, fd.len - 2); // move as size pace in the field
1244
+ *((unsigned short*)(pos)) = fd.len - 2; // fixed size
1245
+ pos += fd.len;
1246
+ }
1247
+ else
1111
1248
  {
1112
- end -= movelen;
1113
- memmove(pos, pos + movelen, end - pos);
1249
+ int blen = fd.varLenBytes();
1250
+ int dl = fd.len; // length
1251
+ if (blen == 1)
1252
+ dl = *((unsigned char*)(pos)) + blen;
1253
+ else if (blen == 2)
1254
+ dl = *((unsigned short*)(pos)) + blen;
1255
+ pos += dl;
1256
+ if ((movelen = fd.len - dl) != 0)
1257
+ {
1258
+ end -= movelen;
1259
+ memmove(pos, pos + movelen, end - pos);
1260
+ }
1114
1261
  }
1115
1262
  }
1116
- m_impl->dataPacked = true;
1263
+ m_impl->dataPacked = true;
1117
1264
  return (uint_td)(pos - ptr);
1118
1265
  }
1119
1266
 
1120
1267
  uint_td table::doGetWriteImageLen()
1121
1268
  {
1122
- if (!blobFieldUsed() && !valiableFormatType() && (m_tableDef->flags.bit0 == false))
1269
+ if (!blobFieldUsed() && !valiableFormatType() &&
1270
+ (m_tableDef->flags.bit0 == false))
1123
1271
  return m_buflen;
1124
1272
  // Make blob pointer list
1125
1273
  if (blobFieldUsed())
@@ -1144,13 +1292,14 @@ uint_td table::doGetWriteImageLen()
1144
1292
  return pack((char*)m_pdata, m_buflen);
1145
1293
  else
1146
1294
  {
1147
- fielddef* FieldDef = &m_tableDef->fieldDefs[m_tableDef->fieldCount - 1];
1295
+ fielddef* fd = &m_tableDef->fieldDefs[m_tableDef->fieldCount - 1];
1148
1296
  size_t len = 0;
1149
1297
  short* pos;
1150
1298
 
1151
- if (FieldDef->type == ft_note)
1152
- len = strlen((char*)fieldPtr((short)(m_tableDef->fieldCount - 1))) + 1;
1153
- else if (FieldDef->type == ft_lvar)
1299
+ if (fd->type == ft_note)
1300
+ len = strlen((char*)fieldPtr((short)(m_tableDef->fieldCount - 1))) +
1301
+ 1;
1302
+ else if (fd->type == ft_lvar)
1154
1303
  {
1155
1304
  // xx................xx.............00
1156
1305
  // ln--data----------ln-----data----00
@@ -1160,14 +1309,13 @@ uint_td table::doGetWriteImageLen()
1160
1309
  len += 2; // size
1161
1310
  len += *pos;
1162
1311
  pos = (short*)((char*)pos + (*pos + 2)); // next position
1163
-
1164
1312
  }
1165
1313
  len += 2;
1166
1314
  }
1167
1315
  else
1168
- len = FieldDef->len;
1316
+ len = fd->len;
1169
1317
 
1170
- len += FieldDef->pos;
1318
+ len += fd->pos;
1171
1319
 
1172
1320
  return (uint_td)len;
1173
1321
  }
@@ -1182,23 +1330,37 @@ uint_td table::unPack(char* ptr, size_t size)
1182
1330
  for (int i = 0; i < m_tableDef->fieldCount; i++)
1183
1331
  {
1184
1332
  fielddef& fd = m_tableDef->fieldDefs[i];
1185
- int blen = fd.varLenBytes();
1186
- int dl = fd.len; // length
1187
- if (blen == 1)
1188
- dl = *((unsigned char*)(pos)) + blen;
1189
- else if (blen == 2)
1190
- dl = *((unsigned short*)(pos)) + blen;
1191
- if ((movelen = fd.len - dl) != 0)
1333
+ if (fd.type == ft_myfixedbinary)
1334
+ {
1335
+ int dl = *((unsigned short*)(pos));
1336
+ assert(dl == fd.len - 2);
1337
+ memmove(pos, pos + 2, dl);
1338
+ pos += dl;
1339
+ *((unsigned short*)(pos)) = 0x00;
1340
+ ;
1341
+ pos += 2;
1342
+ }
1343
+ else
1192
1344
  {
1193
- if (max < end + movelen)
1194
- return 0;
1195
- const char* src = pos + dl;
1196
- memmove(pos + fd.len, src, end - src);
1197
- end += movelen;
1345
+ int blen = fd.varLenBytes();
1346
+ int dl = fd.len; // length
1347
+ if (blen == 1)
1348
+ dl = *((unsigned char*)(pos)) + blen;
1349
+ else if (blen == 2)
1350
+ dl = *((unsigned short*)(pos)) + blen;
1351
+ if ((movelen = fd.len - dl) != 0)
1352
+ {
1353
+ if (max < end + movelen)
1354
+ return 0;
1355
+ char* src = pos + dl;
1356
+ memmove(pos + fd.len, src, end - src);
1357
+ memset(src, 0, movelen);
1358
+ end += movelen;
1359
+ }
1360
+ pos += fd.len;
1198
1361
  }
1199
- pos += fd.len;
1200
1362
  }
1201
- m_impl->dataPacked = false;
1363
+ m_impl->dataPacked = false;
1202
1364
  return (uint_td)(pos - ptr);
1203
1365
  }
1204
1366
 
@@ -1213,15 +1375,14 @@ void table::addBlobEndRow()
1213
1375
  void table::resetSendBlob()
1214
1376
  {
1215
1377
  addSendBlob(NULL);
1216
- m_impl->blobs.clear();
1217
-
1378
+ m_fddefs->blobClear();
1218
1379
  }
1219
1380
 
1220
1381
  void table::addSendBlob(const blob* blob)
1221
1382
  {
1222
1383
  short stat = m_stat;
1223
1384
  /*backup current data buffer*/
1224
- const void *tmp = data();
1385
+ const void* tmp = data();
1225
1386
  setData((void*)blob);
1226
1387
  tdap(TD_ADD_SENDBLOB);
1227
1388
  /*restore data buffer*/
@@ -1234,7 +1395,7 @@ const blobHeader* table::getBlobHeader()
1234
1395
  short stat = m_stat;
1235
1396
  const blobHeader* p;
1236
1397
  /*backup current data buffer*/
1237
- const void *tmp = data();
1398
+ const void* tmp = data();
1238
1399
  setData(&p);
1239
1400
  tdap(TD_GET_BLOB_BUF);
1240
1401
  /*restore data buffer*/
@@ -1244,7 +1405,6 @@ const blobHeader* table::getBlobHeader()
1244
1405
  if (stat)
1245
1406
  return NULL;
1246
1407
  return p;
1247
-
1248
1408
  }
1249
1409
 
1250
1410
  void table::setBlobFieldPointer(char* ptr, const blobHeader* hd)
@@ -1266,12 +1426,11 @@ void table::setBlobFieldPointer(char* ptr, const blobHeader* hd)
1266
1426
  ++hd->curRow;
1267
1427
  hd->nextField = (blobField*)f;
1268
1428
  }
1269
-
1270
1429
  }
1271
1430
 
1272
1431
  void table::onReadAfter()
1273
1432
  {
1274
- m_impl->strBufs.clear();
1433
+ m_fddefs->strBufs()->clear();
1275
1434
  if (valiableFormatType())
1276
1435
  {
1277
1436
  m_datalen = unPack((char*)m_pdata, m_datalen);
@@ -1285,924 +1444,145 @@ void table::onReadAfter()
1285
1444
  }
1286
1445
  if (m_buflen - m_datalen > 0)
1287
1446
  memset((char*)m_pdata + m_datalen, 0, m_buflen - m_datalen);
1288
-
1289
1447
  }
1290
1448
 
1291
1449
  short table::fieldNumByName(const _TCHAR* name)
1292
1450
  {
1293
- short i=0;
1294
- if (name == 0) return i;
1295
- if (m_impl->fields.size() == 0)
1296
- {
1297
- #ifdef _UNICODE
1298
- wchar_t buf[74];
1299
- for (i = 0; i < m_tableDef->fieldCount; i++)
1300
- m_impl->fields.push_back(CFiledNameIndex(i, m_tableDef->fieldDefs[i].name(buf)));
1301
- #else
1302
- for (i = 0; i < m_tableDef->fieldCount; i++)
1303
- m_impl->fields.push_back(CFiledNameIndex(i, m_tableDef->fieldDefs[i].name()));
1304
- #endif
1305
-
1306
- sort(m_impl->fields.begin(), m_impl->fields.end());
1307
- }
1308
- if (binary_search(m_impl->fields.begin(), m_impl->fields.end(), CFiledNameIndex(0, name)))
1309
- {
1310
- std::vector<CFiledNameIndex>::iterator p;
1311
- p = lower_bound(m_impl->fields.begin(), m_impl->fields.end(), CFiledNameIndex(0, name));
1312
- return m_impl->fields[p - m_impl->fields.begin()].index;
1313
- }
1314
-
1315
- return -1;
1451
+ return m_fddefs->indexByName(name);
1316
1452
  }
1317
1453
 
1318
- void* table::fieldPtr(short index)
1454
+ void* table::fieldPtr(short index) const
1319
1455
  {
1320
- if (checkIndex(index) == false)
1456
+ if (!checkIndex(index))
1321
1457
  return NULL;
1322
- return (void*)((char*) m_pdata + m_tableDef->fieldDefs[index].pos);
1458
+ return m_impl->fields[index].ptr();
1323
1459
  }
1324
1460
 
1325
1461
  void table::setFVA(short index, const char* data)
1326
1462
  {
1327
-
1328
- __int64 value;
1329
- double fltValue;
1330
- if (checkIndex(index) == false)
1331
- return;
1332
- fielddef& fd = m_tableDef->fieldDefs[index];
1333
-
1334
- char* p = (char*)m_pdata + fd.pos;
1335
- if (data == NULL)
1336
- {
1337
- memset(p, 0, fd.len);
1463
+ if (!checkIndex(index))
1338
1464
  return;
1339
- }
1340
-
1341
- switch (fd.type)
1342
- {
1343
- case ft_string:
1344
- return store<stringStore, char, char>(p, data, fd, m_impl->cv, m_impl->usePadChar);
1345
- case ft_note:
1346
- case ft_zstring: return store<zstringStore, char, char>(p, data, fd, m_impl->cv);
1347
- case ft_wzstring: return store<wzstringStore, WCHAR, char>(p, data, fd, m_impl->cv);
1348
- case ft_wstring:
1349
- return store<wstringStore, WCHAR, char>(p, data, fd, m_impl->cv, m_impl->usePadChar);
1350
- case ft_mychar: return store<myCharStore, char, char>(p, data, fd, m_impl->cv);
1351
- case ft_myvarchar: return store<myVarCharStore, char, char>(p, data, fd, m_impl->cv);
1352
- case ft_lstring:
1353
- case ft_myvarbinary: return store<myVarBinaryStore, char, char>(p, data, fd, m_impl->cv);
1354
- case ft_mywchar: return store<myWcharStore, WCHAR, char>(p, data, fd, m_impl->cv);
1355
- case ft_mywvarchar: return store<myWvarCharStore, WCHAR, char>(p, data, fd, m_impl->cv);
1356
- case ft_mywvarbinary: return store<myWvarBinaryStore, WCHAR, char>(p, data, fd, m_impl->cv);
1357
- case ft_myblob:
1358
- case ft_mytext:
1359
- {
1360
- char* tmp = blobStore<char>(p, data, fd, m_impl->cv);
1361
- m_impl->blobs.push_back(boost::shared_array<char>(tmp));
1362
- return;
1363
- }
1364
- case ft_decimal:
1365
- case ft_money:
1366
- case ft_numeric:
1367
- case ft_bfloat:
1368
- case ft_numericsts:
1369
- case ft_numericsa:
1370
- case ft_currency: // currecy
1371
- case ft_float: // float double
1372
- fltValue = atof(data);
1373
- setFV(index, fltValue);
1374
- return;
1375
- case ft_lvar: // Lvar
1376
- return;
1377
-
1378
- case ft_date: // date mm/dd/yy
1379
- value = /*StrToBtrDate*/atobtrd((const char*) data).i;
1380
- break;
1381
- case ft_time: // time hh:nn:ss
1382
- value = /*StrToBtrTime*/atobtrt((const char*)data).i;
1383
- break;
1384
- case ft_autoIncUnsigned:
1385
- case ft_uinteger:
1386
- case ft_integer:
1387
- case ft_autoinc:
1388
- case ft_bit: value = _atoi64(data);
1389
- break;
1390
- case ft_logical:
1391
- if (m_impl->logicalToString)
1392
- {
1393
- char tmp[5];
1394
- strncpy(tmp, data, 5);
1395
- if (strcmp(_strupr(tmp), "YES") == 0)
1396
- value = 1;
1397
- else
1398
- value = 0;
1399
- }
1400
- else
1401
- value = atol(data);
1402
- break;
1403
- case ft_timestamp:
1404
- case ft_mytimestamp: value = 0;
1405
- break;
1406
- case ft_mydate:
1407
- {
1408
- myDate d;
1409
- d = data;
1410
- value = d.getValue();
1411
- break;
1412
- }
1413
- case ft_mytime:
1414
- {
1415
- myTime t(fd.len);
1416
- t = data;
1417
- value = t.getValue();
1418
- break;
1419
- }
1420
-
1421
- case ft_mydatetime:
1422
- {
1423
- myDateTime t(fd.len);
1424
- t = data;
1425
- value = t.getValue();
1426
- break;
1427
- }
1428
- default: return;
1429
- }
1430
- setValue(fd, (uchar_td*)m_pdata, value);
1465
+ m_impl->fields[index].setFVA(data);
1431
1466
  }
1432
1467
 
1433
1468
  #ifdef _WIN32
1434
1469
 
1435
1470
  void table::setFVW(short index, const wchar_t* data)
1436
1471
  {
1437
-
1438
- int value;
1439
- double fltValue;
1440
- if (checkIndex(index) == false)
1441
- return;
1442
- fielddef& fd = m_tableDef->fieldDefs[index];
1443
-
1444
- char* p = (char*)m_pdata + fd.pos;
1445
- if (data == NULL)
1446
- {
1447
- memset(p, 0, fd.len);
1448
- return;
1449
- }
1450
-
1451
- switch (fd.type)
1452
- {
1453
- case ft_string:
1454
- return store<stringStore, char, WCHAR>(p, data, fd, m_impl->cv, m_impl->usePadChar);
1455
- case ft_note:
1456
- case ft_zstring: return store<zstringStore, char, WCHAR>(p, data, fd, m_impl->cv);
1457
- case ft_wzstring: return store<wzstringStore, WCHAR, WCHAR>(p, data, fd, m_impl->cv);
1458
- case ft_wstring:
1459
- return store<wstringStore, WCHAR, WCHAR>(p, data, fd, m_impl->cv, m_impl->usePadChar);
1460
- case ft_mychar: return store<myCharStore, char, WCHAR>(p, data, fd, m_impl->cv);
1461
- case ft_myvarchar: return store<myVarCharStore, char, WCHAR>(p, data, fd, m_impl->cv);
1462
- case ft_lstring:
1463
- case ft_myvarbinary: return store<myVarBinaryStore, char, WCHAR>(p, data, fd, m_impl->cv);
1464
- case ft_mywchar: return store<myWcharStore, WCHAR, WCHAR>(p, data, fd, m_impl->cv);
1465
- case ft_mywvarchar: return store<myWvarCharStore, WCHAR, WCHAR>(p, data, fd, m_impl->cv);
1466
- case ft_mywvarbinary: return store<myWvarBinaryStore, WCHAR, WCHAR>(p, data, fd, m_impl->cv);
1467
- case ft_myblob:
1468
- case ft_mytext:
1469
- {
1470
- char* tmp = blobStore<WCHAR>(p, data, fd, m_impl->cv);
1471
- m_impl->blobs.push_back(boost::shared_array<char>(tmp));
1472
- return;
1473
- }
1474
-
1475
- case ft_date: // date mm/dd/yy
1476
- value = /*StrToBtrDate*/atobtrd(data).i;
1477
- setFV(index, value);
1478
- break;
1479
- case ft_time: // time hh:nn:ss
1480
- value = /*StrToBtrTime*/atobtrt(data).i;
1481
- setFV(index, value);
1472
+ if (!checkIndex(index))
1482
1473
  return;
1483
-
1484
- case ft_autoIncUnsigned:
1485
- case ft_uinteger:
1486
- case ft_integer:
1487
- case ft_autoinc:
1488
- case ft_bit:
1489
- {
1490
- __int64 v = _wtoi64(data);
1491
- setFV(index, v);
1492
- break;
1493
- }
1494
- case ft_logical:
1495
- if (m_impl->logicalToString)
1496
- {
1497
- wchar_t tmp[5];
1498
- wcsncpy(tmp, data, 5);
1499
-
1500
- if (wcscmp(_wcsupr(tmp), L"YES") == 0)
1501
- value = 1;
1502
- else
1503
- value = 0;
1504
- }
1505
- else
1506
- value = _wtol(data);
1507
- setFV(index, value);
1508
- break;
1509
-
1510
- case ft_decimal:
1511
- case ft_money:
1512
- case ft_numeric:
1513
- case ft_bfloat:
1514
- case ft_numericsts:
1515
- case ft_numericsa:
1516
- case ft_currency:
1517
- case ft_float: fltValue = _wtof(data);
1518
- setFV(index, fltValue);
1519
- break;
1520
- case ft_timestamp:
1521
- {
1522
- __int64 v = 0;
1523
- setFV(index, v);
1524
- return;
1525
- }
1526
- case ft_mydate:
1527
- {
1528
- myDate d;
1529
- d = data;
1530
- setValue(fd, (uchar_td *)m_pdata, d.getValue());
1531
- return;
1532
- }
1533
- case ft_mytime:
1534
- {
1535
- myTime t(fd.len);
1536
- t = data;
1537
- setValue(fd, (uchar_td*)m_pdata, t.getValue());
1538
- return;
1539
- }
1540
- case ft_mydatetime:
1541
- {
1542
- myDateTime t(fd.len);
1543
- t = data;
1544
- setFV(index, t.getValue());
1545
- return;
1546
- }
1547
- case ft_mytimestamp:
1548
- case ft_lvar: break;
1549
- }
1550
-
1474
+ m_impl->fields[index].setFVW(data);
1551
1475
  }
1552
1476
 
1553
1477
  void table::setFVW(const _TCHAR* FieldName, const wchar_t* data)
1554
1478
  {
1555
1479
  short index = fieldNumByName(FieldName);
1556
- setFVW(index, data);
1480
+ if (!checkIndex(index))
1481
+ return;
1482
+ m_impl->fields[index].setFVW(data);
1557
1483
  }
1558
1484
 
1559
1485
  #endif //_WIN32
1560
1486
 
1561
1487
  void table::setFV(short index, unsigned char data)
1562
1488
  {
1489
+ if (!checkIndex(index))
1490
+ return;
1563
1491
  int value = (long)data;
1564
1492
  setFV(index, value);
1565
1493
  }
1566
1494
 
1567
1495
  void table::setFV(short index, int data)
1568
1496
  {
1569
- char buf[20];
1570
- double d;
1571
- if (checkIndex(index) == false)
1497
+ if (!checkIndex(index))
1572
1498
  return;
1573
- int v = data;
1574
- fielddef& fd = m_tableDef->fieldDefs[index];
1575
- switch (fd.type)
1576
- {
1577
-
1578
- case ft_mydate:
1579
- {
1580
- myDate myd;
1581
- myd.setValue(data, m_impl->myDateTimeValueByBtrv);
1582
- setValue(fd, (uchar_td*)m_pdata, myd.getValue());
1583
- break;
1584
- }
1585
- case ft_mytime:
1586
- {
1587
- myTime myt(fd.len);
1588
- myt.setValue(data, m_impl->myDateTimeValueByBtrv);
1589
- setValue(fd, (uchar_td*)m_pdata, myt.getValue());
1590
- break;
1591
- }
1592
- case ft_integer:
1593
- case ft_date:
1594
- case ft_time:
1595
- case ft_autoIncUnsigned:
1596
- case ft_uinteger:
1597
- case ft_logical:
1598
- case ft_autoinc:
1599
- case ft_bit:
1600
- case ft_mydatetime:
1601
- switch (m_tableDef->fieldDefs[index].len)
1602
- {
1603
- case 1: *((char*)((char*)m_pdata + fd.pos)) = (char) v;
1604
- break;
1605
- case 2: *((short*)((char*)m_pdata + fd.pos)) = (short)v;
1606
- break;
1607
- case 3: memcpy((char*)m_pdata + fd.pos, &v, 3);
1608
- break;
1609
- case 4: *((int*)((char*)m_pdata + fd.pos)) = v;
1610
- break;
1611
- case 8: *((__int64*)((char*)m_pdata + fd.pos)) = v;
1612
- break;
1613
- }
1614
- break;
1615
-
1616
- case ft_timestamp:
1617
- {
1618
- __int64 v = 0;
1619
- setFV(index, v);
1620
- return;
1621
- }
1622
- case ft_decimal:
1623
- case ft_money:
1624
- case ft_numeric:
1625
- case ft_bfloat:
1626
- case ft_numericsts:
1627
- case ft_numericsa:
1628
-
1629
- case ft_currency:
1630
- case ft_float: d = (double)data;
1631
- setFV(index, d);
1632
- break;
1633
- case ft_string:
1634
- case ft_zstring:
1635
- case ft_note:
1636
- case ft_myvarbinary:
1637
- case ft_myvarchar:
1638
- case ft_mychar:
1639
- if (data == 0)
1640
- setFVA(index, "");
1641
- else
1642
- {
1643
- _ltoa_s(data, buf, 20, 10);
1644
- setFVA(index, buf);
1645
- }
1646
- break;
1647
- case ft_mywvarbinary:
1648
- case ft_mywvarchar:
1649
- case ft_mywchar:
1650
- case ft_wstring:
1651
- case ft_wzstring:
1652
- {
1653
- if (data == 0)
1654
- setFV(index, _T(""));
1655
- else
1656
- {
1657
- _TCHAR buf[30];
1658
- _ltot_s(data, buf, 30, 10);
1659
- setFV(index, buf);
1660
- }
1661
- break;
1662
- }
1663
- case ft_lvar: break;
1664
-
1665
- }
1499
+ m_impl->fields[index].setFV(data);
1666
1500
  }
1667
1501
 
1668
1502
  void table::setFV(short index, double data)
1669
1503
  {
1670
- char buf[20];
1671
- __int64 i64;
1672
- if (checkIndex(index) == false)
1504
+ if (!checkIndex(index))
1673
1505
  return;
1674
-
1675
- switch (m_tableDef->fieldDefs[index].type)
1676
- {
1677
- case ft_currency: // currency
1678
- i64 = (__int64)(data * 10000 + 0.5);
1679
- setFV(index, i64);
1680
- break;
1681
- case ft_bfloat: // bfloat
1682
- case ft_float:
1683
- switch (m_tableDef->fieldDefs[index].len)
1684
- {
1685
- case 4: *((float*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos)) = (float)data;
1686
- break;
1687
- case 8: *((double*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos)) = data;
1688
- break;
1689
- default:
1690
- break;
1691
- }
1692
- break;
1693
- case ft_decimal:
1694
- case ft_money: setFVDecimal(index, data);
1695
- break;
1696
- case ft_numeric:
1697
- case ft_numericsts:
1698
- case ft_numericsa: setFVNumeric(index, data);
1699
- break;
1700
-
1701
- case ft_integer:
1702
- case ft_date:
1703
- case ft_time:
1704
- case ft_autoIncUnsigned:
1705
- case ft_uinteger:
1706
- case ft_logical:
1707
- case ft_autoinc:
1708
- case ft_timestamp:
1709
- case ft_bit:
1710
- case ft_mydate:
1711
- case ft_mytime:
1712
- case ft_mydatetime:
1713
- case ft_mytimestamp: i64 = (__int64)data;
1714
- setFV(index, i64);
1715
- break;
1716
- case ft_string:
1717
- case ft_zstring:
1718
- case ft_note:
1719
- case ft_myvarbinary:
1720
- case ft_myvarchar:
1721
- case ft_mychar:
1722
- if (data == 0)
1723
- setFVA(index, "");
1724
- else
1725
- {
1726
- sprintf(buf, "%f", data);
1727
- setFVA(index, buf);
1728
- break;
1729
- }
1730
- case ft_lvar: break;
1731
- case ft_mywvarbinary:
1732
- case ft_mywvarchar:
1733
- case ft_mywchar:
1734
- case ft_wstring:
1735
- case ft_wzstring:
1736
- {
1737
- if (data == 0)
1738
- setFV(index, _T(""));
1739
- else
1740
- {
1741
- _TCHAR buf[40];
1742
- _stprintf_s(buf, 40, _T("%f"), data);
1743
- setFV(index, buf);
1744
- }
1745
- break;
1746
- }
1747
- }
1748
- }
1749
-
1750
- void table::setFV(short index, bool data)
1751
- {
1752
- int value = (int)data;
1753
- setFV(index, value);
1506
+ m_impl->fields[index].setFV(data);
1754
1507
  }
1755
1508
 
1756
1509
  void table::setFV(short index, short data)
1757
1510
  {
1511
+ if (!checkIndex(index))
1512
+ return;
1758
1513
  int value = (int)data;
1759
1514
  setFV(index, value);
1760
1515
  }
1761
1516
 
1762
1517
  void table::setFV(short index, float data)
1763
1518
  {
1519
+ if (!checkIndex(index))
1520
+ return;
1764
1521
  double value = (double)data;
1765
1522
  setFV(index, value);
1766
-
1767
1523
  }
1768
1524
 
1769
- short table::getFVsht(short index) {return (short)getFVlng(index);}
1525
+ short table::getFVsht(short index)
1526
+ {
1527
+ return (short)getFVlng(index);
1528
+ }
1770
1529
 
1771
1530
  int table::getFVlng(short index)
1772
1531
  {
1773
- int ret = 0;
1774
-
1775
- if (checkIndex(index) == false)
1532
+ if (!checkIndex(index))
1776
1533
  return 0;
1777
- fielddef& fd = m_tableDef->fieldDefs[index];
1778
- switch (fd.type)
1779
- {
1780
- case ft_integer:
1781
- case ft_autoinc:
1782
- switch (fd.len)
1783
- {
1784
- case 1: ret = *(((char*)m_pdata + fd.pos));
1785
- break;
1786
- case 2: ret = *((short*)((char*)m_pdata + fd.pos));
1787
- break;
1788
- case 3: memcpy(&ret, (char*)m_pdata + fd.pos, 3);
1789
- ret = ((ret & 0xFFFFFF) << 8) / 0x100;
1790
- break;
1791
- case 8:
1792
- case 4: ret = *((int*)((char*)m_pdata + fd.pos));
1793
- break;
1794
- }
1795
- break;
1796
- case ft_autoIncUnsigned:
1797
- case ft_uinteger:
1798
- case ft_logical:
1799
- case ft_bit:
1800
- case ft_date:
1801
- case ft_time:
1802
- case ft_timestamp:
1803
- case ft_mydatetime:
1804
- case ft_mytimestamp:
1805
- switch (fd.len)
1806
- {
1807
- case 1: ret = *((unsigned char*)((char*)m_pdata + fd.pos));
1808
- break;
1809
- case 2: ret = *((unsigned short*)((char*)m_pdata + fd.pos));
1810
- break;
1811
- case 3: memcpy(&ret, (char*)m_pdata + fd.pos, 3);
1812
- break;
1813
- case 8:
1814
- case 4:
1815
- ret = *((unsigned int*)((char*)m_pdata + fd.pos));
1816
- break;
1817
- }
1818
- break;
1819
- case ft_mydate:
1820
- {
1821
- myDate myd;
1822
- myd.setValue((int)getValue64(fd, (const uchar_td*)m_pdata));
1823
- ret = myd.getValue(m_impl->myDateTimeValueByBtrv);
1824
- break;
1825
- }
1826
- case ft_mytime:
1827
- {
1828
- myTime myt(fd.len);
1829
- myt.setValue((int)getValue64(fd, (const uchar_td*)m_pdata));
1830
- ret = (int)myt.getValue(m_impl->myDateTimeValueByBtrv);
1831
- break; ;
1832
- }
1833
- case ft_string:
1834
- case ft_zstring:
1835
- case ft_note:
1836
- case ft_myvarbinary:
1837
- case ft_myvarchar:
1838
- case ft_mychar: ret = atol(getFVAstr(index));
1839
- break;
1840
- case ft_wstring:
1841
- case ft_wzstring:
1842
- case ft_mywvarbinary:
1843
- case ft_mywvarchar:
1844
- case ft_mywchar: ret = _ttol(getFVstr(index));
1845
- break;
1846
- case ft_currency: ret = (long)(*((__int64*)((char*)m_pdata + fd.pos)) / 10000);
1847
- break;
1848
- case ft_bfloat:
1849
- case ft_float: ret = (long)getFVdbl(index);
1850
- break;
1851
- case ft_decimal:
1852
- case ft_money: ret = (long)getFVDecimal(index);
1853
- break;
1854
- case ft_numeric:
1855
- case ft_numericsts:
1856
- case ft_numericsa: ret = (long)getFVnumeric(index);
1857
- break;
1858
-
1859
- case ft_lvar: break;
1860
- default: return 0;
1861
- }
1862
- return ret;
1534
+ return m_impl->fields[index].getFVlng();
1863
1535
  }
1864
1536
 
1865
- float table::getFVflt(short index) {return (float) getFVdbl(index);}
1537
+ float table::getFVflt(short index)
1538
+ {
1539
+ return (float)getFVdbl(index);
1540
+ }
1866
1541
 
1867
1542
  double table::getFVdbl(short index)
1868
1543
  {
1869
- double ret = 0;
1870
- if (checkIndex(index) == false)
1544
+ if (!checkIndex(index))
1871
1545
  return 0;
1872
- switch (m_tableDef->fieldDefs[index].type)
1873
- {
1874
- case ft_currency:
1875
- ret = (double) * ((__int64*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos));
1876
- ret = ret / 10000;
1877
- break;
1878
-
1879
- case ft_bfloat:
1880
- case ft_timestamp:
1881
- case ft_float:
1882
- switch (m_tableDef->fieldDefs[index].len)
1883
- {
1884
- case 4: ret = (double) * ((float*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos));
1885
- break;
1886
- case 10: // long double
1887
- case 8: ret = (double) * ((double*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos));
1888
- break;
1889
- }
1890
- break;
1891
- case ft_string:
1892
- case ft_zstring:
1893
- case ft_note:
1894
- case ft_myvarbinary:
1895
- case ft_myvarchar:
1896
- case ft_mychar: ret = atof(getFVAstr(index));
1897
- break;
1898
- case ft_wstring:
1899
- case ft_wzstring:
1900
- case ft_mywvarbinary:
1901
- case ft_mywvarchar:
1902
- case ft_mywchar: ret = _ttof(getFVstr(index));
1903
- break;
1904
- case ft_integer:
1905
- case ft_date:
1906
- case ft_time:
1907
- case ft_autoIncUnsigned:
1908
- case ft_uinteger:
1909
- case ft_logical:
1910
- case ft_autoinc:
1911
- case ft_bit:
1912
- case ft_mydate:
1913
- case ft_mytime:
1914
- case ft_mydatetime:
1915
- case ft_mytimestamp: ret = (double)getFV64(index);
1916
- break;
1917
-
1918
- case ft_decimal:
1919
- case ft_money: ret = getFVDecimal(index);
1920
- break;
1921
- case ft_numeric:
1922
- case ft_numericsts:
1923
- case ft_numericsa: ret = getFVnumeric(index);
1924
- break;
1925
- case ft_lvar: break;
1926
- default: return 0;
1927
- }
1928
- return ret;
1546
+ return m_impl->fields[index].getFVdbl();
1929
1547
  }
1930
1548
 
1931
- unsigned char table::getFVbyt(short index) {return (unsigned char)getFVlng(index);}
1549
+ unsigned char table::getFVbyt(short index)
1550
+ {
1551
+ return (unsigned char)getFVlng(index);
1552
+ }
1932
1553
 
1933
1554
  #ifdef _WIN32
1934
1555
 
1935
1556
  const wchar_t* table::getFVWstr(short index)
1936
1557
  {
1937
-
1938
- if (checkIndex(index) == false)
1558
+ if (!checkIndex(index))
1939
1559
  return NULL;
1940
-
1941
- fielddef& fd = m_tableDef->fieldDefs[index];
1942
- char* data = (char*)m_pdata + fd.pos;
1943
- switch (fd.type)
1944
- {
1945
- case ft_string:
1946
- return read<stringStore, char, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv,
1947
- m_impl->trimPadChar);
1948
- case ft_note:
1949
- case ft_zstring: return read<zstringStore, char, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1950
- case ft_wzstring:
1951
- return read<wzstringStore, WCHAR, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1952
- case ft_wstring:
1953
- return read<wstringStore, WCHAR, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv,
1954
- m_impl->trimPadChar);
1955
- case ft_mychar:
1956
- return read<myCharStore, char, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv,
1957
- m_impl->trimPadChar);
1958
- case ft_myvarchar:
1959
- return read<myVarCharStore, char, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1960
- case ft_lstring:
1961
- case ft_myvarbinary:
1962
- return read<myVarBinaryStore, char, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1963
- case ft_mywchar:
1964
- return read<myWcharStore, WCHAR, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv,
1965
- m_impl->trimPadChar);
1966
- case ft_mywvarchar:
1967
- return read<myWvarCharStore, WCHAR, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1968
- case ft_mywvarbinary:
1969
- return read<myWvarBinaryStore, WCHAR, WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1970
- case ft_myblob:
1971
- case ft_mytext: return readBlob<WCHAR>(data, &m_impl->strBufs, fd, m_impl->cv);
1972
- }
1973
- wchar_t* p = (wchar_t*) m_impl->strBufs.getPtrW(max(fd.len * 2, 50));
1974
-
1975
- wchar_t buf[10] = L"%0.";
1976
-
1977
- switch (fd.type)
1978
- {
1979
-
1980
- case ft_integer:
1981
- case ft_bit:
1982
- case ft_autoinc: _i64tow_s(getFV64(index), p, 50, 10);
1983
- return p;
1984
- case ft_logical:
1985
- if (m_impl->logicalToString)
1986
- {
1987
- if (getFVlng(index))
1988
- return L"Yes";
1989
- else
1990
- return L"No";
1991
- }
1992
- else
1993
- _i64tow_s(getFV64(index), p, 50, 10);
1994
-
1995
- case ft_bfloat:
1996
- case ft_float:
1997
- case ft_currency:
1998
- {
1999
-
2000
- swprintf_s(p, 50, L"%lf", getFVdbl(index));
2001
- int k = (int)wcslen(p) - 1;
2002
- while (k >= 0)
2003
- {
2004
- if (p[k] == L'0')
2005
- p[k] = 0x00;
2006
- else if (p[k] == L'.')
2007
- {
2008
- p[k] = 0x00;
2009
- break;
2010
- }
2011
- else
2012
- break;
2013
- k--;
2014
- }
2015
- break;
2016
- }
2017
- case ft_autoIncUnsigned:
2018
- case ft_uinteger:
2019
- swprintf_s(p, 50, L"%lu", getFV64(index));
2020
- break;
2021
- case ft_date: return btrdtoa(getFVlng(index), p);
2022
- case ft_time: return btrttoa(getFVlng(index), p);
2023
- case ft_mydate:
2024
- {
2025
- myDate d;
2026
- d.setValue((int)getValue64(fd, (const uchar_td*)m_pdata));
2027
- return d.toStr(p, m_impl->myDateTimeValueByBtrv);
2028
- }
2029
- case ft_mytime:
2030
- {
2031
-
2032
- myTime t(fd.len);
2033
- t.setValue(getValue64(fd, (const uchar_td*)m_pdata));
2034
- return t.toStr(p);
2035
-
2036
- }
2037
- case ft_mydatetime:
2038
- {
2039
- myDateTime t(fd.len);
2040
- t.setValue(getFV64(index));
2041
- return t.toStr(p);
2042
- }
2043
- case ft_mytimestamp:
2044
- {
2045
- myTimeStamp ts(fd.len);
2046
- ts.setValue(getFV64(index));
2047
- return ts.toStr(p);
2048
- }
2049
- case ft_decimal:
2050
- case ft_money:
2051
- case ft_numeric:
2052
- case ft_numericsts:
2053
- case ft_numericsa: _ltow_s(fd.decimals, p, 50, 10);
2054
- wcscat(buf, p);
2055
- wcscat(buf, L"lf");
2056
- swprintf(p, 50, buf, getFVdbl(index));
2057
- break;
2058
- case ft_lvar: return NULL;
2059
- case ft_timestamp: return btrTimeStamp(getFV64(index)).toString(p);
2060
- default: p[0] = 0x00;
2061
- }
2062
- return p;
1560
+ return m_impl->fields[index].getFVWstr();
2063
1561
  }
2064
1562
 
2065
1563
  const wchar_t* table::getFVWstr(const _TCHAR* FieldName)
2066
1564
  {
2067
1565
  short index = fieldNumByName(FieldName);
2068
1566
  return getFVWstr(index);
2069
-
2070
1567
  }
2071
1568
  #endif //_WIN32
2072
1569
 
2073
1570
  const char* table::getFVAstr(short index)
2074
1571
  {
2075
- char buf[10] = "%0.";
2076
-
2077
- if (checkIndex(index) == false)
1572
+ if (index == -1)
2078
1573
  return NULL;
2079
- fielddef& fd = m_tableDef->fieldDefs[index];
2080
-
2081
- char* data = (char*)m_pdata + fd.pos;
2082
- switch (fd.type)
2083
- {
2084
-
2085
- case ft_string:
2086
- return read<stringStore, char, char>(data, &m_impl->strBufs, fd, m_impl->cv,
2087
- m_impl->trimPadChar);
2088
- case ft_note:
2089
- case ft_zstring: return read<zstringStore, char, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2090
- case ft_wzstring:
2091
- return read<wzstringStore, WCHAR, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2092
- case ft_wstring:
2093
- return read<wstringStore, WCHAR, char>(data, &m_impl->strBufs, fd, m_impl->cv,
2094
- m_impl->trimPadChar);
2095
- case ft_mychar:
2096
- return read<myCharStore, char, char>(data, &m_impl->strBufs, fd, m_impl->cv,
2097
- m_impl->trimPadChar);
2098
- case ft_myvarchar:
2099
- return read<myVarCharStore, char, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2100
- case ft_lstring:
2101
- case ft_myvarbinary:
2102
- return read<myVarBinaryStore, char, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2103
- case ft_mywchar:
2104
- return read<myWcharStore, WCHAR, char>(data, &m_impl->strBufs, fd, m_impl->cv,
2105
- m_impl->trimPadChar);
2106
- case ft_mywvarchar:
2107
- return read<myWvarCharStore, WCHAR, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2108
- case ft_mywvarbinary:
2109
- return read<myWvarBinaryStore, WCHAR, char>(data, &m_impl->strBufs, fd, m_impl->cv);
2110
- case ft_myblob:
2111
- case ft_mytext: return readBlob<char>(data, &m_impl->strBufs, fd, m_impl->cv);
2112
- }
2113
- char* p = m_impl->strBufs.getPtrA(max(fd.len * 2, 50));
2114
- switch (fd.type)
2115
- {
2116
- case ft_integer:
2117
- case ft_bit:
2118
- case ft_autoinc: _i64toa_s(getFV64(index), p, 50, 10);
2119
- return p;
2120
- case ft_logical:
2121
- if (m_impl->logicalToString)
2122
- {
2123
- if (getFVlng(index))
2124
- return "Yes";
2125
- else
2126
- return "No";
2127
- }
2128
- else
2129
- _i64toa_s(getFV64(index), p, 50, 10);
2130
- break;
2131
- case ft_bfloat:
2132
- case ft_float:
2133
- case ft_currency:
2134
- {
2135
- sprintf(p, "%lf", getFVdbl(index));
2136
- size_t k = strlen(p) - 1;
2137
- while (1)
2138
- {
2139
- if (p[k] == '0')
2140
- p[k] = 0x00;
2141
- else if (p[k] == '.')
2142
- {
2143
- p[k] = 0x00;
2144
- break;
2145
- }
2146
- else
2147
- break;
2148
- k--;
2149
- }
2150
- break;
2151
- }
2152
- case ft_date: return btrdtoa(getFVlng(index), p);
2153
- case ft_time: return btrttoa(getFVlng(index), p);
2154
- case ft_autoIncUnsigned:
2155
- case ft_uinteger:
2156
- sprintf_s(p, 50, "%lu", getFV64(index));
2157
- break;
2158
-
2159
- case ft_mydate:
2160
- {
2161
- myDate d;
2162
- d.setValue((int)getValue64(fd, (const uchar_td*)m_pdata));
2163
- return d.toStr(p, m_impl->myDateTimeValueByBtrv);
2164
- }
2165
- case ft_mytime:
2166
- {
2167
- myTime t(fd.len);
2168
- t.setValue(getValue64(fd, (const uchar_td*)m_pdata));
2169
- return t.toStr(p);
2170
- }
2171
- case ft_mytimestamp:
2172
- {
2173
- myTimeStamp ts(fd.len);
2174
- ts.setValue(getFV64(index));
2175
- return ts.toStr(p);
2176
- }
2177
- case ft_mydatetime:
2178
- {
2179
- myDateTime t(fd.len);
2180
- t.setValue(getFV64(index));
2181
- return t.toStr(p);
2182
- }
2183
- case ft_decimal:
2184
- case ft_money:
2185
- case ft_numeric:
2186
- case ft_numericsts:
2187
- case ft_numericsa: _ltoa_s(fd.decimals, p, 50, 10);
2188
- strcat(buf, p);
2189
- strcat(buf, "lf");
2190
- sprintf_s(p, 50, buf, getFVdbl(index));
2191
- break;
2192
- case ft_lvar: return NULL;
2193
- case ft_timestamp: return btrTimeStamp(getFV64(index)).toString(p);
2194
- default: p[0] = 0x00;
2195
- }
2196
- return p;
1574
+ return m_impl->fields[index].getFVAstr();
2197
1575
  }
2198
1576
 
2199
- int table::getFVint(short index) {return (int)getFVlng(index);}
1577
+ int table::getFVint(short index)
1578
+ {
1579
+ return (int)getFVlng(index);
1580
+ }
2200
1581
 
2201
1582
  int table::getFVint(const _TCHAR* FieldName)
2202
1583
  {
2203
1584
  short index = fieldNumByName(FieldName);
2204
1585
  return (int)getFVlng(index);
2205
-
2206
1586
  }
2207
1587
 
2208
1588
  int table::getFVlng(const _TCHAR* FieldName)
@@ -2291,106 +1671,16 @@ void table::setFV(const _TCHAR* FieldName, __int64 data)
2291
1671
 
2292
1672
  __int64 table::getFV64(short index)
2293
1673
  {
2294
- if (checkIndex(index) == false)
1674
+ if (!checkIndex(index))
2295
1675
  return 0;
2296
- fielddef& fd = m_tableDef->fieldDefs[index];
2297
-
2298
- switch (fd.len)
2299
- {
2300
- case 8:
2301
- switch (fd.type)
2302
- {
2303
- case ft_autoIncUnsigned:
2304
- case ft_uinteger:
2305
- case ft_integer:
2306
- case ft_logical:
2307
- case ft_autoinc:
2308
- case ft_bit:
2309
- case ft_currency:
2310
- case ft_timestamp:
2311
- case ft_mydatetime:
2312
- case ft_mytimestamp: return (__int64) *((__int64*)((char*)m_pdata + fd.pos));
2313
- }
2314
- return 0;
2315
- case 7:
2316
- case 6:
2317
- case 5:
2318
- switch (fd.type)
2319
- {
2320
- case ft_mytime:
2321
- case ft_mydatetime:
2322
- case ft_mytimestamp:
2323
- {
2324
- __int64 v = 0;
2325
- memcpy(&v, (char*)m_pdata + fd.pos, fd.len);
2326
- return v;
2327
- }
2328
- }
2329
- return 0;
2330
- default:
2331
-
2332
- return (__int64) getFVlng(index);
2333
- }
2334
-
1676
+ return m_impl->fields[index].getFV64();
2335
1677
  }
2336
1678
 
2337
1679
  void table::setFV(short index, __int64 data)
2338
1680
  {
2339
- if (checkIndex(index) == false)
1681
+ if (!checkIndex(index))
2340
1682
  return;
2341
-
2342
- fielddef& fd = m_tableDef->fieldDefs[index];
2343
- switch (fd.len)
2344
- {
2345
- case 8:
2346
- switch (fd.type)
2347
- {
2348
- case ft_autoIncUnsigned:
2349
- case ft_uinteger:
2350
- case ft_integer:
2351
- case ft_logical:
2352
- case ft_autoinc:
2353
- case ft_bit:
2354
- case ft_currency:
2355
- case ft_mydatetime:
2356
- case ft_mytimestamp: *((__int64*)((char*)m_pdata + fd.pos)) = data;
2357
- break;
2358
- case ft_timestamp:
2359
- {
2360
- btrDate d;
2361
- d.i = getNowDate();
2362
- btrTime t;
2363
- t.i = getNowTime();
2364
- *((__int64*)((char*)m_pdata + fd.pos)) = btrTimeStamp(d, t).i64;
2365
- break;
2366
- }
2367
- case ft_float:
2368
- {
2369
- double d = (double)data;
2370
- setFV(index, d);
2371
- break;
2372
- }
2373
- }
2374
- break;
2375
- case 7:
2376
- case 6:
2377
- case 5:
2378
- switch (fd.type)
2379
- {
2380
- case ft_mytime:
2381
- case ft_mydatetime:
2382
- case ft_mytimestamp: memcpy((char*)m_pdata + fd.pos, &data, fd.len);
2383
- break;
2384
- default: break;
2385
- }
2386
- break;
2387
- default:
2388
- {
2389
- int value = (int)data;
2390
- setFV(index, value);
2391
- break;
2392
- }
2393
- }
1683
+ m_impl->fields[index].setFV(data);
2394
1684
  }
2395
1685
 
2396
1686
  void table::setFV(const _TCHAR* FieldName, const void* data, uint_td size)
@@ -2404,38 +1694,9 @@ void table::setFV(const _TCHAR* FieldName, const void* data, uint_td size)
2404
1694
  */
2405
1695
  void table::setFV(short index, const void* data, uint_td size)
2406
1696
  {
2407
- if (checkIndex(index) == false)
1697
+ if (!checkIndex(index))
2408
1698
  return;
2409
-
2410
- fielddef& fd = m_tableDef->fieldDefs[index];
2411
-
2412
- switch (fd.type)
2413
- {
2414
- case ft_myvarbinary:
2415
- case ft_myvarchar:
2416
- case ft_mywvarbinary:
2417
- case ft_mywvarchar:
2418
- case ft_lstring:
2419
- {
2420
- int sizeByte = fd.varLenBytes();
2421
- size = std::min<uint_td>((uint_td)(fd.len - sizeByte), size);
2422
- memset((char*)m_pdata + fd.pos, 0, fd.len);
2423
- memcpy((char*)m_pdata + fd.pos, &size, sizeByte);
2424
- memcpy((char*)m_pdata + fd.pos + sizeByte, data, size);
2425
- break;
2426
- }
2427
- case ft_myblob:
2428
- case ft_mytext:
2429
- {
2430
- int sizeByte = fd.len - 8;
2431
- memset((char*)m_pdata + fd.pos, 0, fd.len);
2432
- memcpy((char*)m_pdata + fd.pos, &size, sizeByte);
2433
- memcpy((char*)m_pdata + fd.pos + sizeByte, &data, sizeof(char*));
2434
- break;
2435
-
2436
- }
2437
- default: m_stat = STATUS_FIELDTYPE_NOTSUPPORT; // this field type is not supported.
2438
- }
1699
+ m_impl->fields[index].setFV(data, size);
2439
1700
  }
2440
1701
 
2441
1702
  void* table::getFVbin(const _TCHAR* FieldName, uint_td& size)
@@ -2449,38 +1710,12 @@ void* table::getFVbin(const _TCHAR* FieldName, uint_td& size)
2449
1710
  */
2450
1711
  void* table::getFVbin(short index, uint_td& size)
2451
1712
  {
2452
- if (checkIndex(index) == false)
1713
+ if (!checkIndex(index))
2453
1714
  return NULL;
2454
-
2455
- fielddef& fd = m_tableDef->fieldDefs[index];
2456
-
2457
- switch (fd.type)
2458
- {
2459
- case ft_myvarbinary:
2460
- case ft_myvarchar:
2461
- case ft_mywvarbinary:
2462
- case ft_mywvarchar:
2463
- case ft_lstring:
2464
- {
2465
- int sizeByte = fd.varLenBytes();
2466
- size = 0;
2467
- memcpy(&size, (char*)m_pdata + fd.pos, sizeByte);
2468
- return (void*)((char*)m_pdata + fd.pos + sizeByte);
2469
- }
2470
- case ft_myblob:
2471
- case ft_mytext:
2472
- {
2473
- int sizeByte = fd.len - 8;
2474
- size = 0;
2475
- memcpy(&size, (char*)m_pdata + fd.pos, sizeByte);
2476
- char** ptr = (char**)((char*)m_pdata + fd.pos + sizeByte);
2477
- return (void*)*ptr;
2478
- }
2479
- }
2480
- return NULL;
1715
+ return m_impl->fields[index].getFVbin(size);
2481
1716
  }
2482
1717
 
2483
- bool table::checkIndex(short index)
1718
+ bool table::checkIndex(short index) const
2484
1719
  {
2485
1720
  if ((index >= m_tableDef->fieldCount) || (index < 0))
2486
1721
  {
@@ -2490,206 +1725,6 @@ bool table::checkIndex(short index)
2490
1725
  return true;
2491
1726
  }
2492
1727
 
2493
- double table::getFVDecimal(short index)
2494
- {
2495
- unsigned char buf[20] = {0x00};
2496
- char result[30] = {0x00};
2497
- char n[10];
2498
- int i;
2499
- char* t;
2500
- unsigned char sign;
2501
- int len = m_tableDef->fieldDefs[index].len;
2502
- result[0] = '+';
2503
- memcpy(buf, (void*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos), len);
2504
- sign = (unsigned char)(buf[len - 1] & 0x0F);
2505
- buf[len - 1] = (unsigned char)(buf[len - 1] & 0xF0);
2506
- for (i = 0; i < len; i++)
2507
- {
2508
- sprintf_s(n, 50, "%02x", buf[i]);
2509
- strcat(result, n);
2510
- }
2511
- i = (int)strlen(result);
2512
-
2513
- if (sign == 13)
2514
- result[0] = '-';
2515
- result[i - 1] = 0x00;
2516
-
2517
-
2518
- t = result + (m_tableDef->fieldDefs[index].len * 2) - m_tableDef->fieldDefs[index].decimals;
2519
- strcpy((char*)buf, t);
2520
- *t = '.';
2521
- strcpy(t + 1, (char*)buf);
2522
- return atof(result);
2523
- }
2524
-
2525
- double table::getFVnumeric(short index)
2526
- {
2527
- char* t;
2528
- char dp[] = "{ABCDEFGHI}JKLMNOPQR";
2529
- char dpsa[] = "PQRSTUVWXYpqrstuvwxy";
2530
- char* pdp = NULL;
2531
- char i;
2532
- char buf[20] = {0x00};
2533
- char dummy[20];
2534
-
2535
- buf[0] = '+';
2536
- strncpy(buf + 1, (char*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos),
2537
- m_tableDef->fieldDefs[index].len);
2538
-
2539
- t = &(buf[m_tableDef->fieldDefs[index].len]);
2540
-
2541
- switch (m_tableDef->fieldDefs[index].type)
2542
- {
2543
- case ft_numeric: pdp = dp;
2544
- break;
2545
- case ft_numericsa: pdp = dpsa;
2546
- break;
2547
- case ft_numericsts: buf[0] = *t;
2548
- *t = 0x00;
2549
- break;
2550
- }
2551
-
2552
- if (pdp)
2553
- {
2554
- for (i = 0; i < 21; i++)
2555
- {
2556
- if (*t == pdp[i])
2557
- {
2558
- if (i > 10)
2559
- {
2560
- buf[0] = '-';
2561
- *t = (char)(i + 38);
2562
- }
2563
- else
2564
- *t = (char)(i + 48);
2565
- break;
2566
- }
2567
- }
2568
- }
2569
-
2570
- t = buf + strlen(buf) - m_tableDef->fieldDefs[index].decimals;
2571
- strcpy(dummy, t);
2572
- *t = '.';
2573
- strcpy(t + 1, dummy);
2574
- return atof(buf);
2575
- }
2576
-
2577
- void table::setFVDecimal(short index, double data)
2578
- { // Double -> Decimal
2579
- char buf[30] = "%+0";
2580
- char dummy[30];
2581
- int point;
2582
- bool sign = false;
2583
- unsigned char n;
2584
- int i, k;
2585
- int strl;
2586
- bool offset = false; ;
2587
- point = (m_tableDef->fieldDefs[index].len) * 2;
2588
- _ltoa_s(point, dummy, 30, 10);
2589
- strcat(buf, dummy);
2590
- strcat(buf, ".");
2591
- _ltoa_s(m_tableDef->fieldDefs[index].decimals, dummy, 30, 10);
2592
- strcat(buf, dummy);
2593
- strcat(buf, "lf");
2594
- sprintf(dummy, buf, data);
2595
- if (dummy[0] == '-')
2596
- sign = true;
2597
-
2598
- strl = (int)strlen(dummy + 1) - 1;
2599
- if (strl % 2 == 1)
2600
- strl = strl / 2;
2601
- else
2602
- {
2603
- strl = strl / 2 + 1;
2604
- offset = true;
2605
- }
2606
- memset(buf, 0, 30);
2607
- k = 0;
2608
- n = 0;
2609
- point = (int)strlen(dummy + 1);
2610
- if (strl <= m_tableDef->fieldDefs[index].len)
2611
- {
2612
- for (i = 1; i <= point; i++)
2613
- {
2614
- if ((dummy[i] == '-') || (dummy[i] == '.'));
2615
- else
2616
- {
2617
- if (offset)
2618
- {
2619
- n = (unsigned char)(n + dummy[i] - 48);
2620
- buf[k] = n;
2621
- offset = false;
2622
- k++;
2623
- }
2624
- else
2625
- {
2626
- n = (unsigned char)(dummy[i] - 48);
2627
- n = (unsigned char)(n << 4);
2628
- offset = true; ;
2629
- }
2630
- }
2631
- }
2632
- if (sign)
2633
- buf[k] += ((unsigned char)(n + 13));
2634
- else
2635
- buf[k] += ((unsigned char)(n + 12));
2636
- }
2637
- memcpy((void*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos), buf,
2638
- m_tableDef->fieldDefs[index].len);
2639
-
2640
- }
2641
-
2642
- void table::setFVNumeric(short index, double data)
2643
- { // Double -> Numeric
2644
- char buf[30] = "%+0";
2645
- char dummy[30];
2646
- int point;
2647
- int n;
2648
- char dp[] = "{ABCDEFGHI}JKLMNOPQR";
2649
- char dpsa[] = "PQRSTUVWXYpqrstuvwxy";
2650
- bool sign = false;
2651
- char* t;
2652
-
2653
- point = m_tableDef->fieldDefs[index].len + 1;
2654
-
2655
- _ltoa_s(point, dummy, 30, 10);
2656
- strcat(buf, dummy);
2657
- strcat(buf, ".");
2658
- _ltoa_s(m_tableDef->fieldDefs[index].decimals, dummy, 30, 10);
2659
- strcat(buf, dummy);
2660
- strcat(buf, "lf");
2661
- sprintf(dummy, buf, data);
2662
- if (dummy[0] == '-')
2663
- sign = true;
2664
-
2665
-
2666
- strcpy(buf, &dummy[point - m_tableDef->fieldDefs[index].decimals] + 1);
2667
- dummy[point - m_tableDef->fieldDefs[index].decimals] = 0x00;
2668
- strcat(dummy, buf);
2669
-
2670
- n = atol(&dummy[m_tableDef->fieldDefs[index].len]);
2671
- if (sign)
2672
- n += 10;
2673
- t = dummy + 1;
2674
- switch (m_tableDef->fieldDefs[index].type)
2675
- {
2676
- case ft_numeric: dummy[m_tableDef->fieldDefs[index].len] = dp[n];
2677
- break;
2678
- case ft_numericsa: dummy[m_tableDef->fieldDefs[index].len] = dpsa[n];
2679
- break;
2680
- case ft_numericsts:
2681
- if (sign)
2682
- strcat(dummy, "-");
2683
- else
2684
- strcat(dummy, "+");
2685
- t += 1;
2686
- break;
2687
- }
2688
-
2689
- memcpy((void*)((char*)m_pdata + m_tableDef->fieldDefs[index].pos), t,
2690
- m_tableDef->fieldDefs[index].len);
2691
- }
2692
-
2693
1728
  unsigned int table::getRecordHash()
2694
1729
  {
2695
1730
  return hash((const char*)fieldPtr(0), datalen());
@@ -2720,17 +1755,37 @@ short_td table::doBtrvErr(HWND hWnd, _TCHAR* retbuf)
2720
1755
  /* For keyValueDescription */
2721
1756
  bool table::setSeekValueField(int row)
2722
1757
  {
2723
- const std::vector<std::_tstring>& keyValues = m_impl->filterPtr->keyValuesCache();
1758
+ const std::vector<client::seek>& keyValues = m_impl->filterPtr->seeks();
2724
1759
  keydef* kd = &tableDef()->keyDefs[keyNum()];
2725
1760
  if (keyValues.size() % kd->segmentCount)
2726
1761
  return false;
2727
- //Check uniqe key
1762
+ // Check uniqe key
2728
1763
  if (kd->segments[0].flags.bit0)
2729
1764
  return false;
2730
1765
 
2731
- size_t pos = kd->segmentCount * row;
2732
- for (int j=0;j<kd->segmentCount;++j)
2733
- setFV(kd->segments[j].fieldNum, keyValues[pos+j].c_str());
1766
+ const uchar_td* ptr = (const uchar_td*)keyValues[row].data;
1767
+ const uchar_td* data;
1768
+ ushort_td dataSize;
1769
+ if (ptr)
1770
+ {
1771
+ for (int j = 0; j < kd->segmentCount; ++j)
1772
+ {
1773
+ short filedNum = kd->segments[j].fieldNum;
1774
+ fielddef& fd = tableDef()->fieldDefs[filedNum];
1775
+ ptr = fd.getKeyValueFromKeybuf(ptr, &data, dataSize);
1776
+ if (data)
1777
+ {
1778
+ if (fd.maxVarDatalen())
1779
+ setFV(filedNum, data, dataSize);
1780
+ else
1781
+ memcpy(fieldPtr(filedNum), data, dataSize);
1782
+ }
1783
+ else
1784
+ setFV(filedNum, _T(""));
1785
+ }
1786
+ }
1787
+ else
1788
+ return false;
2734
1789
  return true;
2735
1790
  }
2736
1791
 
@@ -2738,100 +1793,111 @@ void table::keyValueDescription(_TCHAR* buf, int bufsize)
2738
1793
  {
2739
1794
 
2740
1795
  std::_tstring s;
2741
- if (stat() == STATUS_NOT_FOUND_TI)
2742
- {
2743
-
2744
- for (int i=0;i<tableDef()->keyDefs[keyNum()].segmentCount;i++)
2745
- {
2746
- short fnum = tableDef()->keyDefs[keyNum()].segments[i].fieldNum;
2747
- s += std::_tstring(tableDef()->fieldDefs[fnum].name())
2748
- + _T(" = ") + getFVstr(fnum) + _T("\n");
2749
- }
2750
- }
1796
+ if (stat() == STATUS_NOT_FOUND_TI)
1797
+ {
1798
+
1799
+ for (int i = 0; i < tableDef()->keyDefs[keyNum()].segmentCount; i++)
1800
+ {
1801
+ short fnum = tableDef()->keyDefs[keyNum()].segments[i].fieldNum;
1802
+ s += std::_tstring(tableDef()->fieldDefs[fnum].name()) + _T(" = ") +
1803
+ getFVstr(fnum) + _T("\n");
1804
+ }
1805
+ }
2751
1806
  else if (stat() == STATUS_DUPPLICATE_KEYVALUE)
2752
- {
1807
+ {
2753
1808
  _TCHAR tmp[50];
2754
- for (int j=0;j<tableDef()->keyCount;j++)
2755
- {
2756
- _stprintf_s(tmp, 50, _T("[key%d]\n"), j);
2757
- s += tmp;
2758
- for (int i=0;i<tableDef()->keyDefs[j].segmentCount;i++)
2759
- {
2760
- short fnum = tableDef()->keyDefs[j].segments[i].fieldNum;
2761
- s += std::_tstring(tableDef()->fieldDefs[fnum].name())
2762
- + _T(" = ") + getFVstr(fnum) + _T("\n");
2763
- }
2764
- }
1809
+ for (int j = 0; j < tableDef()->keyCount; j++)
1810
+ {
1811
+ _stprintf_s(tmp, 50, _T("[key%d]\n"), j);
1812
+ s += tmp;
1813
+ for (int i = 0; i < tableDef()->keyDefs[j].segmentCount; i++)
1814
+ {
1815
+ short fnum = tableDef()->keyDefs[j].segments[i].fieldNum;
1816
+ s += std::_tstring(tableDef()->fieldDefs[fnum].name()) +
1817
+ _T(" = ") + getFVstr(fnum) + _T("\n");
1818
+ }
1819
+ }
1820
+ }
2765
1821
 
2766
- }
1822
+ _stprintf_s(buf, bufsize, _T("table:%s\nstat:%d\n%s"),
1823
+ tableDef()->tableName(), stat(), s.c_str());
1824
+ }
2767
1825
 
2768
- _stprintf_s(buf, bufsize, _T("table:%s\nstat:%d\n%s")
2769
- ,tableDef()->tableName()
2770
- ,stat()
2771
- ,s.c_str());
1826
+ short table::getCurProcFieldCount() const
1827
+ {
1828
+ if (!m_impl->filterPtr || !m_impl->filterPtr->fieldSelected())
1829
+ return tableDef()->fieldCount;
1830
+ return (short)m_impl->filterPtr->selectFieldIndexes().size();
2772
1831
  }
2773
1832
 
1833
+ short table::getCurProcFieldIndex(short index) const
1834
+ {
1835
+ if (!m_impl->filterPtr || !m_impl->filterPtr->fieldSelected())
1836
+ return index;
1837
+ return m_impl->filterPtr->selectFieldIndexes()[index];
1838
+ }
2774
1839
 
2775
1840
  //-------------------------------------------------------------------
2776
1841
  // class queryBase
2777
1842
  //-------------------------------------------------------------------
2778
1843
  typedef boost::escaped_list_separator<_TCHAR> esc_sep;
2779
- typedef boost::tokenizer<esc_sep
2780
- ,std::_tstring::const_iterator
2781
- ,std::_tstring> tokenizer;
1844
+ typedef boost::tokenizer<esc_sep, std::_tstring::const_iterator, std::_tstring>
1845
+ tokenizer;
2782
1846
 
2783
- void analyzeQuery(const _TCHAR* str
2784
- , std::vector<std::_tstring>& selects
2785
- , std::vector<std::_tstring>& where
2786
- , std::vector<std::_tstring>& keyValues
2787
- ,bool& nofilter)
1847
+ void analyzeQuery(const _TCHAR* str, std::vector<std::_tstring>& selects,
1848
+ std::vector<std::_tstring>& where,
1849
+ std::vector<std::_tstring>& keyValues, bool& nofilter)
2788
1850
  {
2789
1851
  esc_sep sep(_T('&'), _T(' '), _T('\''));
2790
1852
  std::_tstring s = str;
1853
+ std::_tstring tmp;
2791
1854
  tokenizer tokens(s, sep);
2792
1855
 
2793
1856
  tokenizer::iterator it = tokens.begin();
2794
- if (it == tokens.end()) return;
1857
+ if (it == tokens.end())
1858
+ return;
2795
1859
  if (*it == _T("*"))
2796
1860
  {
2797
1861
  nofilter = true;
2798
1862
  return;
2799
1863
  }
2800
- s = *it;
2801
- boost::algorithm::to_lower(s);
2802
- if (s == _T("select"))
1864
+ tmp = *it;
1865
+ boost::algorithm::to_lower(tmp);
1866
+ if (tmp == _T("select"))
2803
1867
  {
2804
1868
  tokenizer::iterator itTmp = it;
2805
- s = *(++it);
2806
- if (getFilterLogicTypeCode(s.c_str())==255)
1869
+ tmp = *(++it);
1870
+ if (getFilterLogicTypeCode(tmp.c_str()) == 255)
2807
1871
  {
2808
1872
  esc_sep sep(_T('&'), _T(','), _T('\''));
2809
- tokenizer fields(s, sep);
1873
+ tokenizer fields(tmp, sep);
2810
1874
  tokenizer::iterator itf = fields.begin();
2811
1875
  while (itf != fields.end())
2812
1876
  selects.push_back(*(itf++));
2813
1877
  ++it;
2814
- }else
1878
+ }
1879
+ else
2815
1880
  it = itTmp; // field name is select
2816
1881
  }
2817
1882
  if (it == tokens.end())
2818
1883
  return;
2819
- s = *it;
2820
- boost::algorithm::to_lower(s);
1884
+ tmp = *it;
1885
+ boost::algorithm::to_lower(tmp);
2821
1886
  bool enableWhere = true;
2822
- if (s == _T("in"))
1887
+ if (tmp == _T("in"))
2823
1888
  {
2824
1889
  tokenizer::iterator itTmp = it;
2825
- s = *(++it);
2826
- if (getFilterLogicTypeCode(s.c_str())==255)
1890
+ tmp = *(++it);
1891
+ if (getFilterLogicTypeCode(tmp.c_str()) == 255)
2827
1892
  {
2828
1893
  enableWhere = false;
2829
1894
  esc_sep sep(_T('&'), _T(','), _T('\''));
2830
- tokenizer values(s, sep);
1895
+ tokenizer values(tmp, sep);
2831
1896
  tokenizer::iterator itf = values.begin();
2832
1897
  while (itf != values.end())
2833
1898
  keyValues.push_back(*(itf++));
2834
- }else
1899
+ }
1900
+ else
2835
1901
  it = itTmp; // field name is in
2836
1902
  }
2837
1903
  if (enableWhere)
@@ -2839,28 +1905,67 @@ void analyzeQuery(const _TCHAR* str
2839
1905
  while (it != tokens.end())
2840
1906
  where.push_back(*(it++));
2841
1907
  }
1908
+ }
2842
1909
 
1910
+ keyValuePtr::keyValuePtr(const void* p, ushort_td l, short typeStr)
1911
+ : len(l), type(typeStr)
1912
+ {
1913
+ if (type & KEYVALUE_NEED_COPY)
1914
+ {
1915
+ _TCHAR* tmp = new _TCHAR[len + 1];
1916
+ _tcsncpy(tmp, (_TCHAR*)p, len);
1917
+ tmp[len] = 0x00;
1918
+ ptr = tmp;
1919
+ }
1920
+ else
1921
+ ptr = p;
2843
1922
  }
2844
1923
 
1924
+ keyValuePtr::~keyValuePtr()
1925
+ {
1926
+ if (type & KEYVALUE_NEED_COPY)
1927
+ delete[](_TCHAR*)ptr;
1928
+ }
2845
1929
 
2846
1930
  struct impl
2847
1931
  {
2848
- impl():
2849
- m_reject(1),m_limit(0),m_direction(table::findForword)
2850
- ,m_nofilter(false),m_optimize(false){}
1932
+ impl()
1933
+ : m_reject(1), m_limit(0), m_joinKeySize(0),
1934
+ m_optimize(queryBase::none), m_direction(table::findForword),
1935
+ m_nofilter(false), m_withBookmark(false)
1936
+ {
1937
+ }
2851
1938
 
2852
- int m_reject;
2853
- int m_limit;
2854
- table::eFindType m_direction;
2855
- bool m_nofilter;
2856
- bool m_optimize;
2857
1939
  mutable std::_tstring m_str;
2858
1940
  std::vector<std::_tstring> m_selects;
2859
1941
  std::vector<std::_tstring> m_wheres;
2860
1942
  std::vector<std::_tstring> m_keyValues;
1943
+ std::vector<keyValuePtr> m_keyValuesPtr;
1944
+ int m_reject;
1945
+ int m_limit;
1946
+ int m_joinKeySize;
1947
+ queryBase::eOptimize m_optimize;
1948
+ table::eFindType m_direction;
1949
+ bool m_nofilter;
1950
+ bool m_withBookmark;
2861
1951
  };
2862
1952
 
2863
- queryBase::queryBase():m_impl(new impl){}
1953
+ queryBase::queryBase() : m_impl(new impl)
1954
+ {
1955
+ }
1956
+
1957
+ queryBase::queryBase(const queryBase& r) : m_impl(new impl(*r.m_impl))
1958
+ {
1959
+ }
1960
+
1961
+ queryBase& queryBase::operator=(const queryBase& r)
1962
+ {
1963
+ if (this != &r)
1964
+ {
1965
+ *m_impl = *r.m_impl;
1966
+ }
1967
+ return *this;
1968
+ }
2864
1969
 
2865
1970
  queryBase::~queryBase()
2866
1971
  {
@@ -2884,26 +1989,36 @@ void queryBase::addField(const _TCHAR* name)
2884
1989
  m_impl->m_nofilter = false;
2885
1990
  }
2886
1991
 
2887
- void queryBase::addLogic(const _TCHAR* name, const _TCHAR* logic, const _TCHAR* value)
1992
+ void queryBase::addLogic(const _TCHAR* name, const _TCHAR* logic,
1993
+ const _TCHAR* value)
2888
1994
  {
1995
+ m_impl->m_keyValuesPtr.clear();
2889
1996
  m_impl->m_keyValues.clear();
2890
1997
  m_impl->m_wheres.clear();
2891
1998
  m_impl->m_wheres.push_back(name);
2892
1999
  m_impl->m_wheres.push_back(logic);
2893
2000
  m_impl->m_wheres.push_back(value);
2894
2001
  m_impl->m_nofilter = false;
2895
-
2896
2002
  }
2897
2003
 
2898
- void queryBase::addLogic(const _TCHAR* combine, const _TCHAR* name
2899
- , const _TCHAR* logic, const _TCHAR* value)
2004
+ void queryBase::addLogic(const _TCHAR* combine, const _TCHAR* name,
2005
+ const _TCHAR* logic, const _TCHAR* value)
2900
2006
  {
2901
2007
  m_impl->m_wheres.push_back(combine);
2902
2008
  m_impl->m_wheres.push_back(name);
2903
2009
  m_impl->m_wheres.push_back(logic);
2904
2010
  m_impl->m_wheres.push_back(value);
2905
2011
  m_impl->m_nofilter = false;
2012
+ }
2906
2013
 
2014
+ void queryBase::reserveSeekKeyValueSize(size_t v)
2015
+ {
2016
+ m_impl->m_keyValues.reserve(v);
2017
+ }
2018
+
2019
+ void queryBase::reserveSeekKeyValuePtrSize(size_t v)
2020
+ {
2021
+ m_impl->m_keyValuesPtr.reserve(v);
2907
2022
  }
2908
2023
 
2909
2024
  void queryBase::addSeekKeyValue(const _TCHAR* value, bool reset)
@@ -2912,27 +2027,91 @@ void queryBase::addSeekKeyValue(const _TCHAR* value, bool reset)
2912
2027
  {
2913
2028
  m_impl->m_wheres.clear();
2914
2029
  m_impl->m_keyValues.clear();
2030
+ m_impl->m_keyValuesPtr.clear();
2915
2031
  }
2916
2032
  m_impl->m_keyValues.push_back(value);
2917
- //m_impl->m_reject = 1;
2033
+ // m_impl->m_reject = 1;
2918
2034
  m_impl->m_nofilter = false;
2035
+ }
2919
2036
 
2037
+ void queryBase::addSeekKeyValuePtr(const void* value, ushort_td len,
2038
+ short typeStr, bool reset)
2039
+ {
2040
+ if (reset)
2041
+ {
2042
+ m_impl->m_wheres.clear();
2043
+ m_impl->m_keyValues.clear();
2044
+ m_impl->m_keyValuesPtr.clear();
2045
+ }
2046
+ m_impl->m_keyValuesPtr.push_back(keyValuePtr(value, len, typeStr));
2047
+ m_impl->m_nofilter = false;
2920
2048
  }
2921
2049
 
2922
2050
  void queryBase::clearSeekKeyValues()
2923
2051
  {
2924
2052
  m_impl->m_keyValues.clear();
2053
+ m_impl->m_keyValuesPtr.clear();
2054
+ }
2055
+
2056
+ std::_tstring escape_value(std::_tstring s)
2057
+ {
2058
+ for (int i = (int)s.size() - 1; i >= 0; --i)
2059
+ {
2060
+ if (s[i] == _T('&'))
2061
+ s.insert(s.begin() + i, _T('&'));
2062
+ else if (s[i] == _T('\''))
2063
+ s.insert(s.begin() + i, _T('&'));
2064
+ }
2065
+ return s;
2925
2066
  }
2926
2067
 
2927
- queryBase& queryBase::queryString(const _TCHAR* str)
2068
+ std::_tstring& escape_string(std::_tstring& s)
2069
+ {
2070
+ bool begin = false;
2071
+ for (int i = 0; i < (int)s.size(); ++i)
2072
+ {
2073
+ if (s[i] == _T('&'))
2074
+ {
2075
+ s.insert(s.begin() + i, _T('&'));
2076
+ ++i;
2077
+ }
2078
+ else if (s[i] == _T('\''))
2079
+ {
2080
+ if (begin)
2081
+ {
2082
+ if ((i == (int)s.size() - 1) || (s[i + 1] == _T(' ')))
2083
+ begin = false;
2084
+ else
2085
+ s.insert(s.begin() + i, _T('&'));
2086
+ ++i;
2087
+ }
2088
+ else if ((i == 0) || (s[i - 1] == _T(' ')))
2089
+ begin = true;
2090
+ else
2091
+ {
2092
+ s.insert(s.begin() + i, _T('&'));
2093
+ ++i;
2094
+ }
2095
+ }
2096
+ }
2097
+ return s;
2098
+ }
2099
+
2100
+ queryBase& queryBase::queryString(const _TCHAR* str, bool autoEscape)
2928
2101
  {
2929
2102
  m_impl->m_selects.clear();
2930
2103
  m_impl->m_wheres.clear();
2931
2104
  m_impl->m_keyValues.clear();
2932
2105
  m_impl->m_nofilter = false;
2933
2106
  if (str && str[0])
2934
- analyzeQuery(str, m_impl->m_selects, m_impl->m_wheres, m_impl->m_keyValues
2935
- ,m_impl->m_nofilter);
2107
+ {
2108
+ std::_tstring s = str;
2109
+ boost::trim(s);
2110
+ if (autoEscape)
2111
+ escape_string(s);
2112
+ analyzeQuery(s.c_str(), m_impl->m_selects, m_impl->m_wheres,
2113
+ m_impl->m_keyValues, m_impl->m_nofilter);
2114
+ }
2936
2115
  return *this;
2937
2116
  }
2938
2117
 
@@ -2961,30 +2140,42 @@ queryBase& queryBase::all()
2961
2140
  return *this;
2962
2141
  }
2963
2142
 
2964
- queryBase& queryBase::optimize(bool v)
2143
+ queryBase& queryBase::optimize(queryBase::eOptimize v)
2965
2144
  {
2966
2145
  m_impl->m_optimize = v;
2967
- return *this;
2146
+ return *this;
2968
2147
  }
2969
2148
 
2970
- bool queryBase::isOptimize()const
2149
+ queryBase::eOptimize queryBase::getOptimize() const
2971
2150
  {
2972
2151
  return m_impl->m_optimize;
2973
2152
  }
2974
2153
 
2975
- table::eFindType queryBase::getDirection() const {return m_impl->m_direction;}
2154
+ queryBase& queryBase::bookmarkAlso(bool v)
2155
+ {
2156
+ m_impl->m_withBookmark = v;
2157
+ return *this;
2158
+ }
2976
2159
 
2977
- std::_tstring escape_value(std::_tstring s)
2160
+ bool queryBase::isBookmarkAlso() const
2978
2161
  {
2979
- std::_tstring::iterator it = s.begin();
2980
- for (int i=(int)s.size()-1;i>=0;--i)
2981
- {
2982
- if (s[i] == _T('&'))
2983
- s.insert(s.begin()+i, _T('&'));
2984
- else if (s[i] == _T('\''))
2985
- s.insert(s.begin()+i, _T('&'));
2986
- }
2987
- return s;
2162
+ return m_impl->m_withBookmark;
2163
+ }
2164
+
2165
+ queryBase& queryBase::joinKeySize(int v)
2166
+ {
2167
+ m_impl->m_joinKeySize = v;
2168
+ return *this;
2169
+ }
2170
+
2171
+ int queryBase::getJoinKeySize() const
2172
+ {
2173
+ return m_impl->m_joinKeySize;
2174
+ }
2175
+
2176
+ table::eFindType queryBase::getDirection() const
2177
+ {
2178
+ return m_impl->m_direction;
2988
2179
  }
2989
2180
 
2990
2181
  const _TCHAR* queryBase::toString() const
@@ -3000,43 +2191,118 @@ const _TCHAR* queryBase::toString() const
3000
2191
  if (selects.size())
3001
2192
  {
3002
2193
  s = _T("select ");
3003
- for (int i= 0;i < (int)selects.size();++i)
2194
+ for (int i = 0; i < (int)selects.size(); ++i)
3004
2195
  s += selects[i] + _T(",");
3005
2196
 
3006
2197
  if (s.size())
3007
- s.replace(s.size()-1,1, _T(" "));
2198
+ s.replace(s.size() - 1, 1, _T(" "));
3008
2199
  }
3009
2200
 
3010
- for (size_t i= 0;i < wheres.size();i+=4)
2201
+ for (size_t i = 0; i < wheres.size(); i += 4)
3011
2202
  {
3012
- s += wheres[i] + _T(" ") + wheres[i+1] + _T(" '")
3013
- + escape_value(wheres[i+2]) + _T("' ");
3014
- if (i+3 < wheres.size())
3015
- s += wheres[i+3] + _T(" ");
2203
+ if (i + 1 < wheres.size())
2204
+ s += wheres[i] + _T(" ") + wheres[i + 1];
2205
+ if (i + 2 < wheres.size())
2206
+ s += _T(" '") + escape_value(wheres[i + 2]) + _T("' ");
2207
+ if (i + 3 < wheres.size())
2208
+ s += wheres[i + 3] + _T(" ");
3016
2209
  }
3017
2210
 
3018
2211
  if (keyValues.size())
3019
2212
  {
3020
2213
  s += _T("in ");
3021
- for (size_t i= 0;i < keyValues.size();++i)
2214
+ for (size_t i = 0; i < keyValues.size(); ++i)
3022
2215
  s += _T("'") + escape_value(keyValues[i]) + _T("',");
3023
2216
  }
3024
2217
  if (s.size())
3025
- s.erase(s.end() -1);
3026
-
2218
+ s.erase(s.end() - 1);
3027
2219
 
3028
2220
  return s.c_str();
3029
2221
  }
3030
2222
 
3031
- int queryBase::getReject()const{return m_impl->m_reject;}
2223
+ int queryBase::getReject() const
2224
+ {
2225
+ return m_impl->m_reject;
2226
+ }
3032
2227
 
3033
- int queryBase::getLimit()const{return m_impl->m_limit;}
2228
+ int queryBase::getLimit() const
2229
+ {
2230
+ return m_impl->m_limit;
2231
+ }
3034
2232
 
3035
- bool queryBase::isAll()const{return m_impl->m_nofilter;};
2233
+ bool queryBase::isAll() const
2234
+ {
2235
+ return m_impl->m_nofilter;
2236
+ };
3036
2237
 
3037
- const std::vector<std::_tstring>& queryBase::getSelects() const {return m_impl->m_selects;}
3038
- const std::vector<std::_tstring>& queryBase::getWheres() const {return m_impl->m_wheres;}
3039
- const std::vector<std::_tstring>& queryBase::getSeekKeyValues() const{return m_impl->m_keyValues;}
2238
+ const std::vector<std::_tstring>& queryBase::getSelects() const
2239
+ {
2240
+ return m_impl->m_selects;
2241
+ }
2242
+ const std::vector<std::_tstring>& queryBase::getWheres() const
2243
+ {
2244
+ return m_impl->m_wheres;
2245
+ }
2246
+ const std::vector<std::_tstring>& queryBase::getSeekKeyValues() const
2247
+ {
2248
+ return m_impl->m_keyValues;
2249
+ }
2250
+ const std::vector<keyValuePtr>& queryBase::getSeekValuesPtr() const
2251
+ {
2252
+ return m_impl->m_keyValuesPtr;
2253
+ }
2254
+ short queryBase::selectCount() const
2255
+ {
2256
+ return (short)m_impl->m_selects.size();
2257
+ }
2258
+
2259
+ const _TCHAR* queryBase::getSelect(short index) const
2260
+ {
2261
+ assert((index >= 0) && (index < (short)m_impl->m_selects.size()));
2262
+ return m_impl->m_selects[index].c_str();
2263
+ }
2264
+
2265
+ short queryBase::whereTokens() const
2266
+ {
2267
+ return (short)m_impl->m_wheres.size();
2268
+ }
2269
+
2270
+ const _TCHAR* queryBase::getWhereToken(short index) const
2271
+ {
2272
+ assert((index >= 0) && (index < (short)m_impl->m_wheres.size()));
2273
+ return m_impl->m_wheres[index].c_str();
2274
+ }
2275
+
2276
+ void queryBase::setWhereToken(short index, const _TCHAR* v)
2277
+ {
2278
+ assert((index >= 0) && (index < (short)m_impl->m_wheres.size()));
2279
+ m_impl->m_wheres[index] = v;
2280
+ }
2281
+
2282
+ /* alias field name change to original field name */
2283
+ void queryBase::reverseAliasName(const _TCHAR* alias, const _TCHAR* src)
2284
+ {
2285
+ std::vector<std::_tstring>& selects = m_impl->m_selects;
2286
+ std::vector<std::_tstring>& wheres = m_impl->m_wheres;
2287
+ std::_tstring s;
2288
+ for (size_t i = 0; i < wheres.size(); i += 4)
2289
+ {
2290
+ if (wheres[i] == alias)
2291
+ wheres[i] = src;
2292
+ if (i + 2 < wheres.size())
2293
+ {
2294
+ s = src;
2295
+ s.insert(0, _T("["));
2296
+ s += _T("[");
2297
+ if (wheres[i + 2] == s)
2298
+ wheres[i + 2] = s;
2299
+ }
2300
+ }
2301
+
2302
+ for (size_t i = 0; i < selects.size(); ++i)
2303
+ if (selects[i] == alias)
2304
+ selects[i] = src;
2305
+ }
3040
2306
 
3041
2307
  void queryBase::release()
3042
2308
  {
@@ -3046,12 +2312,10 @@ void queryBase::release()
3046
2312
  queryBase* queryBase::create()
3047
2313
  {
3048
2314
  return new queryBase();
3049
-
3050
2315
  }
3051
2316
 
3052
-
3053
- }// namespace client
3054
- }// namespace tdap
3055
- }// namespace protocol
3056
- }// namespace db
3057
- }// namespace bzs
2317
+ } // namespace client
2318
+ } // namespace tdap
2319
+ } // namespace protocol
2320
+ } // namespace db
2321
+ } // namespace bzs