transactd 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD_UNIX-JA +6 -6
  3. data/README +16 -16
  4. data/README-JA +16 -16
  5. data/bin/common/tdclc_32_2_1.dll +0 -0
  6. data/bin/common/tdclc_64_2_1.dll +0 -0
  7. data/build/common/transactd_cl_common.cmake +0 -1
  8. data/build/common/transactd_common.cmake +28 -38
  9. data/build/swig/ruby/ruby.swg +36 -30
  10. data/build/swig/ruby/tdclrb_wrap.cpp +35016 -0
  11. data/build/swig/tdcl.i +217 -62
  12. data/build/tdclc/CMakeLists.txt +14 -26
  13. data/build/tdclc/libtdclcm.map +4 -0
  14. data/build/tdclc/tdclc.cbproj +1 -1
  15. data/build/tdclc/tdclc.rc +0 -0
  16. data/build/tdclcpp/CMakeLists.txt +7 -22
  17. data/build/tdclcpp/tdclcpp.rc +0 -0
  18. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  19. data/build/tdclrb/CMakeLists.txt +7 -49
  20. data/build/tdclrb/tdclrb.rc +62 -0
  21. data/source/bzs/db/blobBuffer.h +5 -0
  22. data/source/bzs/db/blobStructs.h +2 -0
  23. data/source/bzs/db/engine/mysql/IReadRecords.h +9 -0
  24. data/source/bzs/db/engine/mysql/database.cpp +391 -169
  25. data/source/bzs/db/engine/mysql/database.h +178 -40
  26. data/source/bzs/db/engine/mysql/dbManager.cpp +45 -3
  27. data/source/bzs/db/engine/mysql/dbManager.h +3 -39
  28. data/source/bzs/db/engine/mysql/errorMessage.cpp +11 -7
  29. data/source/bzs/db/engine/mysql/errorMessage.h +1 -1
  30. data/source/bzs/db/engine/mysql/mydebuglog.cpp +1 -2
  31. data/source/bzs/db/engine/mysql/mysqlInternal.h +8 -8
  32. data/source/bzs/db/engine/mysql/mysqlThd.cpp +11 -0
  33. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +1 -1
  34. data/source/bzs/db/protocol/tdap/client/activeTable.cpp +41 -6
  35. data/source/bzs/db/protocol/tdap/client/activeTable.h +177 -8
  36. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +141 -62
  37. data/source/bzs/db/protocol/tdap/client/client.cpp +39 -35
  38. data/source/bzs/db/protocol/tdap/client/client.h +52 -25
  39. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +17 -0
  40. data/source/bzs/db/protocol/tdap/client/connectionPool.h +1 -0
  41. data/source/bzs/db/protocol/tdap/client/database.cpp +5 -1
  42. data/source/bzs/db/protocol/tdap/client/database.h +1 -1
  43. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +49 -12
  44. data/source/bzs/db/protocol/tdap/client/databaseManager.h +42 -5
  45. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +4 -2
  46. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +71 -41
  47. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +49 -49
  48. data/source/bzs/db/protocol/tdap/client/field.cpp +22 -13
  49. data/source/bzs/db/protocol/tdap/client/field.h +7 -3
  50. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +1 -1
  51. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.cpp +0 -1
  52. data/source/bzs/db/protocol/tdap/client/fieldNameAlias.h +1 -0
  53. data/source/bzs/db/protocol/tdap/client/fields.h +111 -24
  54. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +1 -1
  55. data/source/bzs/db/protocol/tdap/client/filter.h +687 -310
  56. data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +12 -4
  57. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +1 -1
  58. data/source/bzs/db/protocol/tdap/client/memRecord.cpp +190 -32
  59. data/source/bzs/db/protocol/tdap/client/memRecord.h +64 -22
  60. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +4 -4
  61. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -2
  62. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +6 -3
  63. data/source/bzs/db/protocol/tdap/client/nsTable.h +1 -1
  64. data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +19 -8
  65. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +194 -87
  66. data/source/bzs/db/protocol/tdap/client/request.h +84 -26
  67. data/source/bzs/db/protocol/tdap/client/stringConverter.h +22 -12
  68. data/source/bzs/db/protocol/tdap/client/table.cpp +494 -286
  69. data/source/bzs/db/protocol/tdap/client/table.h +48 -5
  70. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +133 -87
  71. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +22 -22
  72. data/source/bzs/db/protocol/tdap/client/trdormapi.h +43 -18
  73. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +3 -3
  74. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +1 -0
  75. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +268 -74
  76. data/source/bzs/db/protocol/tdap/mysql/request.h +4 -4
  77. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +179 -43
  78. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +4 -4
  79. data/source/bzs/db/protocol/tdap/tdapRequest.h +15 -14
  80. data/source/bzs/db/protocol/tdap/tdapSchema.h +125 -90
  81. data/source/bzs/db/protocol/tdap/tdapcapi.h +46 -5
  82. data/source/bzs/db/transactd/appModule.h +1 -1
  83. data/source/bzs/db/transactd/connManager.cpp +2 -0
  84. data/source/bzs/db/transactd/transactd.cpp +1 -0
  85. data/source/bzs/env/compiler.h +10 -0
  86. data/source/bzs/env/mbcswchrLinux.cpp +42 -6
  87. data/source/bzs/env/mbcswchrLinux.h +40 -12
  88. data/source/bzs/example/queryData.cpp +33 -4
  89. data/source/bzs/netsvc/client/iconnection.h +107 -0
  90. data/source/bzs/netsvc/client/tcpClient.cpp +15 -1
  91. data/source/bzs/netsvc/client/tcpClient.h +96 -87
  92. data/source/bzs/netsvc/server/serverCpt.cpp +5 -6
  93. data/source/bzs/rtl/benchmark.cpp +2 -2
  94. data/source/bzs/rtl/stringBuffers.cpp +3 -3
  95. data/source/bzs/rtl/stringBuffers.h +2 -2
  96. data/source/bzs/test/tdclatl/bench_query_atl.js +92 -99
  97. data/source/bzs/test/tdclatl/test_query_atl.js +224 -115
  98. data/source/bzs/test/tdclphp/bench.php +126 -101
  99. data/source/bzs/test/tdclphp/transactd_Test.php +1122 -158
  100. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +12 -14
  101. data/source/bzs/test/tdclrb/transactd_spec.rb +1127 -142
  102. data/source/bzs/test/transactdBench/query_bench.cpp +32 -15
  103. data/source/bzs/test/transactdBench/scaling_bench.cpp +32 -7
  104. data/source/bzs/test/transactdBench/transactdBench.cpp +1 -1
  105. data/source/bzs/test/transactdBench/workerBase.h +46 -0
  106. data/source/bzs/test/transactdBench/workerMySQLImple.h +15 -7
  107. data/source/bzs/test/transactdBench/workerTransactdImple.h +10 -18
  108. data/source/bzs/test/trdclengn/test_trdclengn.cpp +1487 -174
  109. data/source/global/ormsrcgen/main.cpp +2 -0
  110. data/source/global/tdclatl/Database.cpp +2 -2
  111. data/source/global/tdclatl/Database.h +1 -1
  112. data/source/global/tdclatl/FieldDefs.cpp +0 -3
  113. data/source/global/tdclatl/PooledDbManager.cpp +2 -2
  114. data/source/global/tdclatl/PooledDbManager.h +1 -1
  115. data/source/global/tdclatl/PreparedQuery.cpp +53 -0
  116. data/source/global/tdclatl/PreparedQuery.h +61 -0
  117. data/source/global/tdclatl/QueryBase.cpp +2 -1
  118. data/source/global/tdclatl/QueryBase.h +1 -1
  119. data/source/global/tdclatl/Record.cpp +3 -15
  120. data/source/global/tdclatl/Recordset.cpp +15 -10
  121. data/source/global/tdclatl/Recordset.h +3 -0
  122. data/source/global/tdclatl/Table.cpp +42 -7
  123. data/source/global/tdclatl/Table.h +3 -1
  124. data/source/global/tdclatl/activeTable.cpp +264 -76
  125. data/source/global/tdclatl/activeTable.h +12 -3
  126. data/source/global/tdclatl/tdclatl.idl +92 -10
  127. data/source/linux/charsetConvert.h +7 -7
  128. data/transactd.gemspec +14 -27
  129. metadata +18 -27
  130. data/bin/common/tdclc_32_2_0.dll +0 -0
  131. data/bin/common/tdclc_64_2_0.dll +0 -0
  132. data/build/swig/php/generate.cmake.in +0 -56
  133. data/build/swig/php/generate.cmd.in +0 -47
  134. data/build/swig/php/php.swg +0 -197
  135. data/build/swig/php/transactd.no_yield.php +0 -4494
  136. data/build/swig/php/transactd.no_yield.php.git.patch +0 -685
  137. data/build/swig/php/transactd.no_yield.php.patch +0 -685
  138. data/build/swig/php/transactd.yield.php +0 -4461
  139. data/build/swig/php/transactd.yield.php.git.patch +0 -652
  140. data/build/swig/php/transactd.yield.php.patch +0 -652
  141. data/build/swig/ruby/generate.cmake.in +0 -35
  142. data/build/swig/ruby/generate.cmd.in +0 -19
  143. data/build/tdclc/BUILDNUMBER.txt +0 -1
  144. data/build/tdclcpp/BUILDNUMBER.txt +0 -1
  145. data/build/tdclrb/BUILDNUMBER.txt +0 -1
  146. data/build/tdclrb/GEM_RELEASE_VERSION +0 -1
@@ -50,13 +50,6 @@ if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
50
50
  endif()
51
51
 
52
52
 
53
- # ==========================================================
54
- # version info
55
- # ==========================================================
56
- transactd_read_version("${TRANSACTD_ROOT}")
57
- transactd_read_build_number("${TRANSACTD_ROOT}")
58
-
59
-
60
53
  # ==========================================================
61
54
  # source files
62
55
  # ==========================================================
@@ -89,17 +82,9 @@ endif()
89
82
  # ==========================================================
90
83
  # add resource file (for Windows Visual Studio)
91
84
  # ==========================================================
85
+ set(${this_target}_RC_FILE "${TRANSACTD_ROOT}/build/tdclc/tdclc.rc")
86
+ transactd_read_rc("${${this_target}_RC_FILE}")
92
87
  if(WIN32)
93
- transactd_ver_info_lic()
94
- set(${this_target}_RC_FILE "${CMAKE_CURRENT_BINARY_DIR}/tdclc.rc")
95
- transactd_generate_rc_file(
96
- TRANSACTD_ROOT "${TRANSACTD_ROOT}"
97
- OUTFILE "${${this_target}_RC_FILE}"
98
- F_VER "${TDVER_C_INTERFACE_VER_MAJOR}.${TDVER_C_INTERFACE_VER_MINOR}.${TDVER_C_INTERFACE_VER_RELEASE}.${TRANSACTD_BUILD_NUMBER}"
99
- P_VER "${TDVER_C_INTERFACE_VER_MAJOR}.${TDVER_C_INTERFACE_VER_MINOR}.${TDVER_C_INTERFACE_VER_RELEASE}.${TRANSACTD_BUILD_NUMBER}"
100
- P_NAME "Transactd Client ${TRANSACTD_VER_POSTFIX}"
101
- F_DESC "Transactd C client"
102
- )
103
88
  transactd_add_rc_file()
104
89
  endif()
105
90
 
@@ -123,12 +108,14 @@ transactd_set_MTMD("MT")
123
108
  # ==========================================================
124
109
  # Add compile definitions
125
110
  # ==========================================================
111
+ set_property(TARGET ${this_target} PROPERTY COMPILE_DEFINITIONS
112
+ PACKAGE_NO_EXPORT BOOST_ALL_NO_LIB _MBCS)
126
113
  if(MSVC)
127
- set_property(TARGET ${this_target} PROPERTY COMPILE_DEFINITIONS
128
- WIN32 _WIN32 _WINDOWS _WIN32_WINNT=0x0501 PACKAGE_NO_EXPORT _USRDLL BOOST_ALL_NO_LIB _MBCS)
114
+ set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
115
+ WIN32 _WIN32 _WINDOWS _WIN32_WINNT=0x0501 _USRDLL)
129
116
  else()
130
- set_property(TARGET ${this_target} PROPERTY COMPILE_DEFINITIONS
131
- PIC BOOST_ALL_NO_LIB _MBCS)
117
+ set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
118
+ PIC _REENTRANT)
132
119
  if(NOT MINGW)
133
120
  set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
134
121
  LINUX)
@@ -145,6 +132,7 @@ if(CAN_LINK_ICONV)
145
132
  endif()
146
133
  if(NOT MSVC)
147
134
  target_link_libraries(${this_target} pthread)
135
+ target_link_libraries(${this_target} -Wl,--version-script,"${TRANSACTD_ROOT}/build/tdclc/libtdclcm.map")
148
136
  endif()
149
137
 
150
138
 
@@ -156,7 +144,7 @@ if(WIN32)
156
144
  ## Windows tdclc_[32|64]_[MAJOR]_[MINOR].dll
157
145
  set_target_properties(${this_target} PROPERTIES PREFIX "")
158
146
  set_target_properties(${this_target} PROPERTIES OUTPUT_NAME
159
- "tdclc_${BZ_BITNESS}_${TDVER_C_INTERFACE_VER_MAJOR}_${TDVER_C_INTERFACE_VER_MINOR}")
147
+ "tdclc_${BZ_BITNESS}_${TD_RC_VER_MAJOR}_${TD_RC_VER_MINOR}")
160
148
  set_target_properties(${this_target} PROPERTIES SUFFIX ".dll")
161
149
  else()
162
150
  ## Linux libtdclc_[32|64].so.[MAJOR].[MINOR]
@@ -167,14 +155,14 @@ else()
167
155
  include(../common/transactd_cl_output.cmake)
168
156
  endif()
169
157
  tdcl_set_outputnames_osx(
170
- "libtdclc_${BZ_BITNESS}" "${TDVER_C_INTERFACE_VER_MAJOR}"
171
- "${TDVER_C_INTERFACE_VER_MINOR}" "${TDVER_C_INTERFACE_VER_RELEASE}"
158
+ "libtdclc_${BZ_BITNESS}" "${TD_RC_VER_MAJOR}"
159
+ "${TD_RC_VER_MINOR}" "${TD_RC_VER_RELEASE}"
172
160
  "${TRANSACTD_ROOT}")
173
161
  else()
174
162
  set_target_properties(${this_target} PROPERTIES SUFFIX ".so")
175
163
  set_target_properties(${this_target} PROPERTIES
176
- SOVERSION ${TDVER_C_INTERFACE_VER_MAJOR}.${TDVER_C_INTERFACE_VER_MINOR}
177
- VERSION ${TDVER_C_INTERFACE_VER_MAJOR}.${TDVER_C_INTERFACE_VER_MINOR}.${TDVER_C_INTERFACE_VER_RELEASE})
164
+ SOVERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}
165
+ VERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}.${TD_RC_VER_RELEASE})
178
166
  endif()
179
167
  endif()
180
168
 
@@ -0,0 +1,4 @@
1
+ {
2
+ global: BTRCALLID; BTRV;BTRVID;BTRCALL;BTRCALL32;BTRCALLID32;
3
+ local: *;
4
+ };
@@ -62,7 +62,7 @@
62
62
  <VerInfo_Locale>1041</VerInfo_Locale>
63
63
  <BRCC_CompilerToUse>rc</BRCC_CompilerToUse>
64
64
  <BRCC_IncludePath>$(BDSINCLUDE)\windows\sdk;$(BRCC_IncludePath)</BRCC_IncludePath>
65
- <DllSuffix>_2_0</DllSuffix>
65
+ <DllSuffix>_2_1</DllSuffix>
66
66
  <DynamicRTL>false</DynamicRTL>
67
67
  <BPILibOutputDir>..\..\lib</BPILibOutputDir>
68
68
  <BCC_PCHUsage>None</BCC_PCHUsage>
data/build/tdclc/tdclc.rc CHANGED
Binary file
@@ -70,13 +70,6 @@ if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
70
70
  endif()
71
71
 
72
72
 
73
- # ==========================================================
74
- # version info
75
- # ==========================================================
76
- transactd_read_version("${TRANSACTD_ROOT}")
77
- transactd_read_build_number("${TRANSACTD_ROOT}")
78
-
79
-
80
73
  # ==========================================================
81
74
  # add source / include dir , set compiler / linker options
82
75
  # ==========================================================
@@ -87,17 +80,9 @@ tdcl_add_include_directory("${TRANSACTD_ROOT}")
87
80
  # ==========================================================
88
81
  # add resource file (for Windows Visual Studio)
89
82
  # ==========================================================
83
+ set(${this_target}_RC_FILE "${TRANSACTD_ROOT}/build/tdclcpp/tdclcpp.rc")
84
+ transactd_read_rc("${${this_target}_RC_FILE}")
90
85
  if(WIN32)
91
- transactd_ver_info_lic()
92
- set(${this_target}_RC_FILE "${CMAKE_CURRENT_BINARY_DIR}/tdclcpp.rc")
93
- transactd_generate_rc_file(
94
- TRANSACTD_ROOT "${TRANSACTD_ROOT}"
95
- OUTFILE "${${this_target}_RC_FILE}"
96
- F_VER "${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_CPP_INTERFACE_VER_RELEASE}.${TRANSACTD_BUILD_NUMBER}"
97
- P_VER "${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_CPP_INTERFACE_VER_RELEASE}.${TRANSACTD_BUILD_NUMBER}"
98
- P_NAME "Transactd Client ${TRANSACTD_VER_POSTFIX}"
99
- F_DESC "Transactd C++ client"
100
- )
101
86
  transactd_add_rc_file()
102
87
  endif()
103
88
 
@@ -127,7 +112,7 @@ if(MSVC)
127
112
  LIB_TDCLCPP TRDCL_AUTOLINK_OFF TRDCLENGN_EXPORTS _CRT_SECURE_NO_WARNINGS)
128
113
  else()
129
114
  set_property(TARGET ${this_target} PROPERTY COMPILE_DEFINITIONS
130
- PIC BOOST_ALL_NO_LIB)
115
+ PIC _REENTRANT BOOST_ALL_NO_LIB)
131
116
  if(NOT MINGW)
132
117
  set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
133
118
  LINUX)
@@ -157,7 +142,7 @@ if(CAN_LINK_ICONV)
157
142
  target_link_libraries(${this_target} "${ICONV_LIBRARY}")
158
143
  endif()
159
144
  if(NOT WIN32)
160
- target_link_libraries(${this_target} dl)
145
+ target_link_libraries(${this_target} dl pthread)
161
146
  endif()
162
147
 
163
148
 
@@ -174,7 +159,7 @@ if(WIN32)
174
159
  endif()
175
160
  set_target_properties(${this_target} PROPERTIES PREFIX "")
176
161
  set_target_properties(${this_target} PROPERTIES OUTPUT_NAME
177
- "${TDCL_CPP_NAME_TMP}_${TDVER_CPP_INTERFACE_VER_MAJOR}_${TDVER_CPP_INTERFACE_VER_MINOR}")
162
+ "${TDCL_CPP_NAME_TMP}_${TD_RC_VER_MAJOR}_${TD_RC_VER_MINOR}")
178
163
  set_target_properties(${this_target} PROPERTIES SUFFIX ".dll")
179
164
  else()
180
165
  ## Linux libtdclcpp_[32|64][m|u].so.[MAJOR].[MINOR].[RELEASE]
@@ -188,8 +173,8 @@ else()
188
173
  set_target_properties(${this_target} PROPERTIES SUFFIX ".so")
189
174
  endif()
190
175
  set_target_properties(${this_target} PROPERTIES
191
- SOVERSION ${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}
192
- VERSION ${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_CPP_INTERFACE_VER_RELEASE})
176
+ SOVERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}
177
+ VERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}.${TD_RC_VER_RELEASE})
193
178
  endif()
194
179
 
195
180
 
Binary file
@@ -152,7 +152,7 @@
152
152
  <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>
153
153
  <BCC_ExtendedErrorInfo>true</BCC_ExtendedErrorInfo>
154
154
  <TD_VER_MAJOR>2</TD_VER_MAJOR>
155
- <TD_VER_MINOR>0</TD_VER_MINOR>
155
+ <TD_VER_MINOR>1</TD_VER_MINOR>
156
156
  <DllSuffix>$(TD_VER_MAJOR)_$(TD_VER_MINOR)</DllSuffix>
157
157
  <TD_CPU>32</TD_CPU>
158
158
  </PropertyGroup>
@@ -67,40 +67,6 @@ if("${TRANSACTD_RUBY_GEM_ROOT_PATH}" STREQUAL "")
67
67
  endif()
68
68
 
69
69
 
70
- # ==========================================================
71
- # version info
72
- # ==========================================================
73
- transactd_read_version("${TRANSACTD_ROOT}")
74
- transactd_read_file_to_int("${TRANSACTD_ROOT}/build/tdclrb/GEM_RELEASE_VERSION")
75
- set(TDVER_RUBY_RELEASE "${TRANSACTD_READ_FILE_TO_INT_RETURN}")
76
- transactd_read_build_number("${TRANSACTD_ROOT}")
77
- set(TDVER_RUBY_BUILD "${TRANSACTD_BUILD_NUMBER}")
78
-
79
-
80
- # ==========================================================
81
- # add custom command for generate swig wrapper
82
- # ==========================================================
83
- set(RUBY_SWIG_WRAPPER_CPP "${CMAKE_CURRENT_BINARY_DIR}/tdclrb_wrap.cpp")
84
- file(TO_NATIVE_PATH "${TRANSACTD_ROOT}/build/swig/tdcl.i" SWIG_INTERFACE_FILE)
85
- file(TO_NATIVE_PATH "${RUBY_SWIG_WRAPPER_CPP}" SWIG_NATIVE_OUTFILE)
86
- file(TO_NATIVE_PATH "${TRANSACTD_ROOT}" SWIG_INC_PATH1)
87
- file(TO_NATIVE_PATH "${TRANSACTD_ROOT}/source" SWIG_INC_PATH2)
88
- # configure generate command file
89
- if(WIN32)
90
- set(SWIG_GEN_CMD_WIN "${CMAKE_CURRENT_BINARY_DIR}/generate.cmd")
91
- configure_file("${TRANSACTD_ROOT}/build/swig/ruby/generate.cmd.in" "${SWIG_GEN_CMD_WIN}" @ONLY)
92
- endif()
93
- set(SWIG_GEN_CMD "${CMAKE_CURRENT_BINARY_DIR}/generate.cmake")
94
- configure_file("${TRANSACTD_ROOT}/build/swig/ruby/generate.cmake.in" "${SWIG_GEN_CMD}" @ONLY)
95
- # add generate command to build time
96
- add_custom_command (
97
- OUTPUT "${RUBY_SWIG_WRAPPER_CPP}"
98
- COMMAND ${CMAKE_COMMAND} -P ${SWIG_GEN_CMD}
99
- COMMENT "Generating tdclrb_wrap.cpp"
100
- DEPENDS "${TRANSACTD_ROOT}/build/swig/tdcl.i"
101
- "${TRANSACTD_ROOT}/build/swig/ruby/ruby.swg")
102
-
103
-
104
70
  # ==========================================================
105
71
  # add swig wrapper source file
106
72
  # ==========================================================
@@ -110,7 +76,7 @@ if(WIN32 AND (NOT MSVC))
110
76
  endif()
111
77
  set(${this_target}_SOURCE_FILES
112
78
  ${${this_target}_SOURCE_FILES}
113
- ${RUBY_SWIG_WRAPPER_CPP}
79
+ ${TRANSACTD_ROOT}/build/swig/ruby/tdclrb_wrap.cpp
114
80
  ${TRANSACTD_ROOT}/source/bzs/db/protocol/tdap/client/connectionPool.cpp
115
81
  ${TRANSACTD_ROOT}/source/bzs/rtl/benchmark.cpp
116
82
  )
@@ -124,19 +90,11 @@ include_directories(${TRANSACTD_ROOT};${TRANSACTD_RUBY_INCLUDE_PATH})
124
90
 
125
91
 
126
92
  # ==========================================================
127
- # add resource file (for Windows Visual Studio)
93
+ # read and add resource file
128
94
  # ==========================================================
95
+ set(${this_target}_RC_FILE "${TRANSACTD_ROOT}/build/tdclrb/tdclrb.rc")
96
+ transactd_read_rc("${${this_target}_RC_FILE}")
129
97
  if(WIN32)
130
- transactd_ver_info_lic()
131
- set(${this_target}_RC_FILE "${CMAKE_CURRENT_BINARY_DIR}/tdclrb.rc")
132
- transactd_generate_rc_file(
133
- TRANSACTD_ROOT "${TRANSACTD_ROOT}"
134
- OUTFILE "${${this_target}_RC_FILE}"
135
- F_VER "${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_RUBY_RELEASE}.${TDVER_RUBY_BUILD}"
136
- P_VER "${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_RUBY_RELEASE}.${TDVER_RUBY_BUILD}"
137
- P_NAME "Transactd Client ${TRANSACTD_VER_POSTFIX}"
138
- F_DESC "Transactd Ruby client"
139
- )
140
98
  transactd_add_rc_file()
141
99
  endif()
142
100
 
@@ -172,7 +130,7 @@ if(MSVC)
172
130
  LIB_TDCLCPP TRDCL_AUTOLINK_OFF TRDCLENGN_EXPORTS _CRT_SECURE_NO_WARNINGS)
173
131
  else()
174
132
  set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
175
- PIC BOOST_ALL_NO_LIB)
133
+ PIC _REENTRANT BOOST_ALL_NO_LIB)
176
134
  if(NOT MINGW)
177
135
  set_property(TARGET ${this_target} APPEND PROPERTY COMPILE_DEFINITIONS
178
136
  LINUX)
@@ -211,8 +169,8 @@ else()
211
169
  endif()
212
170
  if(UNIX)
213
171
  set_target_properties(${this_target} PROPERTIES
214
- SOVERSION ${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}
215
- VERSION ${TDVER_CPP_INTERFACE_VER_MAJOR}.${TDVER_CPP_INTERFACE_VER_MINOR}.${TDVER_RUBY_RELEASE})
172
+ SOVERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}
173
+ VERSION ${TD_RC_VER_MAJOR}.${TD_RC_VER_MINOR}.${TD_RC_VER_RELEASE})
216
174
  endif()
217
175
 
218
176
 
@@ -0,0 +1,62 @@
1
+ //=================================================================
2
+ // Copyright (C) 2013 BizStation Corp All rights reserved.
3
+ //
4
+ // This program is free software; you can redistribute it and/or
5
+ // modify it under the terms of the GNU General Public License
6
+ // as published by the Free Software Foundation; either version 2
7
+ // of the License, or (at your option) any later version.
8
+ //
9
+ // This program is distributed in the hope that it will be useful,
10
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ // GNU General Public License for more details.
13
+ //
14
+ // You should have received a copy of the GNU General Public License
15
+ // along with this program; if not, write to the Free Software
16
+ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
+ // 02111-1307, USA.
18
+ //=================================================================
19
+
20
+ #ifndef __BCPLUSPLUS__
21
+ #include <windows.h>
22
+ #endif
23
+
24
+ #define IDC_STATIC -1
25
+
26
+ /////////////////////////////////////////////////////////////////////////////
27
+ //
28
+ // Version
29
+ //
30
+
31
+ VS_VERSION_INFO VERSIONINFO
32
+ FILEVERSION 2,1,0,10
33
+ PRODUCTVERSION 2,1,0,10
34
+ FILEFLAGSMASK 0x3fL
35
+ #ifdef _DEBUG
36
+ FILEFLAGS 0x1L
37
+ #else
38
+ FILEFLAGS 0x0L
39
+ #endif
40
+ FILEOS 0x40004L
41
+ FILETYPE 0x2L
42
+ FILESUBTYPE 0x0L
43
+ BEGIN
44
+ BLOCK "StringFileInfo"
45
+ BEGIN
46
+ BLOCK "040904b0"
47
+ BEGIN
48
+ VALUE "CompanyName", "BizStation Corp."
49
+ VALUE "FileDescription", "Transactd Ruby client"
50
+ VALUE "FileVersion", "2.1.0.10"
51
+ VALUE "LegalCopyright", "Copyright(C) 2014 BizStation Corp"
52
+ VALUE "ProductVersion", "2.1.0.10"
53
+ VALUE "ProductName", "Transactd Client (GPL V2)"
54
+ END
55
+ END
56
+ BLOCK "VarFileInfo"
57
+
58
+ BEGIN
59
+ VALUE "Translation", 0x409, 1200
60
+ END
61
+ END
62
+
@@ -52,6 +52,7 @@ public:
52
52
  m_blobs.clear();
53
53
  m_bh.fieldCount = 0;
54
54
  m_bh.rows = 0;
55
+ m_bh.dataSize = 0;
55
56
  m_data.clear();
56
57
  m_datasize = 0;
57
58
  m_blobCount = 0;
@@ -85,11 +86,15 @@ public:
85
86
  p += 2;
86
87
  m_datasize = (unsigned int)(p - &m_data[0]);
87
88
  ++m_blobCount;
89
+ m_bh.dataSize += b.bf.size;
90
+
88
91
  }
89
92
 
93
+ //For client
90
94
  void addBlob(const blob& b)
91
95
  {
92
96
  m_blobs.push_back(b);
97
+ m_bh.dataSize += b.bf.size;
93
98
  ++m_blobCount;
94
99
  }
95
100
 
@@ -61,6 +61,8 @@ struct blob
61
61
  */
62
62
  struct blobHeader
63
63
  {
64
+ unsigned int dataSize; // Not include this and blobField::fieldNum
65
+ // blobField::size, Only data(s).
64
66
  unsigned short rows;
65
67
  unsigned short fieldCount;
66
68
  mutable unsigned short curRow;
@@ -44,6 +44,15 @@ public:
44
44
  virtual unsigned short maxRows() const = 0;
45
45
  };
46
46
 
47
+
48
+ class IPrepare
49
+ {
50
+
51
+ public:
52
+ virtual ~IPrepare(){};
53
+ virtual void release() = 0;
54
+ };
55
+
47
56
  } // namespace mysql
48
57
  } // namespace engine
49
58
  } // namespace db
@@ -16,10 +16,10 @@
16
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
17
  02111-1307, USA.
18
18
  ================================================================= */
19
-
19
+ #include <my_config.h>
20
20
  #include "database.h"
21
- #include <boost/bind.hpp>
22
21
  #include "IReadRecords.h"
22
+ #include <boost/bind.hpp>
23
23
  #include "percentageKey.h"
24
24
  #include "mydebuglog.h"
25
25
  #include "mysqlThd.h"
@@ -41,6 +41,20 @@ using namespace std;
41
41
  #define KEYLEN_ALLCOPY 0
42
42
  #define OPEN_TABLE_TIMEOUT_SEC 2
43
43
 
44
+ #if (MODE_READ_ONLY != TD_OPEN_READONLY)
45
+ #error "MODE_READ_ONLY != TD_OPEN_READONLY"
46
+ #endif
47
+
48
+ #if (MODE_EXCLUSIVE != TD_OPEN_EXCLUSIVE)
49
+ #error "MODE_EXCLUSIVE != TD_OPEN_EXCLUSIVE"
50
+ #endif
51
+
52
+ #if (MODE_READ_EXCLUSIVE != TD_OPEN_READONLY_EXCLUSIVE)
53
+ #error "MODE_READ_EXCLUSIVE != TD_OPEN_READONLY_EXCLUSIVE"
54
+ #endif
55
+
56
+
57
+
44
58
  unsigned int hash(const char* s, size_t len)
45
59
  {
46
60
  unsigned int h = 0;
@@ -100,10 +114,9 @@ void tableCacheCounter::release(const std::string& dbname,
100
114
  --m_counts[pos];
101
115
  }
102
116
 
103
- void lockTable(THD* thd, TABLE* tb)
117
+ bool lockTable(THD* thd, TABLE* tb)
104
118
  {
105
119
  bool append = (thd->lock != 0);
106
- thd->in_lock_tables = 1;
107
120
 
108
121
  MYSQL_LOCK* lock = mysql_lock_tables(thd, &tb, 1, 0);
109
122
  if (!append)
@@ -114,10 +127,9 @@ void lockTable(THD* thd, TABLE* tb)
114
127
  if (lockMrg)
115
128
  thd->lock = lockMrg;
116
129
  }
117
- thd->in_lock_tables = 0;
118
130
  DEBUG_WRITELOG_SP1("LOCK TABLE table =%s\n", tb->s->table_name.str);
119
131
 
120
- return;
132
+ return (lock != NULL);
121
133
  }
122
134
 
123
135
  /** The present lock type is returned.
@@ -143,7 +155,8 @@ thr_lock_type locktype(bool trn, enum_sql_command cmd)
143
155
  return lock_type;
144
156
  }
145
157
 
146
- bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback)
158
+
159
+ bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback, database::tableList* tables)
147
160
  {
148
161
  if (thd->lock)
149
162
  {
@@ -154,8 +167,16 @@ bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback)
154
167
  ret = trans_commit_stmt(thd);
155
168
  if (releaseStatementLock)
156
169
  thd->mdl_context.release_statement_locks();
157
- mysql_unlock_tables(thd, thd->lock);
158
- thd->lock = 0;
170
+ if (tables)
171
+ {
172
+ for (size_t i=0;i<tables->size();++i)
173
+ mysql_lock_remove(thd, thd->lock, (*tables)[i]->internalTable());
174
+
175
+ }else
176
+ {
177
+ mysql_unlock_tables(thd, thd->lock);
178
+ thd->lock = 0;
179
+ }
159
180
  return !ret;
160
181
  }
161
182
  return false;
@@ -165,12 +186,12 @@ bool unlockTables(bool releaseStatementLock, THD* thd, bool rollback)
165
186
  #pragma warning(disable : 4355)
166
187
  #endif
167
188
 
168
- bool g_safe_share_mode = false;
169
189
  tableCacheCounter database::tableRef;
170
190
 
171
191
  database::database(const char* name, short cid)
172
- : m_dbname(name), m_thd(createThdForThread()), m_cid(cid),
173
- m_inTransaction(0), m_inSnapshot(0), m_trnType(0)
192
+ : m_dbname(name), m_thd(createThdForThread()),
193
+ m_inTransaction(0), m_inSnapshot(0), m_stat(0), m_usingExclusive(false),
194
+ m_inAutoTransaction(NULL), m_trnType(0), m_cid(cid)
174
195
  {
175
196
  m_thd->security_ctx->skip_grants();
176
197
  }
@@ -194,8 +215,119 @@ void database::use() const
194
215
  m_thd->clear_error();
195
216
  }
196
217
 
197
- // locktable
198
- table* database::useTable(int index, enum_sql_command cmd)
218
+ void database::prebuildIsoratinMode()
219
+ {
220
+ cp_thd_set_read_only(m_thd);
221
+ if (m_inTransaction)
222
+ {
223
+ m_thd->tx_isolation = m_iso;
224
+ m_thd->in_lock_tables = 1;// WITH LOCK
225
+ }
226
+ else if(m_inSnapshot)
227
+ {
228
+ if (m_iso)
229
+ {
230
+ m_thd->in_lock_tables = 1;// WITH LOCK
231
+ m_thd->tx_isolation = m_iso;
232
+ }else
233
+ m_thd->tx_isolation = ISO_REPEATABLE_READ;
234
+ }
235
+ else
236
+ m_thd->tx_isolation = (enum_tx_isolation)m_thd->variables.tx_isolation;
237
+ }
238
+
239
+ void database::prebuildExclusieLockMode(table* tb)
240
+ {
241
+ m_thd->variables.option_bits |= OPTION_TABLE_LOCK;
242
+ m_thd->lex->sql_command = SQLCOM_LOCK_TABLES;
243
+ if (tb->mode() == MODE_EXCLUSIVE)
244
+ tb->m_table->reginfo.lock_type = TL_WRITE;
245
+ else
246
+ tb->m_table->reginfo.lock_type = TL_READ_NO_INSERT;
247
+ m_thd->in_lock_tables = 1;
248
+
249
+ }
250
+
251
+ void database::prebuildLocktype(table* tb, enum_sql_command& cmd, rowLockMode* lck)
252
+ {
253
+ bool trn = ((m_inTransaction > 0) && !tb->isReadOnly());
254
+ if (m_inSnapshot)
255
+ cmd = SQLCOM_SELECT;
256
+ thr_lock_type lock_type = TL_READ;
257
+
258
+ // ExclusveMode and Snapshot can not specify lock type.
259
+ // Auto transaction can.
260
+ if (lck && lck->lock)
261
+ {
262
+ if (m_inTransaction)
263
+ lock_type = (lck->read) ? TL_READ : TL_WRITE;
264
+ else if (!tb->isExclusveMode() && noUserTransaction())
265
+ {
266
+ if (lck->read)
267
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_LOCKTYPE, "Invalid lock type.");
268
+
269
+ assert(cmd == SQLCOM_SELECT);
270
+ lock_type = TL_WRITE;
271
+ cmd = SQLCOM_UPDATE;
272
+ }
273
+ }
274
+ else
275
+ lock_type = locktype(trn, cmd);
276
+ m_thd->in_lock_tables = (lock_type >= TL_WRITE);
277
+ m_thd->lex->sql_command = cmd;
278
+
279
+ if ((lock_type >= TL_WRITE) &&
280
+ (tb->isReadOnly() || cp_thd_get_read_only(m_thd)))
281
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ACCESS_DENIED, "Access denined.");
282
+
283
+ if ((lock_type >= TL_WRITE) &&
284
+ (m_thd->variables.sql_log_bin))
285
+ m_thd->set_current_stmt_binlog_format_row();
286
+
287
+ tb->m_table->reginfo.lock_type = lock_type;
288
+ }
289
+
290
+ void database::changeIntentionLock(table* tb, thr_lock_type lock_type)
291
+ {
292
+ if (lock_type != tb->m_table->reginfo.lock_type)
293
+ {
294
+ tb->m_table->reginfo.lock_type = lock_type;
295
+ m_thd->variables.option_bits |= OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN;
296
+ tb->m_table->file->ha_external_lock(m_thd, F_UNLCK);
297
+ if (lock_type == TL_READ)
298
+ tb->m_table->file->init_table_handle_for_HANDLER();//prebuilt->select_lock_type = LOCK_NONE;
299
+
300
+ tb->m_table->file->ha_external_lock(m_thd,
301
+ (lock_type == TL_WRITE) ? F_WRLCK : F_RDLCK);
302
+ m_thd->variables.option_bits &= ~(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
303
+ tb->m_validCursor = false;
304
+ }
305
+ }
306
+
307
+ /*
308
+ How to set the lock value to InnoDB prebuilt->select_lock_type variable.
309
+
310
+ -- First call
311
+ LOCK_NONE : file->init_table_handle_for_HANDLER();
312
+ LOCK_S : m_table->reginfo.lock_type = TL_READ and
313
+ thd->in_lock_tables = 1;
314
+ LOCK_X : m_table->reginfo.lock_type = TL_WRITE and
315
+ thd->in_lock_tables = 1;
316
+ -- Chage type
317
+ LOCK_X -> LOCK_S
318
+ : thd->variables.option_bits |= OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN;
319
+ file->ha_external_lock(m_thd, F_UNLCK);
320
+ file->init_table_handle_for_HANDLER();
321
+ file->ha_external_lock(m_thd, F_WRLCK);
322
+ thd->variables.option_bits &= ~(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
323
+
324
+ LOCK_S -> LOCK_X
325
+ : thd->variables.option_bits |= OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN;
326
+ file->ha_external_lock(m_thd, F_UNLCK);
327
+ file->ha_external_lock(m_thd, F_RDLCK);
328
+ thd->variables.option_bits &= ~(OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
329
+ */
330
+ table* database::useTable(int index, enum_sql_command cmd, rowLockMode* lck)
199
331
  {
200
332
  if (index >= (int)m_tables.size())
201
333
  THROW_BZS_ERROR_WITH_CODEMSG(1, "Invalid table id.");
@@ -204,66 +336,98 @@ table* database::useTable(int index, enum_sql_command cmd)
204
336
  if (tb == NULL)
205
337
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
206
338
  "Invalid table id.");
207
-
208
339
  if (tb->m_blobBuffer)
209
340
  tb->m_blobBuffer->clear();
341
+
342
+ // Change to shared lock is user tranasction only.
343
+ if (lck && lck->read && lck->lock && !m_inTransaction)
344
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_INVALID_LOCKTYPE,
345
+ "Invalid lock type.");
346
+
347
+ // in-transaction or in-snapshort or exclusive or inAutoTransaction(lock delay)
348
+ // is opened
210
349
  if (tb->islocked())
211
350
  {
212
351
  if (tb->m_table == NULL)
213
352
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
214
353
  "Invalid table id.");
354
+ if (m_inTransaction && (m_iso >= ISO_REPEATABLE_READ))
355
+ changeIntentionLock(tb, (lck && lck->lock && lck->read) ? TL_READ : TL_WRITE);
356
+
357
+ if (tb->isExclusveMode())
358
+ {
359
+ prebuildLocktype(tb, cmd, NULL);
360
+ tb->startStmt();
361
+ }
215
362
  return tb;
216
363
  }
217
- if (g_safe_share_mode && tb->m_table == NULL)
218
- reopen();
364
+
219
365
  if (tb->m_table == NULL)
220
366
  THROW_BZS_ERROR_WITH_CODEMSG(STATUS_FILE_NOT_OPENED,
221
367
  "Invalid table id.");
222
- bool trn = ((m_inTransaction > 0) & (tb->mode() != TD_OPEN_READONLY));
223
- tb->m_table->reginfo.lock_type = locktype(trn, cmd);
224
- if ((tb->mode() == TD_OPEN_READONLY) &&
225
- (tb->m_table->reginfo.lock_type == TL_WRITE))
226
- THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ACCESS_DENIED, "Access denined.");
368
+ prebuildLocktype(tb, cmd, lck);
369
+
227
370
  if (m_thd->lock == 0)
228
- {
229
- m_thd->lex->sql_command = cmd;
230
- m_thd->tx_isolation = (enum_tx_isolation)m_thd->variables.tx_isolation;
231
- cp_thd_set_read_only(m_thd);
232
- }
233
- lockTable(m_thd, tb->m_table);
234
-
235
- if ((tb->m_table->reginfo.lock_type == TL_WRITE) &&
236
- (m_thd->variables.sql_log_bin))
237
- m_thd->set_current_stmt_binlog_format_row();
371
+ prebuildIsoratinMode();
372
+
373
+ if (tb->isExclusveMode())
374
+ prebuildExclusieLockMode(tb);
375
+
376
+ if (!lockTable(m_thd, tb->m_table))
377
+ {
378
+ m_thd->in_lock_tables = 0;
379
+ m_thd->variables.option_bits &= ~OPTION_TABLE_LOCK;
380
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_CANNOT_LOCK_TABLE,
381
+ "lockTable error.");
382
+ }
383
+ if (tb->isExclusveMode())
384
+ m_thd->variables.option_bits &= ~OPTION_TABLE_LOCK;
385
+
386
+ tb->initForHANDLER();
238
387
  tb->setLocked(true);
239
- if (g_safe_share_mode)
240
- {
241
- int ret = 0;
242
- tb->m_keyconv.setKey(tb->m_table->key_info);
243
- if (tb->keyNum() >= 0)
244
- ret =
245
- tb->m_table->file->ha_index_init(tb->keyNum(), 1 /* sorted */);
246
- else if (tb->keyNum() == -2)
247
- ret = tb->m_table->file->ha_rnd_init(false);
248
- if (ret)
249
- THROW_BZS_ERROR_WITH_CODEMSG(ERROR_INDEX_RND_INIT,
250
- "UseTable index_init error.");
251
- }
252
-
388
+ m_thd->in_lock_tables = 0;
253
389
  return tb;
254
390
  }
255
391
 
392
+ size_t database::getNomalOpenTables(tableList& tables)
393
+ {
394
+ for (int i = (int)m_tables.size() - 1; i >= 0; i--)
395
+ {
396
+ boost::shared_ptr<table>& tb = m_tables[i];
397
+ if (tb && tb->islocked() && tb->isNomalMode())
398
+ tables.push_back(tb);
399
+ }
400
+ return tables.size();
401
+ }
402
+
256
403
  void database::unUseTable(table* tb)
257
404
  {
258
405
  if (tb->islocked() && (m_inTransaction + m_inSnapshot == 0))
259
406
  { // Only this table is lock release.
260
407
  bool needUnlock =
261
408
  (locktype(false, m_thd->lex->sql_command) == TL_WRITE);
262
- bool changed = tb->isChanged();
263
- tb->resetTransctionInfo(m_thd);
264
- bool rollback = (!changed && needUnlock);
265
- if (unlockTables(needUnlock, m_thd, rollback))
409
+ bool rollback = (!tb->isChanged() && needUnlock);
410
+ bool ret = true;
411
+ if(m_usingExclusive)
412
+ {
413
+ tableList tables;
414
+ if (getNomalOpenTables(tables))
415
+ ret = unlockTables(needUnlock, m_thd, rollback, &tables);
416
+ }
417
+ else
418
+ ret = unlockTables(needUnlock, m_thd, rollback, NULL);
419
+
420
+ if (ret)
266
421
  {
422
+ tb->resetTransctionInfo(m_thd);
423
+ //unlock whole tebles,
424
+ // but a table can not know unlocked if a table in-autoTransaction
425
+ if (m_inAutoTransaction)
426
+ {
427
+ if (tb != m_inAutoTransaction)
428
+ m_inAutoTransaction->resetTransctionInfo(m_thd);
429
+ m_inAutoTransaction = NULL;
430
+ }
267
431
  DEBUG_WRITELOG_SP1("UNLOCK TABLE table =%s\n",
268
432
  tb->m_table->s->table_name.str);
269
433
  }
@@ -282,11 +446,6 @@ void database::unUseTable(table* tb)
282
446
  "Transaction commit error.");
283
447
  }
284
448
  }
285
- if (g_safe_share_mode)
286
- {
287
- unUseTables(false);
288
- closeForReopen();
289
- }
290
449
  }
291
450
  }
292
451
 
@@ -297,13 +456,24 @@ void database::unUseTables(bool rollback)
297
456
  (locktype((m_inTransaction > 0), m_thd->lex->sql_command) == TL_WRITE);
298
457
  m_inTransaction = 0;
299
458
  m_inSnapshot = 0;
300
- for (int i = 0; i < (int)m_tables.size(); i++)
459
+ m_inAutoTransaction = NULL;
460
+
461
+ bool ret = true;
462
+ if(m_usingExclusive)
301
463
  {
302
- if (m_tables[i])
303
- m_tables[i]->resetTransctionInfo(m_thd);
304
- }
305
- if (unlockTables(needUnlock, m_thd, rollback))
464
+ tableList tables;
465
+ if (getNomalOpenTables(tables))
466
+ ret = unlockTables(needUnlock, m_thd, rollback, &tables);
467
+ }else
468
+ ret = unlockTables(needUnlock, m_thd, rollback, NULL);
469
+
470
+ if (ret)
306
471
  {
472
+ for (int i = 0; i < (int)m_tables.size(); i++)
473
+ {
474
+ if (m_tables[i])
475
+ m_tables[i]->resetTransctionInfo(m_thd);
476
+ }
307
477
  DEBUG_WRITELOG("UNLOCK TABLES \n")
308
478
  }
309
479
  else
@@ -318,19 +488,28 @@ void database::unUseTables(bool rollback)
318
488
  THROW_BZS_ERROR_WITH_CODEMSG(m_stat, "Transaction commit error.");
319
489
  }
320
490
  }
321
- if (g_safe_share_mode)
322
- closeForReopen();
323
491
  }
324
492
 
325
- bool database::beginTrn(short type)
493
+ bool database::beginTrn(short type, enum_tx_isolation iso)
326
494
  {
327
- ++m_inTransaction;
328
- if (m_inTransaction == 1)
495
+ if (m_inSnapshot)
496
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ALREADY_INSNAPSHOT, "Snapshot is already beginning.");
497
+
498
+ bool ret = false;
499
+ if (m_inTransaction == 0)
329
500
  {
330
501
  m_trnType = type;
331
- return true;
502
+ // if ISO_REPEATABLE_READ ,change to force ISO_SERIALIZABLE
503
+ if (iso == ISO_REPEATABLE_READ)
504
+ m_iso = ISO_SERIALIZABLE;
505
+ else
506
+ m_iso = iso;
507
+ if (m_inAutoTransaction)
508
+ m_inAutoTransaction->unUse();
509
+ ret = true;
332
510
  }
333
- return false;
511
+ ++m_inTransaction;
512
+ return ret;
334
513
  }
335
514
 
336
515
  bool database::commitTrn()
@@ -355,10 +534,21 @@ bool database::abortTrn()
355
534
  return (m_inTransaction == 0);
356
535
  }
357
536
 
358
- bool database::beginSnapshot()
537
+ bool database::beginSnapshot(enum_tx_isolation iso)
359
538
  {
539
+ if (m_inTransaction)
540
+ THROW_BZS_ERROR_WITH_CODEMSG(STATUS_ALREADY_INTRANSACTION, "Transaction is already beginning.");
541
+
542
+ bool ret = false;
543
+ if (m_inSnapshot == 0)
544
+ {
545
+ m_iso = iso;
546
+ if (m_inAutoTransaction)
547
+ m_inAutoTransaction->unUse();
548
+ ret = true;
549
+ }
360
550
  ++m_inSnapshot;
361
- return (m_inSnapshot == 1);
551
+ return ret;
362
552
  }
363
553
 
364
554
  bool database::endSnapshot()
@@ -380,12 +570,9 @@ TABLE* database::doOpenTable(const std::string& name, short mode,
380
570
  {
381
571
  TABLE_LIST tables;
382
572
  m_thd->variables.lock_wait_timeout = OPEN_TABLE_TIMEOUT_SEC;
383
- enum_mdl_type type_arg =
384
- (mode == TD_OPEN_EXCLUSIVE) ? MDL_EXCLUSIVE : MDL_SHARED_READ;
385
- thr_lock_type locltype = (mode == TD_OPEN_EXCLUSIVE) ? TL_WRITE : TL_READ;
386
573
  tables.init_one_table(m_dbname.c_str(), m_dbname.size(), name.c_str(),
387
- name.size(), name.c_str(), locltype);
388
- tables.mdl_request.set_type(type_arg);
574
+ name.size(), name.c_str(), TL_READ);
575
+ tables.mdl_request.set_type(MDL_SHARED_READ);
389
576
 
390
577
  Open_table_context ot_act(m_thd, MYSQL_OPEN_GET_NEW_TABLE);
391
578
  m_thd->cp_set_overwrite_status(true);
@@ -437,6 +624,8 @@ table* database::openTable(const std::string& name, short mode,
437
624
  new table(t, *this, name, mode, (int)m_tables.size()));
438
625
  m_tables.push_back(tb);
439
626
  m_stat = STATUS_SUCCESS;
627
+ if (tb->isExclusveMode())
628
+ ++m_usingExclusive;
440
629
  tableRef.addref(m_dbname, name); // addef first then table open.
441
630
  return tb.get();
442
631
  }
@@ -476,33 +665,27 @@ void database::closeTable(table* tb)
476
665
  {
477
666
  if (m_tables[i] && (m_tables[i].get() == tb))
478
667
  {
479
- short mode = tb->m_mode;
480
- TABLE* src = tb->m_table;
481
-
482
- unUseTable(m_tables[i].get());
483
- m_tables[i].reset();
484
- if (mode == TD_OPEN_EXCLUSIVE)
668
+ if (tb->isExclusveMode())
485
669
  {
486
- if (tableUseCount(m_tables, src->s->table_name.str) == 1)
670
+ --m_usingExclusive;
671
+ // Chenge to normal, in order to be listed on the normal list.
672
+ struct ChangeMode
487
673
  {
488
- for (TABLE** tbl = &m_thd->open_tables; *tbl != 0;
489
- *tbl = (*tbl)->next)
674
+ table* m_tb;
675
+ short m_mode;
676
+ ChangeMode(table* tb):m_tb(tb)
490
677
  {
491
- if (*tbl == src)
492
- {
493
- TABLE* tbptr = (*tbl);
494
- MDL_ticket* tc = tbptr->mdl_ticket;
495
- close_thread_table(m_thd, tbl);
496
- m_thd->mdl_context
497
- .set_explicit_duration_for_all_locks();
498
- m_thd->mdl_context.release_all_locks_for_name(tc);
499
- m_thd->mdl_context
500
- .set_transaction_duration_for_all_locks();
501
- }
502
- break;
678
+ m_mode = tb->m_mode;
679
+ m_tb->m_mode = 0;
503
680
  }
504
- }
505
- }
681
+ ~ChangeMode(){m_tb->m_mode = m_mode;}
682
+ }modeChanger(tb);
683
+
684
+ m_tables[i]->unUse();
685
+ }else
686
+ m_tables[i]->unUse();
687
+
688
+ m_tables[i].reset();
506
689
 
507
690
  DEBUG_WRITELOG_SP1("CLOSE TABLE table id=%d \n", i);
508
691
  }
@@ -512,7 +695,6 @@ void database::closeTable(table* tb)
512
695
  void database::closeForReopen()
513
696
  {
514
697
  // A transaction is committed compulsorily.
515
-
516
698
  for (size_t i = 0; i < m_tables.size(); i++)
517
699
  {
518
700
  if (m_tables[i] && (m_tables[i]->m_table != NULL))
@@ -523,6 +705,7 @@ void database::closeForReopen()
523
705
  if (m_thd->mdl_context.has_locks())
524
706
  close_thread_tables(m_thd);
525
707
  m_thd->mdl_context.release_transactional_locks();
708
+ m_usingExclusive = 0;
526
709
  // It is certainly after close_thread_tables.
527
710
  }
528
711
 
@@ -602,12 +785,12 @@ bool table::noKeybufResult = true;
602
785
  table::table(TABLE* myTable, database& db, const std::string& name, short mode,
603
786
  int id)
604
787
  : m_table(myTable), m_name(name), m_mode(mode), m_id(id), m_db(db),
605
- m_keyNum(-1), m_keybuf(new unsigned char[MAX_KEYLEN]),
606
- m_nonNccKeybuf(new unsigned char[MAX_KEYLEN]), m_nonNcc(false), m_stat(0),
607
- m_validCursor(true), m_cursor(false), m_locked(false), m_changed(false),
608
- m_nounlock(false), m_bulkInserting(false),
609
- m_keyconv(m_table->key_info, m_table->s->keys), m_blobBuffer(NULL)
610
-
788
+ m_keybuf(new unsigned char[MAX_KEYLEN]),
789
+ m_nonNccKeybuf(new unsigned char[MAX_KEYLEN]), m_stat(0),
790
+ m_keyconv(m_table->key_info, m_table->s->keys), m_blobBuffer(NULL),
791
+ m_keyNum(-1), m_nonNcc(false), m_validCursor(true), m_cursor(false),
792
+ m_locked(false), m_changed(false), m_nounlock(false), m_bulkInserting(false),
793
+ m_delayAutoCommit(false),m_forceConsistentRead(false)
611
794
  {
612
795
 
613
796
  m_table->read_set = &m_table->s->all_set;
@@ -624,7 +807,7 @@ table::table(TABLE* myTable, database& db, const std::string& name, short mode,
624
807
  #ifdef USE_BTRV_VARIABLE_LEN
625
808
  else if (m_table->s->varchar_fields == 1)
626
809
  {
627
- Field** fd = m_table->field + lastVarFiledNum();
810
+ Field** fd = m_table->field + lastVarFieldNum();
628
811
  if (isVarType((*fd)->type()) && ((*fd)->part_of_key.is_clear_all()) &&
629
812
  ((*fd)->key_start.is_clear_all()) &&
630
813
  (((*fd)->charset()) == &my_charset_bin))
@@ -661,6 +844,8 @@ table::~table()
661
844
  {
662
845
  resetInternalTable(NULL);
663
846
  database::tableRef.release(m_db.name(), m_name);
847
+ for (size_t i = 0; i < preparedStatements.size(); ++i)
848
+ preparedStatements[i]->release();
664
849
  }
665
850
 
666
851
  void table::resetTransctionInfo(THD* thd)
@@ -673,7 +858,8 @@ void table::resetTransctionInfo(THD* thd)
673
858
  m_table->next_number_field = 0;
674
859
  m_table->file->next_insert_id = 0;
675
860
  }
676
- m_locked = false;
861
+ if (isNomalMode())
862
+ m_locked = false;
677
863
  m_validCursor = false;
678
864
  m_nounlock = false;
679
865
  }
@@ -771,6 +957,9 @@ void table::setKeyValues(const uchar* ptr, int size)
771
957
  But blob and prefix index is not equal pack_length.
772
958
 
773
959
  Client needs to make the right image except for null byte.
960
+
961
+ @return -1: whole segment copied.
962
+ n: number of segments copied.
774
963
  */
775
964
  short table::setKeyValuesPacked(const uchar* ptr, int size)
776
965
  {
@@ -1101,14 +1290,14 @@ uint table::recordPackCopy(char* buf, uint maxsize)
1101
1290
  return (uint)(p - buf);
1102
1291
  }
1103
1292
 
1104
- ushort table::fieldPackCopy(unsigned char* dest, short filedNum)
1293
+ ushort table::fieldPackCopy(unsigned char* dest, short fieldNum)
1105
1294
  {
1106
- Field* fd = m_table->field[filedNum];
1295
+ Field* fd = m_table->field[fieldNum];
1107
1296
  uint len = fd->pack_length();
1108
1297
  if (isVarType(fd->type()))
1109
1298
  len = var_total_len(fd);
1110
1299
  #ifdef USE_BTRV_VARIABLE_LEN
1111
- if (lastVarFiledNum() == filedNum)
1300
+ if (lastVarFieldNum() == fieldNum)
1112
1301
  {
1113
1302
  len -= lastVarLenBytes();
1114
1303
  memcpy(dest, fd->ptr + lastVarLenBytes(), len);
@@ -1124,14 +1313,24 @@ inline bool table::keynumCheck(char num)
1124
1313
  return ((num >= 0) && (num < (short)m_table->s->keys));
1125
1314
  }
1126
1315
 
1127
- inline void table::unlockRow()
1316
+ inline void table::tryConsistentRead(bool noConsistent)
1128
1317
  {
1129
- if (!m_nounlock && m_validCursor && m_db.inTransaction() &&
1130
- (m_db.transactionType() == 0))
1131
- {
1318
+ /* Don't read old version that next operation is write, or inTransaqction. */
1319
+ bool const_read = m_forceConsistentRead ||
1320
+ (
1321
+ m_db.noUserTransaction() &&
1322
+ (m_table->reginfo.lock_type < TL_WRITE) &&
1323
+ !noConsistent
1324
+ );
1325
+ m_table->file->try_semi_consistent_read(const_read);
1326
+ }
1327
+
1328
+ inline void table::unlockRow(bool noConsistent)
1329
+ {
1330
+ if ((m_forceConsistentRead || m_db.canUnlockRow()) && m_validCursor && !m_nounlock)
1132
1331
  m_table->file->unlock_row();
1133
- m_nounlock = false;
1134
- }
1332
+ tryConsistentRead(noConsistent);
1333
+ m_nounlock = false;
1135
1334
  }
1136
1335
 
1137
1336
  /* read by key
@@ -1142,10 +1341,10 @@ void table::seekKey(enum ha_rkey_function find_flag, key_part_map keyMap)
1142
1341
  m_nonNcc = false;
1143
1342
  if (keynumCheck(m_keyNum))
1144
1343
  {
1145
- unlockRow();
1344
+ unlockRow(m_delayAutoCommit);
1146
1345
  m_stat = m_table->file->ha_index_read_map(
1147
1346
  m_table->record[0], &m_keybuf[0], keyMap /* keymap() */, find_flag);
1148
- m_cursor = m_validCursor = (m_stat == 0);
1347
+ setCursorStaus();
1149
1348
  if (m_stat == 0)
1150
1349
  {
1151
1350
  if (find_flag != HA_READ_KEY_EXACT)
@@ -1164,10 +1363,10 @@ void table::moveKey(boost::function<int()> func)
1164
1363
  m_nonNcc = false;
1165
1364
  if (keynumCheck(m_keyNum))
1166
1365
  {
1167
- unlockRow();
1366
+ unlockRow(m_delayAutoCommit);
1168
1367
 
1169
1368
  m_stat = func();
1170
- m_cursor = m_validCursor = (m_stat == 0);
1369
+ setCursorStaus();
1171
1370
  if (m_stat == 0)
1172
1371
  key_copy(&m_keybuf[0], m_table->record[0],
1173
1372
  &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
@@ -1183,15 +1382,15 @@ void table::getNextSame(key_part_map keyMap)
1183
1382
  m_nonNcc = false;
1184
1383
  if (keynumCheck(m_keyNum))
1185
1384
  {
1186
- if (m_validCursor && m_db.inTransaction() &&
1187
- (m_db.transactionType() == 0))
1188
- m_table->file->unlock_row();
1385
+ unlockRow(false /*lock*/);
1189
1386
  m_stat = m_table->file->ha_index_next_same(
1190
1387
  m_table->record[0], &m_keybuf[0], keyMap /* keymap() */);
1191
- m_cursor = m_validCursor = (m_stat == 0);
1388
+ setCursorStaus();
1192
1389
  if (m_stat == 0)
1390
+ {
1193
1391
  key_copy(&m_keybuf[0], m_table->record[0],
1194
1392
  &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1393
+ }
1195
1394
  }
1196
1395
  else
1197
1396
  m_stat = STATUS_INVALID_KEYNUM;
@@ -1299,6 +1498,10 @@ void table::getByPercentage(unsigned short per)
1299
1498
  m_stat = STATUS_INVALID_KEYNUM;
1300
1499
  return;
1301
1500
  }
1501
+
1502
+ /* Use constistant read force */
1503
+ smartForceConsistantRead SFCR(this);
1504
+
1302
1505
  if (per > 9800)
1303
1506
  {
1304
1507
  getLast();
@@ -1407,7 +1610,6 @@ void table::getByPercentage(unsigned short per)
1407
1610
 
1408
1611
  int table::percentage(uchar* first, uchar* last, uchar* cur)
1409
1612
  {
1410
- initHandler();
1411
1613
  KEY& key = m_table->key_info[m_keyNum];
1412
1614
  // 1 cur to last
1413
1615
  key_range minkey;
@@ -1472,8 +1674,9 @@ void table::stepFirst()
1472
1674
  {
1473
1675
  if (setNonKey(true))
1474
1676
  {
1677
+ unlockRow(m_delayAutoCommit);
1475
1678
  m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1476
- m_cursor = m_validCursor = (m_stat == 0);
1679
+ setCursorStaus();
1477
1680
  }
1478
1681
  else
1479
1682
  m_stat = STATUS_INVALID_KEYNUM;
@@ -1505,14 +1708,16 @@ void table::stepNext()
1505
1708
  {
1506
1709
  if (setNonKey(false))
1507
1710
  {
1711
+ unlockRow(false/*lock*/);
1508
1712
  m_stat = m_table->file->ha_rnd_pos(m_table->record[0],
1509
1713
  (uchar*)position(true));
1510
1714
  if (m_stat != 0)
1511
1715
  return;
1512
1716
  }
1513
1717
  }
1718
+ unlockRow(m_delayAutoCommit);
1514
1719
  m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1515
- m_cursor = m_validCursor = (m_stat == 0);
1720
+ setCursorStaus();
1516
1721
  }
1517
1722
  }
1518
1723
 
@@ -1537,7 +1742,6 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1537
1742
  m_stat = STATUS_NO_CURRENT;
1538
1743
  return;
1539
1744
  }
1540
- initHandler();
1541
1745
  m_nonNcc = false;
1542
1746
  int reject = (hdr->rejectCount() == 0) ? 4096 : hdr->rejectCount();
1543
1747
  if (reject == 0xFFFF)
@@ -1550,20 +1754,13 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1550
1754
 
1551
1755
  // Is a current position read or not?
1552
1756
  bool read = !includeCurrent;
1553
- bool unlock = (!m_db.inSnapshot() && !m_db.inTransaction()) ||
1554
- (m_db.inTransaction() && (m_db.transactionType() == 0));
1555
- bool forword =
1757
+ bool forword =
1556
1758
  (type == READ_RECORD_GETNEXT) || (type == READ_RECORD_STEPNEXT);
1557
1759
  while ((reject != 0) && (rows != 0))
1558
1760
  {
1559
1761
  if (read)
1560
1762
  {
1561
-
1562
- if (unlock && !m_nounlock && m_validCursor)
1563
- {
1564
- m_table->file->unlock_row();
1565
- m_nounlock = false;
1566
- }
1763
+ unlockRow(false);
1567
1764
 
1568
1765
  if (type == READ_RECORD_GETNEXT)
1569
1766
  m_stat = m_table->file->ha_index_next(m_table->record[0]);
@@ -1576,7 +1773,7 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1576
1773
  m_stat = STATUS_NOSUPPORT_OP;
1577
1774
  return;
1578
1775
  }
1579
- m_cursor = m_validCursor = (m_stat == 0);
1776
+ setCursorStaus();
1580
1777
  }
1581
1778
  else
1582
1779
  read = true;
@@ -1593,14 +1790,17 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1593
1790
  if (m_stat)
1594
1791
  break;
1595
1792
  --rows;
1596
- }
1597
- else if (ret == REC_NOMACTH_NOMORE)
1793
+ }else
1598
1794
  {
1599
- m_stat = STATUS_REACHED_FILTER_COND;
1600
- return;
1795
+ unlock();
1796
+ if (ret == REC_NOMACTH_NOMORE)
1797
+ {
1798
+ m_stat = STATUS_REACHED_FILTER_COND;
1799
+ return;
1800
+ }
1801
+ else
1802
+ --reject;
1601
1803
  }
1602
- else
1603
- --reject;
1604
1804
  }
1605
1805
  if (reject == 0)
1606
1806
  m_stat = STATUS_LIMMIT_OF_REJECT;
@@ -1612,6 +1812,7 @@ void table::readRecords(IReadRecordsHandler* hdr, bool includeCurrent, int type,
1612
1812
  // private
1613
1813
  void table::seekPos(const uchar* rawPos)
1614
1814
  {
1815
+
1615
1816
  seekKey(HA_READ_KEY_OR_NEXT, keymap());
1616
1817
  if (m_keyNum == (int)m_table->s->primary_key)
1617
1818
  return;
@@ -1619,7 +1820,7 @@ void table::seekPos(const uchar* rawPos)
1619
1820
  while ((m_stat == 0) &&
1620
1821
  ((cmp = m_table->file->cmp_ref(position(true), rawPos)) != 0))
1621
1822
  {
1622
- unlockRow();
1823
+ unlockRow(m_delayAutoCommit);
1623
1824
  m_table->file->ha_index_next_same(m_table->record[0], &m_keybuf[0],
1624
1825
  keymap());
1625
1826
  }
@@ -1632,9 +1833,11 @@ void table::movePos(const uchar* pos, char keyNum, bool sureRawValue)
1632
1833
  rawPos = bms()->getRefByBm(*(unsigned int*)pos);
1633
1834
 
1634
1835
  setNonKey();
1635
- unlockRow();
1836
+ unlockRow(m_delayAutoCommit);
1636
1837
  m_stat = m_table->file->ha_rnd_pos(m_table->record[0], (uchar*)rawPos);
1637
- m_cursor = (m_stat == 0);
1838
+ m_cursor = (m_stat == 0) ? true :
1839
+ ((m_stat == HA_ERR_LOCK_WAIT_TIMEOUT) ||
1840
+ (m_stat == HA_ERR_LOCK_DEADLOCK)) ? m_cursor : false;
1638
1841
  if ((keyNum == -1) || (keyNum == -64) || (keyNum == -2))
1639
1842
  return;
1640
1843
  if (m_stat == 0)
@@ -1681,9 +1884,10 @@ ha_rows table::recordCount(bool estimate)
1681
1884
  (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0)
1682
1885
  return m_table->file->records();
1683
1886
  if (estimate)
1684
- { // Since the answer of innodb is random, 1 returns also 0.
1685
- // Since it is important, in the case of 1
1686
- // , whether there is nothing or it is scan and investigate.
1887
+ { /* Since the answer of innodb is random, 1 returns also 0.
1888
+ Since it is important, in the case of 1
1889
+ , whether there is nothing or it is scan and investigate.
1890
+ info() is update statistics variables */
1687
1891
  m_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
1688
1892
  ha_rows rows = m_table->file->records();
1689
1893
  if (rows > 1)
@@ -1697,10 +1901,11 @@ ha_rows table::recordCount(bool estimate)
1697
1901
  fb.setKeyRead(true);
1698
1902
  if (setKeyNum((char)0, false /* sorted */))
1699
1903
  {
1700
- initHandler();
1904
+ m_table->file->try_semi_consistent_read(true);
1701
1905
  m_stat = m_table->file->ha_index_first(m_table->record[0]);
1702
1906
  while (m_stat == 0)
1703
1907
  {
1908
+ m_table->file->unlock_row();
1704
1909
  n++;
1705
1910
  m_stat = m_table->file->ha_index_next(m_table->record[0]);
1706
1911
  }
@@ -1715,10 +1920,11 @@ ha_rows table::recordCount(bool estimate)
1715
1920
  else
1716
1921
  {
1717
1922
  setNonKey(true /* scan */);
1718
- initHandler();
1923
+ m_table->file->try_semi_consistent_read(true);
1719
1924
  m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1720
1925
  while (m_stat == 0)
1721
1926
  {
1927
+ m_table->file->unlock_row();
1722
1928
  ++n;
1723
1929
  m_stat = m_table->file->ha_rnd_next(m_table->record[0]);
1724
1930
  }
@@ -1819,7 +2025,7 @@ void table::setFiledNullFlags()
1819
2025
 
1820
2026
  __int64 table::insert(bool ncc)
1821
2027
  {
1822
- if ((m_mode == TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
2028
+ if ((m_mode == TD_OPEN_READONLY) || (m_table->reginfo.lock_type < TL_WRITE))
1823
2029
  {
1824
2030
  m_stat = STATUS_INVALID_LOCKTYPE;
1825
2031
  return 0;
@@ -1851,17 +2057,17 @@ __int64 table::insert(bool ncc)
1851
2057
  else if (!m_bulkInserting)
1852
2058
  key_copy(&m_keybuf[0], m_table->record[0],
1853
2059
  &m_table->key_info[m_keyNum], KEYLEN_ALLCOPY);
1854
- m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
1855
-
2060
+
2061
+ /* Do not change to m_changed = false */
1856
2062
  m_changed = true;
1857
2063
  }
2064
+ m_nounlock = setCursorStaus();
1858
2065
  return autoincValue;
1859
2066
  }
1860
2067
 
1861
2068
  void table::beginUpdate(char keyNum)
1862
2069
  {
1863
2070
  m_stat = 0;
1864
- m_table->file->try_semi_consistent_read(1);
1865
2071
  beginDel();
1866
2072
  if (m_stat == 0)
1867
2073
  {
@@ -1877,11 +2083,18 @@ void table::beginUpdate(char keyNum)
1877
2083
 
1878
2084
  void table::beginDel()
1879
2085
  {
1880
- if ((m_mode == TD_OPEN_READONLY) || !cp_is_write_lock(m_table->file))
2086
+ if ((m_mode == TD_OPEN_READONLY) || (m_table->reginfo.lock_type < TL_WRITE))
1881
2087
  {
1882
2088
  m_stat = STATUS_INVALID_LOCKTYPE;
1883
2089
  return;
1884
2090
  }
2091
+
2092
+ if (m_db.m_inAutoTransaction == this)
2093
+ {
2094
+ // Confirmed that hold lock(X) by innodb_lock_monitor
2095
+ indexInit();
2096
+ }
2097
+
1885
2098
  if (m_cursor)
1886
2099
  {
1887
2100
  m_stat = 0;
@@ -1900,12 +2113,12 @@ void table::beginDel()
1900
2113
  else
1901
2114
  movePos(position(true), -1, true);
1902
2115
 
1903
- // Has blob fileds then ignore conflicts.
2116
+ // Has blob fields then ignore conflicts.
1904
2117
  if ((m_table->s->blob_fields == 0) &&
1905
2118
  cmp_record(m_table, record[1]))
1906
2119
  m_stat = STATUS_CHANGE_CONFLICT;
1907
2120
 
1908
- m_cursor = m_validCursor = (m_stat == 0);
2121
+ setCursorStaus();
1909
2122
  if (m_stat)
1910
2123
  return;
1911
2124
  }
@@ -1922,7 +2135,6 @@ void table::update(bool ncc)
1922
2135
  {
1923
2136
  if (m_stat == 0)
1924
2137
  {
1925
-
1926
2138
  int nullFieldsOfCurrentKey = setKeyNullFlags();
1927
2139
  setFiledNullFlags();
1928
2140
  m_stat = m_table->file->ha_update_row(m_table->record[1],
@@ -1949,12 +2161,11 @@ void table::update(bool ncc)
1949
2161
  }
1950
2162
  }
1951
2163
  }
1952
- m_cursor = m_validCursor = m_nounlock = (m_stat == 0);
2164
+ /* Do not change to m_changed = false */
2165
+ if (m_stat == 0) m_changed = true;
2166
+ m_nounlock = setCursorStaus();
1953
2167
  }
1954
2168
  }
1955
- if (m_stat == 0)
1956
- m_changed = true;
1957
- m_table->file->try_semi_consistent_read(0);
1958
2169
  }
1959
2170
 
1960
2171
  /** del current record.
@@ -1964,9 +2175,15 @@ void table::update(bool ncc)
1964
2175
  void table::del()
1965
2176
  {
1966
2177
  if (m_stat == 0)
2178
+ {
1967
2179
  m_stat = m_table->file->ha_delete_row(m_table->record[0]);
1968
- if (m_stat == 0)
1969
- m_changed = true;
2180
+ /* Do not change to m_changed = false */
2181
+ if (m_stat == 0) m_changed = true;
2182
+ }
2183
+
2184
+ //No cursor changed
2185
+ m_nounlock = (m_stat == 0);
2186
+
1970
2187
  }
1971
2188
 
1972
2189
  #ifdef USE_BTRV_VARIABLE_LEN
@@ -2018,6 +2235,11 @@ int table::keynumByName(const char* name) const
2018
2235
 
2019
2236
  void table::startBulkInsert(ha_rows rows)
2020
2237
  {
2238
+ if ((m_mode == TD_OPEN_READONLY) || (m_table->reginfo.lock_type < TL_WRITE))
2239
+ {
2240
+ m_stat = STATUS_INVALID_LOCKTYPE;
2241
+ return ;
2242
+ }
2021
2243
  m_table->file->ha_start_bulk_insert(rows);
2022
2244
  m_bulkInserting = true;
2023
2245
  }
@@ -2034,11 +2256,11 @@ void table::endBulkInsert()
2034
2256
  }
2035
2257
  }
2036
2258
 
2037
- const char* table::valStr(int filedNum, int& size)
2259
+ const char* table::valStr(int fieldNum, int& size)
2038
2260
  {
2039
- assert((filedNum >= 0) && (filedNum < (int)m_table->s->fields));
2261
+ assert((fieldNum >= 0) && (fieldNum < (int)m_table->s->fields));
2040
2262
 
2041
- Field* fd = m_table->field[filedNum];
2263
+ Field* fd = m_table->field[fieldNum];
2042
2264
  size = -1;
2043
2265
  if (fd->is_null())
2044
2266
  return "";
@@ -2086,7 +2308,7 @@ void table::setUseFieldList(const std::string& csv)
2086
2308
  {
2087
2309
  std::vector<std::string> values;
2088
2310
  split(values, csv, ",");
2089
- for (int i = 0; i < values.size(); i++)
2311
+ for (int i = 0; i < (int)values.size(); i++)
2090
2312
  addUseField(fieldIndexByName(values[i].c_str()));
2091
2313
  }
2092
2314