aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Data/Base/BaseTableMapper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Data/Base/BaseTableMapper.cs')
-rw-r--r--OpenSim/Data/Base/BaseTableMapper.cs281
1 files changed, 281 insertions, 0 deletions
diff --git a/OpenSim/Data/Base/BaseTableMapper.cs b/OpenSim/Data/Base/BaseTableMapper.cs
new file mode 100644
index 0000000..cad4823
--- /dev/null
+++ b/OpenSim/Data/Base/BaseTableMapper.cs
@@ -0,0 +1,281 @@
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 OpenSim 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.Data.Common;
31using OpenSim.Framework.Data.Base;
32
33namespace OpenSim.Framework.Data.Base
34{
35 public abstract class BaseTableMapper
36 {
37 private readonly BaseDatabaseConnector m_database;
38 private readonly object m_syncRoot = new object();
39
40 protected void WithConnection(Action<DbConnection> action)
41 {
42 lock (m_syncRoot)
43 {
44 DbConnection m_connection = m_database.GetNewConnection();
45
46 if (m_connection.State != ConnectionState.Open)
47 {
48 m_connection.Open();
49 }
50
51 action(m_connection);
52
53 if (m_connection.State == ConnectionState.Open)
54 {
55 m_connection.Close();
56 }
57 }
58 }
59
60 private readonly string m_tableName;
61 public string TableName
62 {
63 get { return m_tableName; }
64 }
65
66 protected BaseSchema m_schema;
67 public BaseSchema Schema
68 {
69 get { return m_schema; }
70 }
71
72 protected BaseFieldMapper m_keyFieldMapper;
73 public BaseFieldMapper KeyFieldMapper
74 {
75 get { return m_keyFieldMapper; }
76 }
77
78 public BaseTableMapper(BaseDatabaseConnector database, string tableName)
79 {
80 m_database = database;
81 m_tableName = tableName.ToLower(); // Stupid MySQL hack.
82 }
83
84 public string CreateParamName(string fieldName)
85 {
86 return m_database.CreateParamName(fieldName);
87 }
88
89 protected DbCommand CreateSelectCommand(DbConnection connection, string fieldName, object primaryKey)
90 {
91 return m_database.CreateSelectCommand(this, connection, fieldName, primaryKey);
92 }
93
94 public string CreateCondition(DbCommand command, string fieldName, object key)
95 {
96 return m_database.CreateCondition(this, command, fieldName, key);
97 }
98
99 public DbCommand CreateInsertCommand(DbConnection connection, object obj)
100 {
101 return m_database.CreateInsertCommand(this, connection, obj);
102 }
103
104 public DbCommand CreateUpdateCommand(DbConnection connection, object rowMapper, object primaryKey)
105 {
106 return m_database.CreateUpdateCommand(this, connection, rowMapper, primaryKey);
107 }
108
109 public object ConvertToDbType(object value)
110 {
111 return m_database.ConvertToDbType(value);
112 }
113
114 protected virtual BaseDataReader CreateReader(IDataReader reader)
115 {
116 return m_database.CreateReader(reader);
117 }
118 }
119
120 public abstract class BaseTableMapper<TRowMapper, TPrimaryKey> : BaseTableMapper
121 {
122 public BaseTableMapper(BaseDatabaseConnector database, string tableName)
123 : base(database, tableName)
124 {
125 }
126
127 // HACK: This is a temporary function used by TryGetValue().
128 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
129 // a using() block. This has been fixed in SVN, so the next
130 // mono release should work.
131 private void TryGetConnectionValue(DbConnection connection, TPrimaryKey primaryKey, ref TRowMapper result, ref bool success)
132 {
133 using (
134 DbCommand command =
135 CreateSelectCommand(connection, KeyFieldMapper.FieldName, primaryKey))
136 {
137 using (IDataReader reader = command.ExecuteReader())
138 {
139 if (reader.Read())
140 {
141 result = FromReader( CreateReader(reader));
142 success = true;
143 }
144 else
145 {
146 success = false;
147 }
148 }
149 }
150 }
151
152 public bool TryGetValue(TPrimaryKey primaryKey, out TRowMapper value)
153 {
154 TRowMapper result = default(TRowMapper);
155 bool success = false;
156
157 WithConnection(delegate(DbConnection connection)
158 {
159 TryGetConnectionValue(connection, primaryKey, ref result, ref success);
160 });
161
162 value = result;
163
164 return success;
165 }
166
167 // HACK: This is a temporary function used by Remove().
168 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
169 // a using() block. This has been fixed in SVN, so the next
170 // mono release should work.
171 protected virtual void TryDelete(DbConnection connection, TPrimaryKey id, ref int deleted)
172 {
173 using (
174 DbCommand command =
175 CreateDeleteCommand(connection, KeyFieldMapper.FieldName, id))
176 {
177 deleted = command.ExecuteNonQuery();
178 }
179 }
180
181 public virtual bool Remove(TPrimaryKey id)
182 {
183 int deleted = 0;
184
185 WithConnection(delegate(DbConnection connection)
186 {
187 TryDelete(connection, id, ref deleted);
188 });
189
190 if (deleted == 1)
191 {
192 return true;
193 }
194 else
195 {
196 return false;
197 }
198 }
199
200 public DbCommand CreateDeleteCommand(DbConnection connection, string fieldName, TPrimaryKey primaryKey)
201 {
202 string table = TableName;
203
204 DbCommand command = connection.CreateCommand();
205
206 string conditionString = CreateCondition(command, fieldName, primaryKey);
207
208 string query =
209 String.Format("delete from {0} where {1}", table, conditionString);
210
211 command.CommandText = query;
212 command.CommandType = CommandType.Text;
213
214 return command;
215 }
216
217 // HACK: This is a temporary function used by Update().
218 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
219 // a using() block. This has been fixed in SVN, so the next
220 // mono release should work.
221 protected void TryUpdate(DbConnection connection, TPrimaryKey primaryKey, TRowMapper value, ref int updated)
222 {
223 using (DbCommand command = CreateUpdateCommand(connection, value, primaryKey))
224 {
225 updated = command.ExecuteNonQuery();
226 }
227 }
228
229 public virtual bool Update(TPrimaryKey primaryKey, TRowMapper value)
230 {
231 int updated = 0;
232
233 WithConnection(delegate(DbConnection connection)
234 {
235 TryUpdate(connection, primaryKey, value, ref updated);
236 });
237
238 if (updated == 1)
239 {
240 return true;
241 }
242 else
243 {
244 return false;
245 }
246 }
247
248 // HACK: This is a temporary function used by Add().
249 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
250 // a using() block. This has been fixed in SVN, so the next
251 // mono release should work.
252 protected void TryAdd(DbConnection connection, TRowMapper value, ref int added)
253 {
254 using (DbCommand command = CreateInsertCommand(connection, value))
255 {
256 added = command.ExecuteNonQuery();
257 }
258 }
259
260 public virtual bool Add(TRowMapper value)
261 {
262 int added = 0;
263
264 WithConnection(delegate(DbConnection connection)
265 {
266 TryAdd(connection, value, ref added);
267 });
268
269 if (added == 1)
270 {
271 return true;
272 }
273 else
274 {
275 return false;
276 }
277 }
278
279 public abstract TRowMapper FromReader(BaseDataReader reader);
280 }
281}