diff options
Diffstat (limited to 'OpenSim/Data/MySQL/MySQLAssetData.cs')
-rw-r--r-- | OpenSim/Data/MySQL/MySQLAssetData.cs | 324 |
1 files changed, 159 insertions, 165 deletions
diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 73de64b..5d8da17 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs | |||
@@ -45,7 +45,6 @@ namespace OpenSim.Data.MySQL | |||
45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 46 | ||
47 | private string m_connectionString; | 47 | private string m_connectionString; |
48 | private object m_dbLock = new object(); | ||
49 | 48 | ||
50 | protected virtual Assembly Assembly | 49 | protected virtual Assembly Assembly |
51 | { | 50 | { |
@@ -107,46 +106,46 @@ namespace OpenSim.Data.MySQL | |||
107 | override public AssetBase GetAsset(UUID assetID) | 106 | override public AssetBase GetAsset(UUID assetID) |
108 | { | 107 | { |
109 | AssetBase asset = null; | 108 | AssetBase asset = null; |
110 | lock (m_dbLock) | 109 | |
110 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
111 | { | 111 | { |
112 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 112 | dbcon.Open(); |
113 | |||
114 | using (MySqlCommand cmd = new MySqlCommand( | ||
115 | "SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id", | ||
116 | dbcon)) | ||
113 | { | 117 | { |
114 | dbcon.Open(); | 118 | cmd.Parameters.AddWithValue("?id", assetID.ToString()); |
115 | 119 | ||
116 | using (MySqlCommand cmd = new MySqlCommand( | 120 | try |
117 | "SELECT name, description, assetType, local, temporary, asset_flags, CreatorID, data FROM assets WHERE id=?id", | ||
118 | dbcon)) | ||
119 | { | 121 | { |
120 | cmd.Parameters.AddWithValue("?id", assetID.ToString()); | 122 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) |
121 | |||
122 | try | ||
123 | { | 123 | { |
124 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | 124 | if (dbReader.Read()) |
125 | { | 125 | { |
126 | if (dbReader.Read()) | 126 | asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString()); |
127 | { | 127 | asset.Data = (byte[])dbReader["data"]; |
128 | asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString()); | 128 | asset.Description = (string)dbReader["description"]; |
129 | asset.Data = (byte[])dbReader["data"]; | 129 | |
130 | asset.Description = (string)dbReader["description"]; | 130 | string local = dbReader["local"].ToString(); |
131 | 131 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | |
132 | string local = dbReader["local"].ToString(); | 132 | asset.Local = true; |
133 | if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase)) | 133 | else |
134 | asset.Local = true; | 134 | asset.Local = false; |
135 | else | 135 | |
136 | asset.Local = false; | 136 | asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); |
137 | 137 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | |
138 | asset.Temporary = Convert.ToBoolean(dbReader["temporary"]); | ||
139 | asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | ||
140 | } | ||
141 | } | 138 | } |
142 | } | 139 | } |
143 | catch (Exception e) | 140 | } |
144 | { | 141 | catch (Exception e) |
145 | m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message); | 142 | { |
146 | } | 143 | m_log.Error( |
144 | string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); | ||
147 | } | 145 | } |
148 | } | 146 | } |
149 | } | 147 | } |
148 | |||
150 | return asset; | 149 | return asset; |
151 | } | 150 | } |
152 | 151 | ||
@@ -157,137 +156,134 @@ namespace OpenSim.Data.MySQL | |||
157 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> | 156 | /// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks> |
158 | override public void StoreAsset(AssetBase asset) | 157 | override public void StoreAsset(AssetBase asset) |
159 | { | 158 | { |
160 | lock (m_dbLock) | 159 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
161 | { | 160 | { |
162 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 161 | dbcon.Open(); |
162 | |||
163 | using (MySqlCommand cmd = | ||
164 | new MySqlCommand( | ||
165 | "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + | ||
166 | "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", | ||
167 | dbcon)) | ||
163 | { | 168 | { |
164 | dbcon.Open(); | 169 | string assetName = asset.Name; |
170 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
171 | { | ||
172 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
173 | m_log.WarnFormat( | ||
174 | "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
175 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
176 | } | ||
165 | 177 | ||
166 | using (MySqlCommand cmd = | 178 | string assetDescription = asset.Description; |
167 | new MySqlCommand( | 179 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) |
168 | "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + | ||
169 | "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)", | ||
170 | dbcon)) | ||
171 | { | 180 | { |
172 | string assetName = asset.Name; | 181 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); |
173 | if (asset.Name.Length > 64) | 182 | m_log.WarnFormat( |
174 | { | 183 | "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", |
175 | assetName = asset.Name.Substring(0, 64); | 184 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); |
176 | m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add"); | 185 | } |
177 | } | 186 | |
178 | 187 | try | |
179 | string assetDescription = asset.Description; | 188 | { |
180 | if (asset.Description.Length > 64) | 189 | using (cmd) |
181 | { | ||
182 | assetDescription = asset.Description.Substring(0, 64); | ||
183 | m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add"); | ||
184 | } | ||
185 | |||
186 | try | ||
187 | { | ||
188 | using (cmd) | ||
189 | { | ||
190 | // create unix epoch time | ||
191 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
192 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
193 | cmd.Parameters.AddWithValue("?name", assetName); | ||
194 | cmd.Parameters.AddWithValue("?description", assetDescription); | ||
195 | cmd.Parameters.AddWithValue("?assetType", asset.Type); | ||
196 | cmd.Parameters.AddWithValue("?local", asset.Local); | ||
197 | cmd.Parameters.AddWithValue("?temporary", asset.Temporary); | ||
198 | cmd.Parameters.AddWithValue("?create_time", now); | ||
199 | cmd.Parameters.AddWithValue("?access_time", now); | ||
200 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
201 | cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); | ||
202 | cmd.Parameters.AddWithValue("?data", asset.Data); | ||
203 | cmd.ExecuteNonQuery(); | ||
204 | } | ||
205 | } | ||
206 | catch (Exception e) | ||
207 | { | 190 | { |
208 | m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", | 191 | // create unix epoch time |
209 | asset.FullID, asset.Name, e.Message); | 192 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); |
193 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
194 | cmd.Parameters.AddWithValue("?name", assetName); | ||
195 | cmd.Parameters.AddWithValue("?description", assetDescription); | ||
196 | cmd.Parameters.AddWithValue("?assetType", asset.Type); | ||
197 | cmd.Parameters.AddWithValue("?local", asset.Local); | ||
198 | cmd.Parameters.AddWithValue("?temporary", asset.Temporary); | ||
199 | cmd.Parameters.AddWithValue("?create_time", now); | ||
200 | cmd.Parameters.AddWithValue("?access_time", now); | ||
201 | cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID); | ||
202 | cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); | ||
203 | cmd.Parameters.AddWithValue("?data", asset.Data); | ||
204 | cmd.ExecuteNonQuery(); | ||
210 | } | 205 | } |
211 | } | 206 | } |
207 | catch (Exception e) | ||
208 | { | ||
209 | m_log.Error( | ||
210 | string.Format( | ||
211 | "[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ", | ||
212 | asset.FullID, asset.Name) | ||
213 | , e); | ||
214 | } | ||
212 | } | 215 | } |
213 | } | 216 | } |
214 | } | 217 | } |
215 | 218 | ||
216 | private void UpdateAccessTime(AssetBase asset) | 219 | private void UpdateAccessTime(AssetBase asset) |
217 | { | 220 | { |
218 | lock (m_dbLock) | 221 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
219 | { | 222 | { |
220 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 223 | dbcon.Open(); |
221 | { | ||
222 | dbcon.Open(); | ||
223 | 224 | ||
224 | using (MySqlCommand cmd | 225 | using (MySqlCommand cmd |
225 | = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon)) | 226 | = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon)) |
227 | { | ||
228 | try | ||
226 | { | 229 | { |
227 | try | 230 | using (cmd) |
228 | { | ||
229 | using (cmd) | ||
230 | { | ||
231 | // create unix epoch time | ||
232 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); | ||
233 | cmd.Parameters.AddWithValue("?id", asset.ID); | ||
234 | cmd.Parameters.AddWithValue("?access_time", now); | ||
235 | cmd.ExecuteNonQuery(); | ||
236 | } | ||
237 | } | ||
238 | catch (Exception e) | ||
239 | { | 231 | { |
240 | m_log.ErrorFormat( | 232 | // create unix epoch time |
241 | "[ASSETS DB]: " + | 233 | int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow); |
242 | "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString() | 234 | cmd.Parameters.AddWithValue("?id", asset.ID); |
243 | + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name); | 235 | cmd.Parameters.AddWithValue("?access_time", now); |
236 | cmd.ExecuteNonQuery(); | ||
244 | } | 237 | } |
245 | } | 238 | } |
239 | catch (Exception e) | ||
240 | { | ||
241 | m_log.Error( | ||
242 | string.Format( | ||
243 | "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ", | ||
244 | asset.FullID, asset.Name), | ||
245 | e); | ||
246 | } | ||
246 | } | 247 | } |
247 | } | 248 | } |
248 | } | 249 | } |
249 | 250 | ||
250 | /// <summary> | 251 | /// <summary> |
251 | /// Check if the asset exists in the database | 252 | /// Check if the assets exist in the database. |
252 | /// </summary> | 253 | /// </summary> |
253 | /// <param name="uuid">The asset UUID</param> | 254 | /// <param name="uuidss">The assets' IDs</param> |
254 | /// <returns>true if it exists, false otherwise.</returns> | 255 | /// <returns>For each asset: true if it exists, false otherwise</returns> |
255 | override public bool ExistsAsset(UUID uuid) | 256 | public override bool[] AssetsExist(UUID[] uuids) |
256 | { | 257 | { |
257 | // m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid); | 258 | if (uuids.Length == 0) |
259 | return new bool[0]; | ||
258 | 260 | ||
259 | bool assetExists = false; | 261 | HashSet<UUID> exist = new HashSet<UUID>(); |
260 | 262 | ||
261 | lock (m_dbLock) | 263 | string ids = "'" + string.Join("','", uuids) + "'"; |
264 | string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids); | ||
265 | |||
266 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | ||
262 | { | 267 | { |
263 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 268 | dbcon.Open(); |
269 | using (MySqlCommand cmd = new MySqlCommand(sql, dbcon)) | ||
264 | { | 270 | { |
265 | dbcon.Open(); | 271 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) |
266 | using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon)) | ||
267 | { | 272 | { |
268 | cmd.Parameters.AddWithValue("?id", uuid.ToString()); | 273 | while (dbReader.Read()) |
269 | |||
270 | try | ||
271 | { | ||
272 | using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
273 | { | ||
274 | if (dbReader.Read()) | ||
275 | { | ||
276 | // m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid); | ||
277 | assetExists = true; | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | catch (Exception e) | ||
282 | { | 274 | { |
283 | m_log.ErrorFormat( | 275 | UUID id = DBGuid.FromDB(dbReader["id"]); |
284 | "[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid); | 276 | exist.Add(id); |
285 | } | 277 | } |
286 | } | 278 | } |
287 | } | 279 | } |
288 | } | 280 | } |
289 | 281 | ||
290 | return assetExists; | 282 | bool[] results = new bool[uuids.Length]; |
283 | for (int i = 0; i < uuids.Length; i++) | ||
284 | results[i] = exist.Contains(uuids[i]); | ||
285 | |||
286 | return results; | ||
291 | } | 287 | } |
292 | 288 | ||
293 | /// <summary> | 289 | /// <summary> |
@@ -302,46 +298,47 @@ namespace OpenSim.Data.MySQL | |||
302 | { | 298 | { |
303 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | 299 | List<AssetMetadata> retList = new List<AssetMetadata>(count); |
304 | 300 | ||
305 | lock (m_dbLock) | 301 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
306 | { | 302 | { |
307 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 303 | dbcon.Open(); |
304 | |||
305 | using (MySqlCommand cmd | ||
306 | = new MySqlCommand( | ||
307 | "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", | ||
308 | dbcon)) | ||
308 | { | 309 | { |
309 | dbcon.Open(); | 310 | cmd.Parameters.AddWithValue("?start", start); |
311 | cmd.Parameters.AddWithValue("?count", count); | ||
310 | 312 | ||
311 | using (MySqlCommand cmd | 313 | try |
312 | = new MySqlCommand( | ||
313 | "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", | ||
314 | dbcon)) | ||
315 | { | 314 | { |
316 | cmd.Parameters.AddWithValue("?start", start); | 315 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) |
317 | cmd.Parameters.AddWithValue("?count", count); | ||
318 | |||
319 | try | ||
320 | { | 316 | { |
321 | using (MySqlDataReader dbReader = cmd.ExecuteReader()) | 317 | while (dbReader.Read()) |
322 | { | 318 | { |
323 | while (dbReader.Read()) | 319 | AssetMetadata metadata = new AssetMetadata(); |
324 | { | 320 | metadata.Name = (string)dbReader["name"]; |
325 | AssetMetadata metadata = new AssetMetadata(); | 321 | metadata.Description = (string)dbReader["description"]; |
326 | metadata.Name = (string)dbReader["name"]; | 322 | metadata.Type = (sbyte)dbReader["assetType"]; |
327 | metadata.Description = (string)dbReader["description"]; | 323 | metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. |
328 | metadata.Type = (sbyte)dbReader["assetType"]; | 324 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); |
329 | metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct. | 325 | metadata.FullID = DBGuid.FromDB(dbReader["id"]); |
330 | metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]); | 326 | metadata.CreatorID = dbReader["CreatorID"].ToString(); |
331 | metadata.FullID = DBGuid.FromDB(dbReader["id"]); | 327 | |
332 | metadata.CreatorID = dbReader["CreatorID"].ToString(); | 328 | // Current SHA1s are not stored/computed. |
333 | 329 | metadata.SHA1 = new byte[] { }; | |
334 | // Current SHA1s are not stored/computed. | 330 | |
335 | metadata.SHA1 = new byte[] { }; | 331 | retList.Add(metadata); |
336 | |||
337 | retList.Add(metadata); | ||
338 | } | ||
339 | } | 332 | } |
340 | } | 333 | } |
341 | catch (Exception e) | 334 | } |
342 | { | 335 | catch (Exception e) |
343 | m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); | 336 | { |
344 | } | 337 | m_log.Error( |
338 | string.Format( | ||
339 | "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ", | ||
340 | start, count), | ||
341 | e); | ||
345 | } | 342 | } |
346 | } | 343 | } |
347 | } | 344 | } |
@@ -351,17 +348,14 @@ namespace OpenSim.Data.MySQL | |||
351 | 348 | ||
352 | public override bool Delete(string id) | 349 | public override bool Delete(string id) |
353 | { | 350 | { |
354 | lock (m_dbLock) | 351 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) |
355 | { | 352 | { |
356 | using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) | 353 | dbcon.Open(); |
357 | { | ||
358 | dbcon.Open(); | ||
359 | 354 | ||
360 | using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon)) | 355 | using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon)) |
361 | { | 356 | { |
362 | cmd.Parameters.AddWithValue("?id", id); | 357 | cmd.Parameters.AddWithValue("?id", id); |
363 | cmd.ExecuteNonQuery(); | 358 | cmd.ExecuteNonQuery(); |
364 | } | ||
365 | } | 359 | } |
366 | } | 360 | } |
367 | 361 | ||