transactd 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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