aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data
diff options
context:
space:
mode:
authorMelanie Thielker2017-03-23 23:00:48 +0000
committerMelanie Thielker2017-03-31 14:38:41 +0100
commit680231d7e79cae2636e9722ca12b79345fa2dbdd (patch)
tree183a1b0d9e3e39b645b4897047c8338dda7f0d3d /OpenSim/Data
parentAllow short-circuiting region restart delays of there are no users left (diff)
downloadopensim-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')
-rw-r--r--OpenSim/Data/MySQL/MySQLFramework.cs75
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs163
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;
36namespace OpenSim.Data.MySQL 36namespace 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}