aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/PGSQL/PGSQLAssetData.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/PGSQL/PGSQLAssetData.cs295
1 files changed, 295 insertions, 0 deletions
diff --git a/OpenSim/Data/PGSQL/PGSQLAssetData.cs b/OpenSim/Data/PGSQL/PGSQLAssetData.cs
new file mode 100644
index 0000000..ab74856
--- /dev/null
+++ b/OpenSim/Data/PGSQL/PGSQLAssetData.cs
@@ -0,0 +1,295 @@
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
28using System;
29using System.Data;
30using System.Reflection;
31using System.Collections.Generic;
32using OpenMetaverse;
33using log4net;
34using OpenSim.Framework;
35using Npgsql;
36using NpgsqlTypes;
37
38namespace OpenSim.Data.PGSQL
39{
40 /// <summary>
41 /// A PGSQL Interface for the Asset server
42 /// </summary>
43 public class PGSQLAssetData : AssetDataBase
44 {
45 private const string _migrationStore = "AssetStore";
46
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 private long m_ticksToEpoch;
49 /// <summary>
50 /// Database manager
51 /// </summary>
52 private PGSQLManager m_database;
53 private string m_connectionString;
54
55 protected virtual Assembly Assembly
56 {
57 get { return GetType().Assembly; }
58 }
59
60 #region IPlugin Members
61
62 override public void Dispose() { }
63
64 /// <summary>
65 /// <para>Initialises asset interface</para>
66 /// </summary>
67 // [Obsolete("Cannot be default-initialized!")]
68 override public void Initialise()
69 {
70 m_log.Info("[PGSQLAssetData]: " + Name + " cannot be default-initialized!");
71 throw new PluginNotInitialisedException(Name);
72 }
73
74 /// <summary>
75 /// Initialises asset interface
76 /// </summary>
77 /// <para>
78 /// a string instead of file, if someone writes the support
79 /// </para>
80 /// <param name="connectionString">connect string</param>
81 override public void Initialise(string connectionString)
82 {
83 m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
84
85 m_database = new PGSQLManager(connectionString);
86 m_connectionString = connectionString;
87
88 //New migration to check for DB changes
89 m_database.CheckMigration(_migrationStore);
90 }
91
92 /// <summary>
93 /// Database provider version.
94 /// </summary>
95 override public string Version
96 {
97 get { return m_database.getVersion(); }
98 }
99
100 /// <summary>
101 /// The name of this DB provider.
102 /// </summary>
103 override public string Name
104 {
105 get { return "PGSQL Asset storage engine"; }
106 }
107
108 #endregion
109
110 #region IAssetDataPlugin Members
111
112 /// <summary>
113 /// Fetch Asset from m_database
114 /// </summary>
115 /// <param name="assetID">the asset UUID</param>
116 /// <returns></returns>
117 override public AssetBase GetAsset(UUID assetID)
118 {
119 string sql = "SELECT * FROM assets WHERE id = :id";
120 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
121 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
122 {
123 cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
124 conn.Open();
125 using (NpgsqlDataReader reader = cmd.ExecuteReader())
126 {
127 if (reader.Read())
128 {
129 AssetBase asset = new AssetBase(
130 DBGuid.FromDB(reader["id"]),
131 (string)reader["name"],
132 Convert.ToSByte(reader["assetType"]),
133 reader["creatorid"].ToString()
134 );
135 // Region Main
136 asset.Description = (string)reader["description"];
137 asset.Local = Convert.ToBoolean(reader["local"]);
138 asset.Temporary = Convert.ToBoolean(reader["temporary"]);
139 asset.Flags = (AssetFlags)(Convert.ToInt32(reader["asset_flags"]));
140 asset.Data = (byte[])reader["data"];
141 return asset;
142 }
143 return null; // throw new Exception("No rows to return");
144 }
145 }
146 }
147
148 /// <summary>
149 /// Create asset in m_database
150 /// </summary>
151 /// <param name="asset">the asset</param>
152 override public void StoreAsset(AssetBase asset)
153 {
154
155 string sql =
156 @"UPDATE assets set name = :name, description = :description, " + "\"assetType\" " + @" = :assetType,
157 local = :local, temporary = :temporary, creatorid = :creatorid, data = :data
158 WHERE id=:id;
159
160 INSERT INTO assets
161 (id, name, description, " + "\"assetType\" " + @", local,
162 temporary, create_time, access_time, creatorid, asset_flags, data)
163 Select :id, :name, :description, :assetType, :local,
164 :temporary, :create_time, :access_time, :creatorid, :asset_flags, :data
165 Where not EXISTS(SELECT * FROM assets WHERE id=:id)
166 ";
167
168 string assetName = asset.Name;
169 if (asset.Name.Length > 64)
170 {
171 assetName = asset.Name.Substring(0, 64);
172 m_log.WarnFormat(
173 "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
174 asset.Name, asset.ID, asset.Name.Length, assetName.Length);
175 }
176
177 string assetDescription = asset.Description;
178 if (asset.Description.Length > 64)
179 {
180 assetDescription = asset.Description.Substring(0, 64);
181 m_log.WarnFormat(
182 "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
183 asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
184 }
185
186 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
187 using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
188 {
189 int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
190 command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
191 command.Parameters.Add(m_database.CreateParameter("name", assetName));
192 command.Parameters.Add(m_database.CreateParameter("description", assetDescription));
193 command.Parameters.Add(m_database.CreateParameter("assetType", asset.Type));
194 command.Parameters.Add(m_database.CreateParameter("local", asset.Local));
195 command.Parameters.Add(m_database.CreateParameter("temporary", asset.Temporary));
196 command.Parameters.Add(m_database.CreateParameter("access_time", now));
197 command.Parameters.Add(m_database.CreateParameter("create_time", now));
198 command.Parameters.Add(m_database.CreateParameter("asset_flags", (int)asset.Flags));
199 command.Parameters.Add(m_database.CreateParameter("creatorid", asset.Metadata.CreatorID));
200 command.Parameters.Add(m_database.CreateParameter("data", asset.Data));
201 conn.Open();
202 try
203 {
204 command.ExecuteNonQuery();
205 }
206 catch(Exception e)
207 {
208 m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql);
209 }
210 }
211 }
212
213
214// Commented out since currently unused - this probably should be called in GetAsset()
215// private void UpdateAccessTime(AssetBase asset)
216// {
217// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = :access_time WHERE id=:id"))
218// {
219// int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
220// cmd.Parameters.AddWithValue(":id", asset.FullID.ToString());
221// cmd.Parameters.AddWithValue(":access_time", now);
222// try
223// {
224// cmd.ExecuteNonQuery();
225// }
226// catch (Exception e)
227// {
228// m_log.Error(e.ToString());
229// }
230// }
231// }
232
233 /// <summary>
234 /// Check if asset exist in m_database
235 /// </summary>
236 /// <param name="uuid"></param>
237 /// <returns>true if exist.</returns>
238 override public bool ExistsAsset(UUID uuid)
239 {
240 if (GetAsset(uuid) != null)
241 {
242 return true;
243 }
244 return false;
245 }
246
247 /// <summary>
248 /// Returns a list of AssetMetadata objects. The list is a subset of
249 /// the entire data set offset by <paramref name="start" /> containing
250 /// <paramref name="count" /> elements.
251 /// </summary>
252 /// <param name="start">The number of results to discard from the total data set.</param>
253 /// <param name="count">The number of rows the returned list should contain.</param>
254 /// <returns>A list of AssetMetadata objects.</returns>
255 public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
256 {
257 List<AssetMetadata> retList = new List<AssetMetadata>(count);
258 string sql = @" SELECT id, name, description, " + "\"assetType\"" + @", temporary, creatorid
259 FROM assets
260 order by id
261 limit :stop
262 offset :start;";
263
264 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
265 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
266 {
267 cmd.Parameters.Add(m_database.CreateParameter("start", start));
268 cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
269 conn.Open();
270 using (NpgsqlDataReader reader = cmd.ExecuteReader())
271 {
272 while (reader.Read())
273 {
274 AssetMetadata metadata = new AssetMetadata();
275 metadata.FullID = DBGuid.FromDB(reader["id"]);
276 metadata.Name = (string)reader["name"];
277 metadata.Description = (string)reader["description"];
278 metadata.Type = Convert.ToSByte(reader["assetType"]);
279 metadata.Temporary = Convert.ToBoolean(reader["temporary"]);
280 metadata.CreatorID = (string)reader["creatorid"];
281 retList.Add(metadata);
282 }
283 }
284 }
285
286 return retList;
287 }
288
289 public override bool Delete(string id)
290 {
291 return false;
292 }
293 #endregion
294 }
295}