aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Data.Base/BaseTableMapper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Data.Base/BaseTableMapper.cs')
-rw-r--r--OpenSim/Framework/Data.Base/BaseTableMapper.cs280
1 files changed, 280 insertions, 0 deletions
diff --git a/OpenSim/Framework/Data.Base/BaseTableMapper.cs b/OpenSim/Framework/Data.Base/BaseTableMapper.cs
new file mode 100644
index 0000000..d69fcbb
--- /dev/null
+++ b/OpenSim/Framework/Data.Base/BaseTableMapper.cs
@@ -0,0 +1,280 @@
1/*
2* Copyright (c) Tribal Media AB, http://tribalmedia.se/
3*
4* Redistribution and use in source and binary forms, with or without
5* modification, are permitted provided that the following conditions are met:
6* * Redistributions of source code must retain the above copyright
7* notice, this list of conditions and the following disclaimer.
8* * Redistributions in binary form must reproduce the above copyright
9* notice, this list of conditions and the following disclaimer in the
10* documentation and/or other materials provided with the distribution.
11* * The name of Tribal Media AB may not be used to endorse or promote products
12* derived from this software without specific prior written permission.
13*
14* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
15* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
18* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*
25*/
26
27using System;
28using System.Data;
29using System.Data.Common;
30using TribalMedia.Framework.Data;
31
32namespace TribalMedia.Framework.Data
33{
34 public abstract class BaseTableMapper
35 {
36 private readonly BaseDatabaseConnector m_database;
37 private readonly object m_syncRoot = new object();
38
39 protected void WithConnection(Action<DbConnection> action)
40 {
41 lock (m_syncRoot)
42 {
43 DbConnection m_connection = m_database.GetNewConnection();
44
45 if (m_connection.State != ConnectionState.Open)
46 {
47 m_connection.Open();
48 }
49
50 action(m_connection);
51
52 if (m_connection.State == ConnectionState.Open)
53 {
54 m_connection.Close();
55 }
56 }
57 }
58
59 private readonly string m_tableName;
60 public string TableName
61 {
62 get { return m_tableName; }
63 }
64
65 protected BaseSchema m_schema;
66 public BaseSchema Schema
67 {
68 get { return m_schema; }
69 }
70
71 protected BaseFieldMapper m_keyFieldMapper;
72 public BaseFieldMapper KeyFieldMapper
73 {
74 get { return m_keyFieldMapper; }
75 }
76
77 public BaseTableMapper(BaseDatabaseConnector database, string tableName)
78 {
79 m_database = database;
80 m_tableName = tableName.ToLower(); // Stupid MySQL hack.
81 }
82
83 public string CreateParamName(string fieldName)
84 {
85 return m_database.CreateParamName(fieldName);
86 }
87
88 protected DbCommand CreateSelectCommand(DbConnection connection, string fieldName, object primaryKey)
89 {
90 return m_database.CreateSelectCommand(this, connection, fieldName, primaryKey);
91 }
92
93 public string CreateCondition(DbCommand command, string fieldName, object key)
94 {
95 return m_database.CreateCondition(this, command, fieldName, key);
96 }
97
98 public DbCommand CreateInsertCommand(DbConnection connection, object obj)
99 {
100 return m_database.CreateInsertCommand(this, connection, obj);
101 }
102
103 public DbCommand CreateUpdateCommand(DbConnection connection, object rowMapper, object primaryKey)
104 {
105 return m_database.CreateUpdateCommand(this, connection, rowMapper, primaryKey);
106 }
107
108 public object ConvertToDbType(object value)
109 {
110 return m_database.ConvertToDbType(value);
111 }
112
113 protected virtual BaseDataReader CreateReader(IDataReader reader)
114 {
115 return m_database.CreateReader(reader);
116 }
117 }
118
119 public abstract class BaseTableMapper<TRowMapper, TPrimaryKey> : BaseTableMapper
120 {
121 public BaseTableMapper(BaseDatabaseConnector database, string tableName)
122 : base(database, tableName)
123 {
124 }
125
126 // HACK: This is a temporary function used by TryGetValue().
127 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
128 // a using() block. This has been fixed in SVN, so the next
129 // mono release should work.
130 private void TryGetConnectionValue(DbConnection connection, TPrimaryKey primaryKey, ref TRowMapper result, ref bool success)
131 {
132 using (
133 DbCommand command =
134 CreateSelectCommand(connection, KeyFieldMapper.FieldName, primaryKey))
135 {
136 using (IDataReader reader = command.ExecuteReader())
137 {
138 if (reader.Read())
139 {
140 result = FromReader( CreateReader(reader));
141 success = true;
142 }
143 else
144 {
145 success = false;
146 }
147 }
148 }
149 }
150
151 public bool TryGetValue(TPrimaryKey primaryKey, out TRowMapper value)
152 {
153 TRowMapper result = default(TRowMapper);
154 bool success = false;
155
156 WithConnection(delegate(DbConnection connection)
157 {
158 TryGetConnectionValue(connection, primaryKey, ref result, ref success);
159 });
160
161 value = result;
162
163 return success;
164 }
165
166 // HACK: This is a temporary function used by Remove().
167 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
168 // a using() block. This has been fixed in SVN, so the next
169 // mono release should work.
170 protected virtual void TryDelete(DbConnection connection, TPrimaryKey id, ref int deleted)
171 {
172 using (
173 DbCommand command =
174 CreateDeleteCommand(connection, KeyFieldMapper.FieldName, id))
175 {
176 deleted = command.ExecuteNonQuery();
177 }
178 }
179
180 public virtual bool Remove(TPrimaryKey id)
181 {
182 int deleted = 0;
183
184 WithConnection(delegate(DbConnection connection)
185 {
186 TryDelete(connection, id, ref deleted);
187 });
188
189 if (deleted == 1)
190 {
191 return true;
192 }
193 else
194 {
195 return false;
196 }
197 }
198
199 public DbCommand CreateDeleteCommand(DbConnection connection, string fieldName, TPrimaryKey primaryKey)
200 {
201 string table = TableName;
202
203 DbCommand command = connection.CreateCommand();
204
205 string conditionString = CreateCondition(command, fieldName, primaryKey);
206
207 string query =
208 String.Format("delete from {0} where {1}", table, conditionString);
209
210 command.CommandText = query;
211 command.CommandType = CommandType.Text;
212
213 return command;
214 }
215
216 // HACK: This is a temporary function used by Update().
217 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
218 // a using() block. This has been fixed in SVN, so the next
219 // mono release should work.
220 protected void TryUpdate(DbConnection connection, TPrimaryKey primaryKey, TRowMapper value, ref int updated)
221 {
222 using (DbCommand command = CreateUpdateCommand(connection, value, primaryKey))
223 {
224 updated = command.ExecuteNonQuery();
225 }
226 }
227
228 public virtual bool Update(TPrimaryKey primaryKey, TRowMapper value)
229 {
230 int updated = 0;
231
232 WithConnection(delegate(DbConnection connection)
233 {
234 TryUpdate(connection, primaryKey, value, ref updated);
235 });
236
237 if (updated == 1)
238 {
239 return true;
240 }
241 else
242 {
243 return false;
244 }
245 }
246
247 // HACK: This is a temporary function used by Add().
248 // Due to a bug in mono 1.2.6, delegate blocks cannot contain
249 // a using() block. This has been fixed in SVN, so the next
250 // mono release should work.
251 protected void TryAdd(DbConnection connection, TRowMapper value, ref int added)
252 {
253 using (DbCommand command = CreateInsertCommand(connection, value))
254 {
255 added = command.ExecuteNonQuery();
256 }
257 }
258
259 public virtual bool Add(TRowMapper value)
260 {
261 int added = 0;
262
263 WithConnection(delegate(DbConnection connection)
264 {
265 TryAdd(connection, value, ref added);
266 });
267
268 if (added == 1)
269 {
270 return true;
271 }
272 else
273 {
274 return false;
275 }
276 }
277
278 public abstract TRowMapper FromReader(BaseDataReader reader);
279 }
280} \ No newline at end of file