OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
MySQLAssetData.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Data;
30 using System.Reflection;
31 using System.Collections.Generic;
32 using log4net;
33 using MySql.Data.MySqlClient;
34 using OpenMetaverse;
35 using OpenSim.Framework;
36 using OpenSim.Data;
37 
38 namespace OpenSim.Data.MySQL
39 {
44  {
45  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 
47  private string m_connectionString;
48 
49  protected virtual Assembly Assembly
50  {
51  get { return GetType().Assembly; }
52  }
53 
54  #region IPlugin Members
55 
56  public override string Version { get { return "1.0.0.0"; } }
57 
69  public override void Initialise(string connect)
70  {
71  m_connectionString = connect;
72 
73  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
74  {
75  dbcon.Open();
76  Migration m = new Migration(dbcon, Assembly, "AssetStore");
77  m.Update();
78  }
79  }
80 
81  public override void Initialise()
82  {
83  throw new NotImplementedException();
84  }
85 
86  public override void Dispose() { }
87 
91  override public string Name
92  {
93  get { return "MySQL Asset storage engine"; }
94  }
95 
96  #endregion
97 
98  #region IAssetDataPlugin Members
99 
106  override public AssetBase GetAsset(UUID assetID)
107  {
108  AssetBase asset = null;
109 
110  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
111  {
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))
117  {
118  cmd.Parameters.AddWithValue("?id", assetID.ToString());
119 
120  try
121  {
122  using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
123  {
124  if (dbReader.Read())
125  {
126  asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["assetType"], dbReader["CreatorID"].ToString());
127  asset.Data = (byte[])dbReader["data"];
128  asset.Description = (string)dbReader["description"];
129 
130  string local = dbReader["local"].ToString();
131  if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
132  asset.Local = true;
133  else
134  asset.Local = false;
135 
136  asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
137  asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
138  }
139  }
140  }
141  catch (Exception e)
142  {
143  m_log.Error(
144  string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
145  }
146  }
147  }
148 
149  return asset;
150  }
151 
157  override public bool StoreAsset(AssetBase asset)
158  {
159  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
160  {
161  dbcon.Open();
162 
163  string assetName = asset.Name;
164  if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
165  {
166  assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
167  m_log.WarnFormat(
168  "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
169  asset.Name, asset.ID, asset.Name.Length, assetName.Length);
170  }
171 
172  string assetDescription = asset.Description;
173  if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
174  {
175  assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
176  m_log.WarnFormat(
177  "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
178  asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
179  }
180 
181  using (MySqlCommand cmd =
182  new MySqlCommand(
183  "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
184  "VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
185  dbcon))
186  {
187  try
188  {
189  // create unix epoch time
190  int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
191  cmd.Parameters.AddWithValue("?id", asset.ID);
192  cmd.Parameters.AddWithValue("?name", assetName);
193  cmd.Parameters.AddWithValue("?description", assetDescription);
194  cmd.Parameters.AddWithValue("?assetType", asset.Type);
195  cmd.Parameters.AddWithValue("?local", asset.Local);
196  cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
197  cmd.Parameters.AddWithValue("?create_time", now);
198  cmd.Parameters.AddWithValue("?access_time", now);
199  cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
200  cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
201  cmd.Parameters.AddWithValue("?data", asset.Data);
202  cmd.ExecuteNonQuery();
203  return true;
204  }
205  catch (Exception e)
206  {
207  m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
208  asset.FullID, asset.Name, e.Message);
209  return false;
210  }
211  }
212  }
213  }
214 
215  private void UpdateAccessTime(AssetBase asset)
216  {
217  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
218  {
219  dbcon.Open();
220 
221  using (MySqlCommand cmd
222  = new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
223  {
224  try
225  {
226  // create unix epoch time
227  int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
228  cmd.Parameters.AddWithValue("?id", asset.ID);
229  cmd.Parameters.AddWithValue("?access_time", now);
230  cmd.ExecuteNonQuery();
231  }
232  catch (Exception e)
233  {
234  m_log.Error(
235  string.Format(
236  "[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
237  asset.FullID, asset.Name),
238  e);
239  }
240  }
241  }
242  }
243 
249  public override bool[] AssetsExist(UUID[] uuids)
250  {
251  if (uuids.Length == 0)
252  return new bool[0];
253 
254  HashSet<UUID> exist = new HashSet<UUID>();
255 
256  string ids = "'" + string.Join("','", uuids) + "'";
257  string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
258 
259  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
260  {
261  dbcon.Open();
262  using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
263  {
264  using (MySqlDataReader dbReader = cmd.ExecuteReader())
265  {
266  while (dbReader.Read())
267  {
268  UUID id = DBGuid.FromDB(dbReader["id"]);
269  exist.Add(id);
270  }
271  }
272  }
273  }
274 
275  bool[] results = new bool[uuids.Length];
276  for (int i = 0; i < uuids.Length; i++)
277  results[i] = exist.Contains(uuids[i]);
278 
279  return results;
280  }
281 
290  public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
291  {
292  List<AssetMetadata> retList = new List<AssetMetadata>(count);
293 
294  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
295  {
296  dbcon.Open();
297 
298  using (MySqlCommand cmd
299  = new MySqlCommand(
300  "SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
301  dbcon))
302  {
303  cmd.Parameters.AddWithValue("?start", start);
304  cmd.Parameters.AddWithValue("?count", count);
305 
306  try
307  {
308  using (MySqlDataReader dbReader = cmd.ExecuteReader())
309  {
310  while (dbReader.Read())
311  {
312  AssetMetadata metadata = new AssetMetadata();
313  metadata.Name = (string)dbReader["name"];
314  metadata.Description = (string)dbReader["description"];
315  metadata.Type = (sbyte)dbReader["assetType"];
316  metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
317  metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
318  metadata.FullID = DBGuid.FromDB(dbReader["id"]);
319  metadata.CreatorID = dbReader["CreatorID"].ToString();
320 
321  // Current SHA1s are not stored/computed.
322  metadata.SHA1 = new byte[] { };
323 
324  retList.Add(metadata);
325  }
326  }
327  }
328  catch (Exception e)
329  {
330  m_log.Error(
331  string.Format(
332  "[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
333  start, count),
334  e);
335  }
336  }
337  }
338 
339  return retList;
340  }
341 
342  public override bool Delete(string id)
343  {
344  using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
345  {
346  dbcon.Open();
347 
348  using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
349  {
350  cmd.Parameters.AddWithValue("?id", id);
351  cmd.ExecuteNonQuery();
352  }
353  }
354 
355  return true;
356  }
357 
358  #endregion
359  }
360 }
OpenSim.Server.Handlers.Simulation.Utils Utils
override AssetBase GetAsset(UUID assetID)
Fetch Asset assetID from database
override void Initialise()
Default-initialises the plugin
override List< AssetMetadata > FetchAssetMetadataSet(int start, int count)
Returns a list of AssetMetadata objects. The list is a subset of the entire data set offset by start ...
A MySQL Interface for the Asset Server
override bool StoreAsset(AssetBase asset)
Create an asset in database, or update it if existing.
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
static readonly int MAX_ASSET_NAME
Definition: AssetBase.cs:53
override bool[] AssetsExist(UUID[] uuids)
Check if the assets exist in the database.
static readonly int MAX_ASSET_DESC
Definition: AssetBase.cs:54
override void Initialise(string connect)
override bool Delete(string id)