diff options
author | Melanie Thielker | 2017-03-23 23:00:48 +0000 |
---|---|---|
committer | Melanie Thielker | 2017-03-31 14:38:41 +0100 |
commit | 680231d7e79cae2636e9722ca12b79345fa2dbdd (patch) | |
tree | 183a1b0d9e3e39b645b4897047c8338dda7f0d3d /OpenSim/Data/MySQL | |
parent | Allow short-circuiting region restart delays of there are no users left (diff) | |
download | opensim-SC_OLD-680231d7e79cae2636e9722ca12b79345fa2dbdd.zip opensim-SC_OLD-680231d7e79cae2636e9722ca12b79345fa2dbdd.tar.gz opensim-SC_OLD-680231d7e79cae2636e9722ca12b79345fa2dbdd.tar.bz2 opensim-SC_OLD-680231d7e79cae2636e9722ca12b79345fa2dbdd.tar.xz |
Make the MySqlGeneric layer transaction aware
Diffstat (limited to 'OpenSim/Data/MySQL')
-rw-r--r-- | OpenSim/Data/MySQL/MySQLFramework.cs | 75 | ||||
-rw-r--r-- | OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 163 |
2 files changed, 155 insertions, 83 deletions
diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index 34791cf..93662db 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs | |||
@@ -36,7 +36,7 @@ using MySql.Data.MySqlClient; | |||
36 | namespace OpenSim.Data.MySQL | 36 | namespace OpenSim.Data.MySQL |
37 | { | 37 | { |
38 | /// <summary> | 38 | /// <summary> |
39 | /// A database interface class to a user profile storage system | 39 | /// Common code for a number of database modules |
40 | /// </summary> | 40 | /// </summary> |
41 | public class MySqlFramework | 41 | public class MySqlFramework |
42 | { | 42 | { |
@@ -44,14 +44,24 @@ namespace OpenSim.Data.MySQL | |||
44 | log4net.LogManager.GetLogger( | 44 | log4net.LogManager.GetLogger( |
45 | System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 45 | System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | protected string m_connectionString; | 47 | protected string m_connectionString = String.Empty; |
48 | protected object m_dbLock = new object(); | 48 | protected MySqlTransaction m_trans = null; |
49 | 49 | ||
50 | // Constructor using a connection string. Instances constructed | ||
51 | // this way will open a new connection for each call. | ||
50 | protected MySqlFramework(string connectionString) | 52 | protected MySqlFramework(string connectionString) |
51 | { | 53 | { |
52 | m_connectionString = connectionString; | 54 | m_connectionString = connectionString; |
53 | } | 55 | } |
54 | 56 | ||
57 | // Constructor using a connection object. Instances constructed | ||
58 | // this way will use the connection object and never create | ||
59 | // new connections. | ||
60 | protected MySqlFramework(MySqlTransaction trans) | ||
61 | { | ||
62 | m_trans = trans; | ||
63 | } | ||
64 | |||
55 | ////////////////////////////////////////////////////////////// | 65 | ////////////////////////////////////////////////////////////// |
56 | // | 66 | // |
57 | // All non queries are funneled through one connection | 67 | // All non queries are funneled through one connection |
@@ -59,33 +69,48 @@ namespace OpenSim.Data.MySQL | |||
59 | // | 69 | // |
60 | protected int ExecuteNonQuery(MySqlCommand cmd) | 70 | protected int ExecuteNonQuery(MySqlCommand cmd) |
61 | { | 71 | { |
62 | lock (m_dbLock) | 72 | if (m_trans == null) |
63 | { | 73 | { |
64 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 74 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
65 | { | 75 | { |
66 | try | 76 | dbcon.Open(); |
67 | { | 77 | return ExecuteNonQueryWithConnection(cmd, dbcon); |
68 | dbcon.Open(); | 78 | } |
69 | cmd.Connection = dbcon; | 79 | } |
80 | else | ||
81 | { | ||
82 | return ExecuteNonQueryWithTransaction(cmd, m_trans); | ||
83 | } | ||
84 | } | ||
70 | 85 | ||
71 | try | 86 | private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) |
72 | { | 87 | { |
73 | return cmd.ExecuteNonQuery(); | 88 | cmd.Transaction = trans; |
74 | } | 89 | return ExecuteNonQueryWithConnection(cmd, trans.Connection); |
75 | catch (Exception e) | 90 | } |
76 | { | 91 | |
77 | m_log.Error(e.Message, e); | 92 | private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) |
78 | m_log.Error(Environment.StackTrace.ToString()); | 93 | { |
79 | return 0; | 94 | try |
80 | } | 95 | { |
81 | } | 96 | cmd.Connection = dbcon; |
82 | catch (Exception e) | 97 | |
83 | { | 98 | try |
84 | m_log.Error(e.Message, e); | 99 | { |
85 | return 0; | 100 | return cmd.ExecuteNonQuery(); |
86 | } | ||
87 | } | 101 | } |
102 | catch (Exception e) | ||
103 | { | ||
104 | m_log.Error(e.Message, e); | ||
105 | m_log.Error(Environment.StackTrace.ToString()); | ||
106 | return 0; | ||
107 | } | ||
108 | } | ||
109 | catch (Exception e) | ||
110 | { | ||
111 | m_log.Error(e.Message, e); | ||
112 | return 0; | ||
88 | } | 113 | } |
89 | } | 114 | } |
90 | } | 115 | } |
91 | } \ No newline at end of file | 116 | } |
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 6aae9c6..bd8bbd5 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | |||
@@ -53,14 +53,27 @@ namespace OpenSim.Data.MySQL | |||
53 | get { return GetType().Assembly; } | 53 | get { return GetType().Assembly; } |
54 | } | 54 | } |
55 | 55 | ||
56 | public MySQLGenericTableHandler(MySqlTransaction trans, | ||
57 | string realm, string storeName) : base(trans) | ||
58 | { | ||
59 | m_Realm = realm; | ||
60 | |||
61 | CommonConstruct(storeName); | ||
62 | } | ||
63 | |||
56 | public MySQLGenericTableHandler(string connectionString, | 64 | public MySQLGenericTableHandler(string connectionString, |
57 | string realm, string storeName) : base(connectionString) | 65 | string realm, string storeName) : base(connectionString) |
58 | { | 66 | { |
59 | m_Realm = realm; | 67 | m_Realm = realm; |
60 | m_connectionString = connectionString; | ||
61 | 68 | ||
69 | CommonConstruct(storeName); | ||
70 | } | ||
71 | |||
72 | protected void CommonConstruct(string storeName) | ||
73 | { | ||
62 | if (storeName != String.Empty) | 74 | if (storeName != String.Empty) |
63 | { | 75 | { |
76 | // We always use a new connection for any Migrations | ||
64 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 77 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
65 | { | 78 | { |
66 | dbcon.Open(); | 79 | dbcon.Open(); |
@@ -111,6 +124,11 @@ namespace OpenSim.Data.MySQL | |||
111 | 124 | ||
112 | public virtual T[] Get(string[] fields, string[] keys) | 125 | public virtual T[] Get(string[] fields, string[] keys) |
113 | { | 126 | { |
127 | return Get(fields, keys, String.Empty); | ||
128 | } | ||
129 | |||
130 | public virtual T[] Get(string[] fields, string[] keys, string options) | ||
131 | { | ||
114 | if (fields.Length != keys.Length) | 132 | if (fields.Length != keys.Length) |
115 | return new T[0]; | 133 | return new T[0]; |
116 | 134 | ||
@@ -126,8 +144,8 @@ namespace OpenSim.Data.MySQL | |||
126 | 144 | ||
127 | string where = String.Join(" and ", terms.ToArray()); | 145 | string where = String.Join(" and ", terms.ToArray()); |
128 | 146 | ||
129 | string query = String.Format("select * from {0} where {1}", | 147 | string query = String.Format("select * from {0} where {1} {2}", |
130 | m_Realm, where); | 148 | m_Realm, where, options); |
131 | 149 | ||
132 | cmd.CommandText = query; | 150 | cmd.CommandText = query; |
133 | 151 | ||
@@ -137,72 +155,92 @@ namespace OpenSim.Data.MySQL | |||
137 | 155 | ||
138 | protected T[] DoQuery(MySqlCommand cmd) | 156 | protected T[] DoQuery(MySqlCommand cmd) |
139 | { | 157 | { |
158 | if (m_trans == null) | ||
159 | { | ||
160 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
161 | { | ||
162 | dbcon.Open(); | ||
163 | |||
164 | return DoQueryWithConnection(cmd, dbcon); | ||
165 | } | ||
166 | } | ||
167 | else | ||
168 | { | ||
169 | return DoQueryWithTransaction(cmd, m_trans); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans) | ||
174 | { | ||
175 | cmd.Transaction = trans; | ||
176 | |||
177 | return DoQueryWithConnection(cmd, trans.Connection); | ||
178 | } | ||
179 | |||
180 | protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon) | ||
181 | { | ||
140 | List<T> result = new List<T>(); | 182 | List<T> result = new List<T>(); |
141 | 183 | ||
142 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 184 | cmd.Connection = dbcon; |
185 | |||
186 | using (IDataReader reader = cmd.ExecuteReader()) | ||
143 | { | 187 | { |
144 | dbcon.Open(); | 188 | if (reader == null) |
145 | cmd.Connection = dbcon; | 189 | return new T[0]; |
146 | 190 | ||
147 | using (IDataReader reader = cmd.ExecuteReader()) | 191 | CheckColumnNames(reader); |
148 | { | ||
149 | if (reader == null) | ||
150 | return new T[0]; | ||
151 | 192 | ||
152 | CheckColumnNames(reader); | 193 | while (reader.Read()) |
194 | { | ||
195 | T row = new T(); | ||
153 | 196 | ||
154 | while (reader.Read()) | 197 | foreach (string name in m_Fields.Keys) |
155 | { | 198 | { |
156 | T row = new T(); | 199 | if (reader[name] is DBNull) |
157 | |||
158 | foreach (string name in m_Fields.Keys) | ||
159 | { | 200 | { |
160 | if (reader[name] is DBNull) | 201 | continue; |
161 | { | ||
162 | continue; | ||
163 | } | ||
164 | if (m_Fields[name].FieldType == typeof(bool)) | ||
165 | { | ||
166 | int v = Convert.ToInt32(reader[name]); | ||
167 | m_Fields[name].SetValue(row, v != 0 ? true : false); | ||
168 | } | ||
169 | else if (m_Fields[name].FieldType == typeof(UUID)) | ||
170 | { | ||
171 | m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); | ||
172 | } | ||
173 | else if (m_Fields[name].FieldType == typeof(int)) | ||
174 | { | ||
175 | int v = Convert.ToInt32(reader[name]); | ||
176 | m_Fields[name].SetValue(row, v); | ||
177 | } | ||
178 | else if (m_Fields[name].FieldType == typeof(uint)) | ||
179 | { | ||
180 | uint v = Convert.ToUInt32(reader[name]); | ||
181 | m_Fields[name].SetValue(row, v); | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | m_Fields[name].SetValue(row, reader[name]); | ||
186 | } | ||
187 | } | 202 | } |
188 | 203 | if (m_Fields[name].FieldType == typeof(bool)) | |
189 | if (m_DataField != null) | 204 | { |
205 | int v = Convert.ToInt32(reader[name]); | ||
206 | m_Fields[name].SetValue(row, v != 0 ? true : false); | ||
207 | } | ||
208 | else if (m_Fields[name].FieldType == typeof(UUID)) | ||
209 | { | ||
210 | m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name])); | ||
211 | } | ||
212 | else if (m_Fields[name].FieldType == typeof(int)) | ||
213 | { | ||
214 | int v = Convert.ToInt32(reader[name]); | ||
215 | m_Fields[name].SetValue(row, v); | ||
216 | } | ||
217 | else if (m_Fields[name].FieldType == typeof(uint)) | ||
218 | { | ||
219 | uint v = Convert.ToUInt32(reader[name]); | ||
220 | m_Fields[name].SetValue(row, v); | ||
221 | } | ||
222 | else | ||
190 | { | 223 | { |
191 | Dictionary<string, string> data = | 224 | m_Fields[name].SetValue(row, reader[name]); |
192 | new Dictionary<string, string>(); | 225 | } |
226 | } | ||
193 | 227 | ||
194 | foreach (string col in m_ColumnNames) | 228 | if (m_DataField != null) |
195 | { | 229 | { |
196 | data[col] = reader[col].ToString(); | 230 | Dictionary<string, string> data = |
197 | if (data[col] == null) | 231 | new Dictionary<string, string>(); |
198 | data[col] = String.Empty; | ||
199 | } | ||
200 | 232 | ||
201 | m_DataField.SetValue(row, data); | 233 | foreach (string col in m_ColumnNames) |
234 | { | ||
235 | data[col] = reader[col].ToString(); | ||
236 | if (data[col] == null) | ||
237 | data[col] = String.Empty; | ||
202 | } | 238 | } |
203 | 239 | ||
204 | result.Add(row); | 240 | m_DataField.SetValue(row, data); |
205 | } | 241 | } |
242 | |||
243 | result.Add(row); | ||
206 | } | 244 | } |
207 | } | 245 | } |
208 | 246 | ||
@@ -357,14 +395,23 @@ namespace OpenSim.Data.MySQL | |||
357 | 395 | ||
358 | public object DoQueryScalar(MySqlCommand cmd) | 396 | public object DoQueryScalar(MySqlCommand cmd) |
359 | { | 397 | { |
360 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 398 | if (m_trans == null) |
361 | { | 399 | { |
362 | dbcon.Open(); | 400 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
363 | cmd.Connection = dbcon; | 401 | { |
402 | dbcon.Open(); | ||
403 | cmd.Connection = dbcon; | ||
404 | |||
405 | return cmd.ExecuteScalar(); | ||
406 | } | ||
407 | } | ||
408 | else | ||
409 | { | ||
410 | cmd.Connection = m_trans.Connection; | ||
411 | cmd.Transaction = m_trans; | ||
364 | 412 | ||
365 | return cmd.ExecuteScalar(); | 413 | return cmd.ExecuteScalar(); |
366 | } | 414 | } |
367 | } | 415 | } |
368 | |||
369 | } | 416 | } |
370 | } | 417 | } |