aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs (renamed from OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs)253
1 files changed, 203 insertions, 50 deletions
diff --git a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs
index 4145d95..826c6fc 100644
--- a/OpenSim/Data/MSSQL/MSSQLGenericTableHandler.cs
+++ b/OpenSim/Data/PGSQL/PGSQLGenericTableHandler.cs
@@ -30,30 +30,38 @@ using System.Collections.Generic;
30using System.Data; 30using System.Data;
31using System.Reflection; 31using System.Reflection;
32using log4net; 32using log4net;
33using System.Data.SqlClient;
34using OpenMetaverse; 33using OpenMetaverse;
35using OpenSim.Framework; 34using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces; 35using OpenSim.Region.Framework.Interfaces;
37using System.Text; 36using System.Text;
37using Npgsql;
38 38
39namespace OpenSim.Data.MSSQL 39namespace OpenSim.Data.PGSQL
40{ 40{
41 public class MSSQLGenericTableHandler<T> where T : class, new() 41 public class PGSQLGenericTableHandler<T> : PGSqlFramework where T : class, new()
42 { 42 {
43// private static readonly ILog m_log = 43 private static readonly ILog m_log =
44// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 protected string m_ConnectionString; 46 protected string m_ConnectionString;
47 protected MSSQLManager m_database; //used for parameter type translation 47 protected PGSQLManager m_database; //used for parameter type translation
48 protected Dictionary<string, FieldInfo> m_Fields = 48 protected Dictionary<string, FieldInfo> m_Fields =
49 new Dictionary<string, FieldInfo>(); 49 new Dictionary<string, FieldInfo>();
50 50
51 protected Dictionary<string, string> m_FieldTypes = new Dictionary<string, string>();
52
51 protected List<string> m_ColumnNames = null; 53 protected List<string> m_ColumnNames = null;
52 protected string m_Realm; 54 protected string m_Realm;
53 protected FieldInfo m_DataField = null; 55 protected FieldInfo m_DataField = null;
54 56
55 public MSSQLGenericTableHandler(string connectionString, 57 protected virtual Assembly Assembly
58 {
59 get { return GetType().Assembly; }
60 }
61
62 public PGSQLGenericTableHandler(string connectionString,
56 string realm, string storeName) 63 string realm, string storeName)
64 : base(connectionString)
57 { 65 {
58 m_Realm = realm; 66 m_Realm = realm;
59 67
@@ -61,7 +69,7 @@ namespace OpenSim.Data.MSSQL
61 69
62 if (storeName != String.Empty) 70 if (storeName != String.Empty)
63 { 71 {
64 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 72 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
65 { 73 {
66 conn.Open(); 74 conn.Open();
67 Migration m = new Migration(conn, GetType().Assembly, storeName); 75 Migration m = new Migration(conn, GetType().Assembly, storeName);
@@ -69,13 +77,15 @@ namespace OpenSim.Data.MSSQL
69 } 77 }
70 78
71 } 79 }
72 m_database = new MSSQLManager(m_ConnectionString); 80 m_database = new PGSQLManager(m_ConnectionString);
73 81
74 Type t = typeof(T); 82 Type t = typeof(T);
75 FieldInfo[] fields = t.GetFields(BindingFlags.Public | 83 FieldInfo[] fields = t.GetFields(BindingFlags.Public |
76 BindingFlags.Instance | 84 BindingFlags.Instance |
77 BindingFlags.DeclaredOnly); 85 BindingFlags.DeclaredOnly);
78 86
87 LoadFieldTypes();
88
79 if (fields.Length == 0) 89 if (fields.Length == 0)
80 return; 90 return;
81 91
@@ -89,7 +99,31 @@ namespace OpenSim.Data.MSSQL
89 99
90 } 100 }
91 101
92 private void CheckColumnNames(SqlDataReader reader) 102 private void LoadFieldTypes()
103 {
104 m_FieldTypes = new Dictionary<string, string>();
105
106 string query = string.Format(@"select column_name,data_type
107 from INFORMATION_SCHEMA.COLUMNS
108 where table_name = lower('{0}');
109
110 ", m_Realm);
111 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
112 using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
113 {
114 conn.Open();
115 using (NpgsqlDataReader rdr = cmd.ExecuteReader())
116 {
117 while (rdr.Read())
118 {
119 // query produces 0 to many rows of single column, so always add the first item in each row
120 m_FieldTypes.Add((string)rdr[0], (string)rdr[1]);
121 }
122 }
123 }
124 }
125
126 private void CheckColumnNames(NpgsqlDataReader reader)
93 { 127 {
94 if (m_ColumnNames != null) 128 if (m_ColumnNames != null)
95 return; 129 return;
@@ -97,6 +131,7 @@ namespace OpenSim.Data.MSSQL
97 m_ColumnNames = new List<string>(); 131 m_ColumnNames = new List<string>();
98 132
99 DataTable schemaTable = reader.GetSchemaTable(); 133 DataTable schemaTable = reader.GetSchemaTable();
134
100 foreach (DataRow row in schemaTable.Rows) 135 foreach (DataRow row in schemaTable.Rows)
101 { 136 {
102 if (row["ColumnName"] != null && 137 if (row["ColumnName"] != null &&
@@ -106,21 +141,37 @@ namespace OpenSim.Data.MSSQL
106 } 141 }
107 } 142 }
108 143
144 // TODO GET CONSTRAINTS FROM POSTGRESQL
109 private List<string> GetConstraints() 145 private List<string> GetConstraints()
110 { 146 {
111 List<string> constraints = new List<string>(); 147 List<string> constraints = new List<string>();
112 string query = string.Format(@"SELECT 148 string query = string.Format(@"SELECT kcu.column_name
113 COL_NAME(ic.object_id,ic.column_id) AS column_name 149 FROM information_schema.table_constraints tc
114 FROM sys.indexes AS i 150 LEFT JOIN information_schema.key_column_usage kcu
115 INNER JOIN sys.index_columns AS ic 151 ON tc.constraint_catalog = kcu.constraint_catalog
116 ON i.object_id = ic.object_id AND i.index_id = ic.index_id 152 AND tc.constraint_schema = kcu.constraint_schema
117 WHERE i.is_primary_key = 1 153 AND tc.constraint_name = kcu.constraint_name
118 AND i.object_id = OBJECT_ID('{0}');", m_Realm); 154
119 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 155 LEFT JOIN information_schema.referential_constraints rc
120 using (SqlCommand cmd = new SqlCommand(query, conn)) 156 ON tc.constraint_catalog = rc.constraint_catalog
157 AND tc.constraint_schema = rc.constraint_schema
158 AND tc.constraint_name = rc.constraint_name
159
160 LEFT JOIN information_schema.constraint_column_usage ccu
161 ON rc.unique_constraint_catalog = ccu.constraint_catalog
162 AND rc.unique_constraint_schema = ccu.constraint_schema
163 AND rc.unique_constraint_name = ccu.constraint_name
164
165 where tc.table_name = lower('{0}')
166 and lower(tc.constraint_type) in ('primary key')
167 and kcu.column_name is not null
168 ;", m_Realm);
169
170 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
171 using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
121 { 172 {
122 conn.Open(); 173 conn.Open();
123 using (SqlDataReader rdr = cmd.ExecuteReader()) 174 using (NpgsqlDataReader rdr = cmd.ExecuteReader())
124 { 175 {
125 while (rdr.Read()) 176 while (rdr.Read())
126 { 177 {
@@ -144,14 +195,18 @@ namespace OpenSim.Data.MSSQL
144 195
145 List<string> terms = new List<string>(); 196 List<string> terms = new List<string>();
146 197
147 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 198 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
148 using (SqlCommand cmd = new SqlCommand()) 199 using (NpgsqlCommand cmd = new NpgsqlCommand())
149 { 200 {
150 201
151 for (int i = 0; i < fields.Length; i++) 202 for (int i = 0; i < fields.Length; i++)
152 { 203 {
153 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i])); 204 if ( m_FieldTypes.ContainsKey(fields[i]) )
154 terms.Add("[" + fields[i] + "] = @" + fields[i]); 205 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
206 else
207 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
208
209 terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
155 } 210 }
156 211
157 string where = String.Join(" AND ", terms.ToArray()); 212 string where = String.Join(" AND ", terms.ToArray());
@@ -166,10 +221,18 @@ namespace OpenSim.Data.MSSQL
166 } 221 }
167 } 222 }
168 223
169 protected T[] DoQuery(SqlCommand cmd) 224 protected T[] DoQuery(NpgsqlCommand cmd)
170 { 225 {
171 List<T> result = new List<T>(); 226 List<T> result = new List<T>();
172 using (SqlDataReader reader = cmd.ExecuteReader()) 227 if (cmd.Connection == null)
228 {
229 cmd.Connection = new NpgsqlConnection(m_connectionString);
230 }
231 if (cmd.Connection.State == ConnectionState.Closed)
232 {
233 cmd.Connection.Open();
234 }
235 using (NpgsqlDataReader reader = cmd.ExecuteReader())
173 { 236 {
174 if (reader == null) 237 if (reader == null)
175 return new T[0]; 238 return new T[0];
@@ -213,6 +276,7 @@ namespace OpenSim.Data.MSSQL
213 foreach (string col in m_ColumnNames) 276 foreach (string col in m_ColumnNames)
214 { 277 {
215 data[col] = reader[col].ToString(); 278 data[col] = reader[col].ToString();
279
216 if (data[col] == null) 280 if (data[col] == null)
217 data[col] = String.Empty; 281 data[col] = String.Empty;
218 } 282 }
@@ -228,16 +292,34 @@ namespace OpenSim.Data.MSSQL
228 292
229 public virtual T[] Get(string where) 293 public virtual T[] Get(string where)
230 { 294 {
231 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 295 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
232 using (SqlCommand cmd = new SqlCommand()) 296 using (NpgsqlCommand cmd = new NpgsqlCommand())
233 { 297 {
234 298
235 string query = String.Format("SELECT * FROM {0} WHERE {1}", 299 string query = String.Format("SELECT * FROM {0} WHERE {1}",
236 m_Realm, where); 300 m_Realm, where);
237 cmd.Connection = conn; 301 cmd.Connection = conn;
238 cmd.CommandText = query; 302 cmd.CommandText = query;
303 //m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
239 304
240 //m_log.WarnFormat("[MSSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where); 305 conn.Open();
306 return DoQuery(cmd);
307 }
308 }
309
310 public virtual T[] Get(string where, NpgsqlParameter parameter)
311 {
312 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
313 using (NpgsqlCommand cmd = new NpgsqlCommand())
314 {
315
316 string query = String.Format("SELECT * FROM {0} WHERE {1}",
317 m_Realm, where);
318 cmd.Connection = conn;
319 cmd.CommandText = query;
320 //m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
321
322 cmd.Parameters.Add(parameter);
241 323
242 conn.Open(); 324 conn.Open();
243 return DoQuery(cmd); 325 return DoQuery(cmd);
@@ -249,8 +331,8 @@ namespace OpenSim.Data.MSSQL
249 List<string> constraintFields = GetConstraints(); 331 List<string> constraintFields = GetConstraints();
250 List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>(); 332 List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
251 333
252 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 334 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
253 using (SqlCommand cmd = new SqlCommand()) 335 using (NpgsqlCommand cmd = new NpgsqlCommand())
254 { 336 {
255 337
256 StringBuilder query = new StringBuilder(); 338 StringBuilder query = new StringBuilder();
@@ -260,21 +342,24 @@ namespace OpenSim.Data.MSSQL
260 foreach (FieldInfo fi in m_Fields.Values) 342 foreach (FieldInfo fi in m_Fields.Values)
261 { 343 {
262 names.Add(fi.Name); 344 names.Add(fi.Name);
263 values.Add("@" + fi.Name); 345 values.Add(":" + fi.Name);
264 // Temporarily return more information about what field is unexpectedly null for 346 // Temporarily return more information about what field is unexpectedly null for
265 // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the 347 // http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
266 // InventoryTransferModule or we may be required to substitute a DBNull here. 348 // InventoryTransferModule or we may be required to substitute a DBNull here.
267 if (fi.GetValue(row) == null) 349 if (fi.GetValue(row) == null)
268 throw new NullReferenceException( 350 throw new NullReferenceException(
269 string.Format( 351 string.Format(
270 "[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null", 352 "[PGSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
271 fi.Name, row)); 353 fi.Name, row));
272 354
273 if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name)) 355 if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
274 { 356 {
275 constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString())); 357 constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString() ));
276 } 358 }
277 cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row).ToString())); 359 if (m_FieldTypes.ContainsKey(fi.Name))
360 cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row), m_FieldTypes[fi.Name]));
361 else
362 cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row)));
278 } 363 }
279 364
280 if (m_DataField != null) 365 if (m_DataField != null)
@@ -289,8 +374,12 @@ namespace OpenSim.Data.MSSQL
289 constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key)); 374 constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
290 } 375 }
291 names.Add(kvp.Key); 376 names.Add(kvp.Key);
292 values.Add("@" + kvp.Key); 377 values.Add(":" + kvp.Key);
293 cmd.Parameters.Add(m_database.CreateParameter("@" + kvp.Key, kvp.Value)); 378
379 if (m_FieldTypes.ContainsKey(kvp.Key))
380 cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value, m_FieldTypes[kvp.Key]));
381 else
382 cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value));
294 } 383 }
295 384
296 } 385 }
@@ -299,15 +388,15 @@ namespace OpenSim.Data.MSSQL
299 int i = 0; 388 int i = 0;
300 for (i = 0; i < names.Count - 1; i++) 389 for (i = 0; i < names.Count - 1; i++)
301 { 390 {
302 query.AppendFormat("[{0}] = {1}, ", names[i], values[i]); 391 query.AppendFormat("\"{0}\" = {1}, ", names[i], values[i]);
303 } 392 }
304 query.AppendFormat("[{0}] = {1} ", names[i], values[i]); 393 query.AppendFormat("\"{0}\" = {1} ", names[i], values[i]);
305 if (constraints.Count > 0) 394 if (constraints.Count > 0)
306 { 395 {
307 List<string> terms = new List<string>(); 396 List<string> terms = new List<string>();
308 for (int j = 0; j < constraints.Count; j++) 397 for (int j = 0; j < constraints.Count; j++)
309 { 398 {
310 terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key); 399 terms.Add(String.Format(" \"{0}\" = :{0}", constraints[j].Key));
311 } 400 }
312 string where = String.Join(" AND ", terms.ToArray()); 401 string where = String.Join(" AND ", terms.ToArray());
313 query.AppendFormat(" WHERE {0} ", where); 402 query.AppendFormat(" WHERE {0} ", where);
@@ -319,7 +408,7 @@ namespace OpenSim.Data.MSSQL
319 conn.Open(); 408 conn.Open();
320 if (cmd.ExecuteNonQuery() > 0) 409 if (cmd.ExecuteNonQuery() > 0)
321 { 410 {
322 //m_log.WarnFormat("[MSSQLGenericTable]: Updating {0}", m_Realm); 411 //m_log.WarnFormat("[PGSQLGenericTable]: Updating {0}", m_Realm);
323 return true; 412 return true;
324 } 413 }
325 else 414 else
@@ -327,12 +416,14 @@ namespace OpenSim.Data.MSSQL
327 // assume record has not yet been inserted 416 // assume record has not yet been inserted
328 417
329 query = new StringBuilder(); 418 query = new StringBuilder();
330 query.AppendFormat("INSERT INTO {0} ([", m_Realm); 419 query.AppendFormat("INSERT INTO {0} (\"", m_Realm);
331 query.Append(String.Join("],[", names.ToArray())); 420 query.Append(String.Join("\",\"", names.ToArray()));
332 query.Append("]) values (" + String.Join(",", values.ToArray()) + ")"); 421 query.Append("\") values (" + String.Join(",", values.ToArray()) + ")");
333 cmd.Connection = conn; 422 cmd.Connection = conn;
334 cmd.CommandText = query.ToString(); 423 cmd.CommandText = query.ToString();
335 //m_log.WarnFormat("[MSSQLGenericTable]: Inserting into {0}", m_Realm); 424
425 // m_log.WarnFormat("[PGSQLGenericTable]: Inserting into {0} sql {1}", m_Realm, cmd.CommandText);
426
336 if (conn.State != ConnectionState.Open) 427 if (conn.State != ConnectionState.Open)
337 conn.Open(); 428 conn.Open();
338 if (cmd.ExecuteNonQuery() > 0) 429 if (cmd.ExecuteNonQuery() > 0)
@@ -355,13 +446,17 @@ namespace OpenSim.Data.MSSQL
355 446
356 List<string> terms = new List<string>(); 447 List<string> terms = new List<string>();
357 448
358 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 449 using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
359 using (SqlCommand cmd = new SqlCommand()) 450 using (NpgsqlCommand cmd = new NpgsqlCommand())
360 { 451 {
361 for (int i = 0; i < fields.Length; i++) 452 for (int i = 0; i < fields.Length; i++)
362 { 453 {
363 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i])); 454 if (m_FieldTypes.ContainsKey(fields[i]))
364 terms.Add("[" + fields[i] + "] = @" + fields[i]); 455 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
456 else
457 cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
458
459 terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
365 } 460 }
366 461
367 string where = String.Join(" AND ", terms.ToArray()); 462 string where = String.Join(" AND ", terms.ToArray());
@@ -374,11 +469,69 @@ namespace OpenSim.Data.MSSQL
374 469
375 if (cmd.ExecuteNonQuery() > 0) 470 if (cmd.ExecuteNonQuery() > 0)
376 { 471 {
377 //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand); 472 //m_log.Warn("[PGSQLGenericTable]: " + deleteCommand);
378 return true; 473 return true;
379 } 474 }
380 return false; 475 return false;
381 } 476 }
382 } 477 }
478 public long GetCount(string field, string key)
479 {
480 return GetCount(new string[] { field }, new string[] { key });
481 }
482
483 public long GetCount(string[] fields, string[] keys)
484 {
485 if (fields.Length != keys.Length)
486 return 0;
487
488 List<string> terms = new List<string>();
489
490 using (NpgsqlCommand cmd = new NpgsqlCommand())
491 {
492 for (int i = 0; i < fields.Length; i++)
493 {
494 cmd.Parameters.AddWithValue(fields[i], keys[i]);
495 terms.Add("\"" + fields[i] + "\" = :" + fields[i]);
496 }
497
498 string where = String.Join(" and ", terms.ToArray());
499
500 string query = String.Format("select count(*) from {0} where {1}",
501 m_Realm, where);
502
503 cmd.CommandText = query;
504
505 Object result = DoQueryScalar(cmd);
506
507 return Convert.ToInt64(result);
508 }
509 }
510
511 public long GetCount(string where)
512 {
513 using (NpgsqlCommand cmd = new NpgsqlCommand())
514 {
515 string query = String.Format("select count(*) from {0} where {1}",
516 m_Realm, where);
517
518 cmd.CommandText = query;
519
520 object result = DoQueryScalar(cmd);
521
522 return Convert.ToInt64(result);
523 }
524 }
525
526 public object DoQueryScalar(NpgsqlCommand cmd)
527 {
528 using (NpgsqlConnection dbcon = new NpgsqlConnection(m_ConnectionString))
529 {
530 dbcon.Open();
531 cmd.Connection = dbcon;
532
533 return cmd.ExecuteScalar();
534 }
535 }
383 } 536 }
384} 537}