opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 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.Collections.Generic;
30 using System.Data;
31 using System.Reflection;
32 using log4net;
33 #if CSharpSqlite
34 using Community.CsharpSqlite.Sqlite;
35 #else
36 using Mono.Data.Sqlite;
37 #endif
38 using OpenMetaverse;
39 using OpenSim.Framework;
40 using OpenSim.Region.Framework.Interfaces;
41  
42 namespace OpenSim.Data.SQLite
43 {
44 public class SQLiteGenericTableHandler<T> : SQLiteFramework where T: class, new()
45 {
46 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47  
48 protected Dictionary<string, FieldInfo> m_Fields =
49 new Dictionary<string, FieldInfo>();
50  
51 protected List<string> m_ColumnNames = null;
52 protected string m_Realm;
53 protected FieldInfo m_DataField = null;
54  
55 protected static SqliteConnection m_Connection;
56 private static bool m_initialized;
57  
58 protected virtual Assembly Assembly
59 {
60 get { return GetType().Assembly; }
61 }
62  
63 public SQLiteGenericTableHandler(string connectionString,
64 string realm, string storeName) : base(connectionString)
65 {
66 m_Realm = realm;
67  
68 if (!m_initialized)
69 {
70 m_Connection = new SqliteConnection(connectionString);
71 //Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString));
72 m_Connection.Open();
73  
74 if (storeName != String.Empty)
75 {
76 //SqliteConnection newConnection =
77 // (SqliteConnection)((ICloneable)m_Connection).Clone();
78 //newConnection.Open();
79  
80 //Migration m = new Migration(newConnection, Assembly, storeName);
81 Migration m = new Migration(m_Connection, Assembly, storeName);
82 m.Update();
83 //newConnection.Close();
84 //newConnection.Dispose();
85 }
86  
87 m_initialized = true;
88 }
89  
90 Type t = typeof(T);
91 FieldInfo[] fields = t.GetFields(BindingFlags.Public |
92 BindingFlags.Instance |
93 BindingFlags.DeclaredOnly);
94  
95 if (fields.Length == 0)
96 return;
97  
98 foreach (FieldInfo f in fields)
99 {
100 if (f.Name != "Data")
101 m_Fields[f.Name] = f;
102 else
103 m_DataField = f;
104 }
105 }
106  
107 private void CheckColumnNames(IDataReader reader)
108 {
109 if (m_ColumnNames != null)
110 return;
111  
112 m_ColumnNames = new List<string>();
113  
114 DataTable schemaTable = reader.GetSchemaTable();
115 foreach (DataRow row in schemaTable.Rows)
116 {
117 if (row["ColumnName"] != null &&
118 (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
119 m_ColumnNames.Add(row["ColumnName"].ToString());
120 }
121 }
122  
123 public virtual T[] Get(string field, string key)
124 {
125 return Get(new string[] { field }, new string[] { key });
126 }
127  
128 public virtual T[] Get(string[] fields, string[] keys)
129 {
130 if (fields.Length != keys.Length)
131 return new T[0];
132  
133 List<string> terms = new List<string>();
134  
135 using (SqliteCommand cmd = new SqliteCommand())
136 {
137 for (int i = 0 ; i < fields.Length ; i++)
138 {
139 cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
140 terms.Add("`" + fields[i] + "` = :" + fields[i]);
141 }
142  
143 string where = String.Join(" and ", terms.ToArray());
144  
145 string query = String.Format("select * from {0} where {1}",
146 m_Realm, where);
147  
148 cmd.CommandText = query;
149  
150 return DoQuery(cmd);
151 }
152 }
153  
154 protected T[] DoQuery(SqliteCommand cmd)
155 {
156 IDataReader reader = ExecuteReader(cmd, m_Connection);
157 if (reader == null)
158 return new T[0];
159  
160 CheckColumnNames(reader);
161  
162 List<T> result = new List<T>();
163  
164 while (reader.Read())
165 {
166 T row = new T();
167  
168 foreach (string name in m_Fields.Keys)
169 {
170 if (m_Fields[name].GetValue(row) is bool)
171 {
172 int v = Convert.ToInt32(reader[name]);
173 m_Fields[name].SetValue(row, v != 0 ? true : false);
174 }
175 else if (m_Fields[name].GetValue(row) is UUID)
176 {
177 UUID uuid = UUID.Zero;
178  
179 UUID.TryParse(reader[name].ToString(), out uuid);
180 m_Fields[name].SetValue(row, uuid);
181 }
182 else if (m_Fields[name].GetValue(row) is int)
183 {
184 int v = Convert.ToInt32(reader[name]);
185 m_Fields[name].SetValue(row, v);
186 }
187 else
188 {
189 m_Fields[name].SetValue(row, reader[name]);
190 }
191 }
192  
193 if (m_DataField != null)
194 {
195 Dictionary<string, string> data =
196 new Dictionary<string, string>();
197  
198 foreach (string col in m_ColumnNames)
199 {
200 data[col] = reader[col].ToString();
201 if (data[col] == null)
202 data[col] = String.Empty;
203 }
204  
205 m_DataField.SetValue(row, data);
206 }
207  
208 result.Add(row);
209 }
210  
211 //CloseCommand(cmd);
212  
213 return result.ToArray();
214 }
215  
216 public virtual T[] Get(string where)
217 {
218 using (SqliteCommand cmd = new SqliteCommand())
219 {
220 string query = String.Format("select * from {0} where {1}",
221 m_Realm, where);
222  
223 cmd.CommandText = query;
224  
225 return DoQuery(cmd);
226 }
227 }
228  
229 public virtual bool Store(T row)
230 {
231 using (SqliteCommand cmd = new SqliteCommand())
232 {
233 string query = "";
234 List<String> names = new List<String>();
235 List<String> values = new List<String>();
236  
237 foreach (FieldInfo fi in m_Fields.Values)
238 {
239 names.Add(fi.Name);
240 values.Add(":" + fi.Name);
241 cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
242 }
243  
244 if (m_DataField != null)
245 {
246 Dictionary<string, string> data =
247 (Dictionary<string, string>)m_DataField.GetValue(row);
248  
249 foreach (KeyValuePair<string, string> kvp in data)
250 {
251 names.Add(kvp.Key);
252 values.Add(":" + kvp.Key);
253 cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
254 }
255 }
256  
257 query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
258  
259 cmd.CommandText = query;
260  
261 if (ExecuteNonQuery(cmd, m_Connection) > 0)
262 return true;
263 }
264  
265 return false;
266 }
267  
268 public virtual bool Delete(string field, string key)
269 {
270 return Delete(new string[] { field }, new string[] { key });
271 }
272  
273 public virtual bool Delete(string[] fields, string[] keys)
274 {
275 if (fields.Length != keys.Length)
276 return false;
277  
278 List<string> terms = new List<string>();
279  
280 using (SqliteCommand cmd = new SqliteCommand())
281 {
282 for (int i = 0 ; i < fields.Length ; i++)
283 {
284 cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
285 terms.Add("`" + fields[i] + "` = :" + fields[i]);
286 }
287  
288 string where = String.Join(" and ", terms.ToArray());
289  
290 string query = String.Format("delete from {0} where {1}", m_Realm, where);
291  
292 cmd.CommandText = query;
293  
294 return ExecuteNonQuery(cmd, m_Connection) > 0;
295 }
296 }
297 }
298 }