aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/PGSQL/PGSQLAssetData.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/PGSQL/PGSQLAssetData.cs')
-rw-r--r--OpenSim/Data/PGSQL/PGSQLAssetData.cs296
1 files changed, 296 insertions, 0 deletions
diff --git a/OpenSim/Data/PGSQL/PGSQLAssetData.cs b/OpenSim/Data/PGSQL/PGSQLAssetData.cs
new file mode 100644
index 0000000..7c5c01d
--- /dev/null
+++ b/OpenSim/Data/PGSQL/PGSQLAssetData.cs
@@ -0,0 +1,296 @@
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 bool 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 return true;
212 }
213
214
215// Commented out since currently unused - this probably should be called in GetAsset()
216// private void UpdateAccessTime(AssetBase asset)
217// {
218// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = :access_time WHERE id=:id"))
219// {
220// int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
221// cmd.Parameters.AddWithValue(":id", asset.FullID.ToString());
222// cmd.Parameters.AddWithValue(":access_time", now);
223// try
224// {
225// cmd.ExecuteNonQuery();
226// }
227// catch (Exception e)
228// {
229// m_log.Error(e.ToString());
230// }
231// }
232// }
233
234 /// <summary>
235 /// Check if asset exist in m_database
236 /// </summary>
237 /// <param name="uuid"></param>
238 /// <returns>true if exist.</returns>
239 override public bool ExistsAsset(UUID uuid)
240 {
241 if (GetAsset(uuid) != null)
242 {
243 return true;
244 }
245 return false;
246 }
247
248 /// <summary>
249 /// Returns a list of AssetMetadata objects. The list is a subset of
250 /// the entire data set offset by <paramref name="start" /> containing
251 /// <paramref name="count" /> elements.
252 /// </summary>
253 /// <param name="start">The number of results to discard from the total data set.</param>
254 /// <param name="count">The number of rows the returned list should contain.</param>
255 /// <returns>A list of AssetMetadata objects.</returns>
256 public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
257 {
258 List<AssetMetadata> retList = new List<AssetMetadata>(count);
259 string sql = @" SELECT id, name, description, " + "\"assetType\"" + @", temporary, creatorid
260 FROM assets
261 order by id
262 limit :stop
263 offset :start;";
264
265 using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
266 using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
267 {
268 cmd.Parameters.Add(m_database.CreateParameter("start", start));
269 cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
270 conn.Open();
271 using (NpgsqlDataReader reader = cmd.ExecuteReader())
272 {
273 while (reader.Read())
274 {
275 AssetMetadata metadata = new AssetMetadata();
276 metadata.FullID = DBGuid.FromDB(reader["id"]);
277 metadata.Name = (string)reader["name"];
278 metadata.Description = (string)reader["description"];
279 metadata.Type = Convert.ToSByte(reader["assetType"]);
280 metadata.Temporary = Convert.ToBoolean(reader["temporary"]);
281 metadata.CreatorID = (string)reader["creatorid"];
282 retList.Add(metadata);
283 }
284 }
285 }
286
287 return retList;
288 }
289
290 public override bool Delete(string id)
291 {
292 return false;
293 }
294 #endregion
295 }
296}