diff options
Diffstat (limited to '')
20 files changed, 600 insertions, 1908 deletions
diff --git a/OpenSim/Data/SQLite/Resources/001_AuthStore.sql b/OpenSim/Data/SQLite/Resources/001_AuthStore.sql new file mode 100644 index 0000000..468567d --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/001_AuthStore.sql | |||
@@ -0,0 +1,18 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | CREATE TABLE auth ( | ||
4 | UUID char(36) NOT NULL, | ||
5 | passwordHash char(32) NOT NULL default '', | ||
6 | passwordSalt char(32) NOT NULL default '', | ||
7 | webLoginKey varchar(255) NOT NULL default '', | ||
8 | accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount', | ||
9 | PRIMARY KEY (`UUID`) | ||
10 | ); | ||
11 | |||
12 | CREATE TABLE tokens ( | ||
13 | UUID char(36) NOT NULL, | ||
14 | token varchar(255) NOT NULL, | ||
15 | validity datetime NOT NULL | ||
16 | ); | ||
17 | |||
18 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/001_Avatar.sql b/OpenSim/Data/SQLite/Resources/001_Avatar.sql new file mode 100644 index 0000000..7ec906b --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/001_Avatar.sql | |||
@@ -0,0 +1,9 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | CREATE TABLE Avatars ( | ||
4 | PrincipalID CHAR(36) NOT NULL, | ||
5 | Name VARCHAR(32) NOT NULL, | ||
6 | Value VARCHAR(255) NOT NULL DEFAULT '', | ||
7 | PRIMARY KEY(PrincipalID, Name)); | ||
8 | |||
9 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql new file mode 100644 index 0000000..f1b9ab9 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/001_FriendsStore.sql | |||
@@ -0,0 +1,10 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | CREATE TABLE `Friends` ( | ||
4 | `PrincipalID` CHAR(36) NOT NULL, | ||
5 | `Friend` VARCHAR(255) NOT NULL, | ||
6 | `Flags` VARCHAR(16) NOT NULL DEFAULT 0, | ||
7 | `Offered` VARCHAR(32) NOT NULL DEFAULT 0, | ||
8 | PRIMARY KEY(`PrincipalID`, `Friend`)); | ||
9 | |||
10 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/001_UserAccount.sql b/OpenSim/Data/SQLite/Resources/001_UserAccount.sql new file mode 100644 index 0000000..f9bf24c --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/001_UserAccount.sql | |||
@@ -0,0 +1,17 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | -- useraccounts table | ||
4 | CREATE TABLE UserAccounts ( | ||
5 | PrincipalID CHAR(36) NOT NULL, | ||
6 | ScopeID CHAR(36) NOT NULL, | ||
7 | FirstName VARCHAR(64) NOT NULL, | ||
8 | LastName VARCHAR(64) NOT NULL, | ||
9 | Email VARCHAR(64), | ||
10 | ServiceURLs TEXT, | ||
11 | Created INT(11), | ||
12 | UserLevel integer NOT NULL DEFAULT 0, | ||
13 | UserFlags integer NOT NULL DEFAULT 0, | ||
14 | UserTitle varchar(64) NOT NULL DEFAULT '' | ||
15 | ); | ||
16 | |||
17 | COMMIT; \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/Resources/002_AuthStore.sql b/OpenSim/Data/SQLite/Resources/002_AuthStore.sql new file mode 100644 index 0000000..3237b68 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/002_AuthStore.sql | |||
@@ -0,0 +1,5 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users; | ||
4 | |||
5 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql new file mode 100644 index 0000000..6733502 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/002_FriendsStore.sql | |||
@@ -0,0 +1,5 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`; | ||
4 | |||
5 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/002_UserAccount.sql b/OpenSim/Data/SQLite/Resources/002_UserAccount.sql new file mode 100644 index 0000000..c7a6293 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/002_UserAccount.sql | |||
@@ -0,0 +1,5 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | INSERT INTO UserAccounts (PrincipalID, ScopeID, FirstName, LastName, Email, ServiceURLs, Created) SELECT `UUID` AS PrincipalID, '00000000-0000-0000-0000-000000000000' AS ScopeID, username AS FirstName, surname AS LastName, '' as Email, '' AS ServiceURLs, created as Created FROM users; | ||
4 | |||
5 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index c52f60b..ace40e5 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs | |||
@@ -234,7 +234,8 @@ namespace OpenSim.Data.SQLite | |||
234 | AssetBase asset = new AssetBase( | 234 | AssetBase asset = new AssetBase( |
235 | new UUID((String)row["UUID"]), | 235 | new UUID((String)row["UUID"]), |
236 | (String)row["Name"], | 236 | (String)row["Name"], |
237 | Convert.ToSByte(row["Type"]) | 237 | Convert.ToSByte(row["Type"]), |
238 | UUID.Zero.ToString() | ||
238 | ); | 239 | ); |
239 | 240 | ||
240 | asset.Description = (String) row["Description"]; | 241 | asset.Description = (String) row["Description"]; |
diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs new file mode 100644 index 0000000..84ce775 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs | |||
@@ -0,0 +1,262 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using Mono.Data.SqliteClient; | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData | ||
39 | { | ||
40 | private string m_Realm; | ||
41 | private List<string> m_ColumnNames; | ||
42 | private int m_LastExpire; | ||
43 | private string m_connectionString; | ||
44 | |||
45 | protected static SqliteConnection m_Connection; | ||
46 | private static bool m_initialized = false; | ||
47 | |||
48 | public SQLiteAuthenticationData(string connectionString, string realm) | ||
49 | : base(connectionString) | ||
50 | { | ||
51 | m_Realm = realm; | ||
52 | m_connectionString = connectionString; | ||
53 | |||
54 | if (!m_initialized) | ||
55 | { | ||
56 | m_Connection = new SqliteConnection(connectionString); | ||
57 | m_Connection.Open(); | ||
58 | |||
59 | using (SqliteConnection dbcon = (SqliteConnection)((ICloneable)m_Connection).Clone()) | ||
60 | { | ||
61 | dbcon.Open(); | ||
62 | Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore"); | ||
63 | m.Update(); | ||
64 | dbcon.Close(); | ||
65 | } | ||
66 | |||
67 | m_initialized = true; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | public AuthenticationData Get(UUID principalID) | ||
72 | { | ||
73 | AuthenticationData ret = new AuthenticationData(); | ||
74 | ret.Data = new Dictionary<string, object>(); | ||
75 | |||
76 | SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID"); | ||
77 | cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); | ||
78 | |||
79 | IDataReader result = ExecuteReader(cmd, m_Connection); | ||
80 | |||
81 | try | ||
82 | { | ||
83 | if (result.Read()) | ||
84 | { | ||
85 | ret.PrincipalID = principalID; | ||
86 | |||
87 | if (m_ColumnNames == null) | ||
88 | { | ||
89 | m_ColumnNames = new List<string>(); | ||
90 | |||
91 | DataTable schemaTable = result.GetSchemaTable(); | ||
92 | foreach (DataRow row in schemaTable.Rows) | ||
93 | m_ColumnNames.Add(row["ColumnName"].ToString()); | ||
94 | } | ||
95 | |||
96 | foreach (string s in m_ColumnNames) | ||
97 | { | ||
98 | if (s == "UUID") | ||
99 | continue; | ||
100 | |||
101 | ret.Data[s] = result[s].ToString(); | ||
102 | } | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | else | ||
107 | { | ||
108 | return null; | ||
109 | } | ||
110 | } | ||
111 | catch | ||
112 | { | ||
113 | } | ||
114 | finally | ||
115 | { | ||
116 | CloseCommand(cmd); | ||
117 | } | ||
118 | |||
119 | return null; | ||
120 | } | ||
121 | |||
122 | public bool Store(AuthenticationData data) | ||
123 | { | ||
124 | if (data.Data.ContainsKey("UUID")) | ||
125 | data.Data.Remove("UUID"); | ||
126 | |||
127 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
128 | string[] values = new string[data.Data.Count]; | ||
129 | int i = 0; | ||
130 | foreach (object o in data.Data.Values) | ||
131 | values[i++] = o.ToString(); | ||
132 | |||
133 | SqliteCommand cmd = new SqliteCommand(); | ||
134 | |||
135 | if (Get(data.PrincipalID) != null) | ||
136 | { | ||
137 | |||
138 | |||
139 | string update = "update `" + m_Realm + "` set "; | ||
140 | bool first = true; | ||
141 | foreach (string field in fields) | ||
142 | { | ||
143 | if (!first) | ||
144 | update += ", "; | ||
145 | update += "`" + field + "` = :" + field; | ||
146 | cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); | ||
147 | |||
148 | first = false; | ||
149 | } | ||
150 | |||
151 | update += " where UUID = :UUID"; | ||
152 | cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); | ||
153 | |||
154 | cmd.CommandText = update; | ||
155 | try | ||
156 | { | ||
157 | if (ExecuteNonQuery(cmd, m_Connection) < 1) | ||
158 | { | ||
159 | CloseCommand(cmd); | ||
160 | return false; | ||
161 | } | ||
162 | } | ||
163 | catch (Exception e) | ||
164 | { | ||
165 | Console.WriteLine(e.ToString()); | ||
166 | CloseCommand(cmd); | ||
167 | return false; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | else | ||
172 | { | ||
173 | string insert = "insert into `" + m_Realm + "` (`UUID`, `" + | ||
174 | String.Join("`, `", fields) + | ||
175 | "`) values (:UUID, :" + String.Join(", :", fields) + ")"; | ||
176 | |||
177 | cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); | ||
178 | foreach (string field in fields) | ||
179 | cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); | ||
180 | |||
181 | cmd.CommandText = insert; | ||
182 | |||
183 | try | ||
184 | { | ||
185 | if (ExecuteNonQuery(cmd, m_Connection) < 1) | ||
186 | { | ||
187 | CloseCommand(cmd); | ||
188 | return false; | ||
189 | } | ||
190 | } | ||
191 | catch (Exception e) | ||
192 | { | ||
193 | Console.WriteLine(e.ToString()); | ||
194 | CloseCommand(cmd); | ||
195 | return false; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | CloseCommand(cmd); | ||
200 | |||
201 | return true; | ||
202 | } | ||
203 | |||
204 | public bool SetDataItem(UUID principalID, string item, string value) | ||
205 | { | ||
206 | SqliteCommand cmd = new SqliteCommand("update `" + m_Realm + | ||
207 | "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'"); | ||
208 | |||
209 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
210 | return true; | ||
211 | |||
212 | return false; | ||
213 | } | ||
214 | |||
215 | public bool SetToken(UUID principalID, string token, int lifetime) | ||
216 | { | ||
217 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
218 | DoExpire(); | ||
219 | |||
220 | SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + | ||
221 | "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))"); | ||
222 | |||
223 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
224 | { | ||
225 | cmd.Dispose(); | ||
226 | return true; | ||
227 | } | ||
228 | |||
229 | cmd.Dispose(); | ||
230 | return false; | ||
231 | } | ||
232 | |||
233 | public bool CheckToken(UUID principalID, string token, int lifetime) | ||
234 | { | ||
235 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
236 | DoExpire(); | ||
237 | |||
238 | SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now, 'localtime', '+" + lifetime.ToString() + | ||
239 | " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')"); | ||
240 | |||
241 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
242 | { | ||
243 | cmd.Dispose(); | ||
244 | return true; | ||
245 | } | ||
246 | |||
247 | cmd.Dispose(); | ||
248 | |||
249 | return false; | ||
250 | } | ||
251 | |||
252 | private void DoExpire() | ||
253 | { | ||
254 | SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')"); | ||
255 | ExecuteNonQuery(cmd, m_Connection); | ||
256 | |||
257 | cmd.Dispose(); | ||
258 | |||
259 | m_LastExpire = System.Environment.TickCount; | ||
260 | } | ||
261 | } | ||
262 | } | ||
diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs b/OpenSim/Data/SQLite/SQLiteAvatarData.cs index 2e39cd0..b3f4a4c 100644 --- a/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs +++ b/OpenSim/Data/SQLite/SQLiteAvatarData.cs | |||
@@ -26,34 +26,48 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
30 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
31 | using System.Text; | 30 | using System.Data; |
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using Mono.Data.SqliteClient; | ||
32 | 37 | ||
33 | namespace OpenGridServices.Manager | 38 | namespace OpenSim.Data.SQLite |
34 | { | 39 | { |
35 | public class BlockingQueue<T> | 40 | /// <summary> |
41 | /// A SQLite Interface for Avatar Data | ||
42 | /// </summary> | ||
43 | public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>, | ||
44 | IAvatarData | ||
36 | { | 45 | { |
37 | private Queue<T> _queue = new Queue<T>(); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
38 | private object _queueSync = new object(); | ||
39 | 47 | ||
40 | public void Enqueue(T value) | 48 | public SQLiteAvatarData(string connectionString, string realm) : |
49 | base(connectionString, realm, "Avatar") | ||
41 | { | 50 | { |
42 | lock (_queueSync) | ||
43 | { | ||
44 | _queue.Enqueue(value); | ||
45 | Monitor.Pulse(_queueSync); | ||
46 | } | ||
47 | } | 51 | } |
48 | 52 | ||
49 | public T Dequeue() | 53 | public bool Delete(UUID principalID, string name) |
50 | { | 54 | { |
51 | lock (_queueSync) | 55 | SqliteCommand cmd = new SqliteCommand(); |
56 | |||
57 | cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm); | ||
58 | cmd.Parameters.Add(":PrincipalID", principalID.ToString()); | ||
59 | cmd.Parameters.Add(":Name", name); | ||
60 | |||
61 | try | ||
52 | { | 62 | { |
53 | if (_queue.Count < 1) | 63 | if (ExecuteNonQuery(cmd, m_Connection) > 0) |
54 | Monitor.Wait(_queueSync); | 64 | return true; |
55 | 65 | ||
56 | return _queue.Dequeue(); | 66 | return false; |
67 | } | ||
68 | finally | ||
69 | { | ||
70 | CloseCommand(cmd); | ||
57 | } | 71 | } |
58 | } | 72 | } |
59 | } | 73 | } |
diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs index 12b2750..20b5085 100644 --- a/OpenSim/Data/SQLite/SQLiteFramework.cs +++ b/OpenSim/Data/SQLite/SQLiteFramework.cs | |||
@@ -40,12 +40,10 @@ namespace OpenSim.Data.SQLite | |||
40 | /// </summary> | 40 | /// </summary> |
41 | public class SQLiteFramework | 41 | public class SQLiteFramework |
42 | { | 42 | { |
43 | protected SqliteConnection m_Connection; | 43 | protected Object m_lockObject = new Object(); |
44 | 44 | ||
45 | protected SQLiteFramework(string connectionString) | 45 | protected SQLiteFramework(string connectionString) |
46 | { | 46 | { |
47 | m_Connection = new SqliteConnection(connectionString); | ||
48 | m_Connection.Open(); | ||
49 | } | 47 | } |
50 | 48 | ||
51 | ////////////////////////////////////////////////////////////// | 49 | ////////////////////////////////////////////////////////////// |
@@ -53,27 +51,37 @@ namespace OpenSim.Data.SQLite | |||
53 | // All non queries are funneled through one connection | 51 | // All non queries are funneled through one connection |
54 | // to increase performance a little | 52 | // to increase performance a little |
55 | // | 53 | // |
56 | protected int ExecuteNonQuery(SqliteCommand cmd) | 54 | protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection) |
57 | { | 55 | { |
58 | lock (m_Connection) | 56 | lock (connection) |
59 | { | 57 | { |
60 | cmd.Connection = m_Connection; | 58 | SqliteConnection newConnection = |
59 | (SqliteConnection)((ICloneable)connection).Clone(); | ||
60 | newConnection.Open(); | ||
61 | |||
62 | cmd.Connection = newConnection; | ||
63 | //Console.WriteLine("XXX " + cmd.CommandText); | ||
61 | 64 | ||
62 | return cmd.ExecuteNonQuery(); | 65 | return cmd.ExecuteNonQuery(); |
63 | } | 66 | } |
64 | } | 67 | } |
65 | 68 | ||
66 | protected IDataReader ExecuteReader(SqliteCommand cmd) | 69 | protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection) |
67 | { | 70 | { |
68 | SqliteConnection newConnection = | 71 | lock (connection) |
69 | (SqliteConnection)((ICloneable)m_Connection).Clone(); | 72 | { |
70 | newConnection.Open(); | 73 | SqliteConnection newConnection = |
74 | (SqliteConnection)((ICloneable)connection).Clone(); | ||
75 | newConnection.Open(); | ||
71 | 76 | ||
72 | cmd.Connection = newConnection; | 77 | cmd.Connection = newConnection; |
73 | return cmd.ExecuteReader(); | 78 | //Console.WriteLine("XXX " + cmd.CommandText); |
79 | |||
80 | return cmd.ExecuteReader(); | ||
81 | } | ||
74 | } | 82 | } |
75 | 83 | ||
76 | protected void CloseReaderCommand(SqliteCommand cmd) | 84 | protected void CloseCommand(SqliteCommand cmd) |
77 | { | 85 | { |
78 | cmd.Connection.Close(); | 86 | cmd.Connection.Close(); |
79 | cmd.Connection.Dispose(); | 87 | cmd.Connection.Dispose(); |
diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs new file mode 100644 index 0000000..0b12182 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs | |||
@@ -0,0 +1,70 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using Mono.Data.SqliteClient; | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | public class SQLiteFriendsData : SQLiteGenericTableHandler<FriendsData>, IFriendsData | ||
39 | { | ||
40 | public SQLiteFriendsData(string connectionString, string realm) | ||
41 | : base(connectionString, realm, "FriendsStore") | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public FriendsData[] GetFriends(UUID userID) | ||
46 | { | ||
47 | SqliteCommand cmd = new SqliteCommand(); | ||
48 | |||
49 | cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = :PrincipalID", m_Realm); | ||
50 | cmd.Parameters.Add(":PrincipalID", userID.ToString()); | ||
51 | |||
52 | return DoQuery(cmd); | ||
53 | |||
54 | } | ||
55 | |||
56 | public bool Delete(UUID principalID, string friend) | ||
57 | { | ||
58 | SqliteCommand cmd = new SqliteCommand(); | ||
59 | |||
60 | cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm); | ||
61 | cmd.Parameters.Add(":PrincipalID", principalID.ToString()); | ||
62 | cmd.Parameters.Add(":Friend", friend); | ||
63 | |||
64 | ExecuteNonQuery(cmd, cmd.Connection); | ||
65 | |||
66 | return true; | ||
67 | } | ||
68 | |||
69 | } | ||
70 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 8e91693..b39bb19 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs | |||
@@ -48,16 +48,33 @@ namespace OpenSim.Data.SQLite | |||
48 | protected string m_Realm; | 48 | protected string m_Realm; |
49 | protected FieldInfo m_DataField = null; | 49 | protected FieldInfo m_DataField = null; |
50 | 50 | ||
51 | protected static SqliteConnection m_Connection; | ||
52 | private static bool m_initialized; | ||
53 | |||
51 | public SQLiteGenericTableHandler(string connectionString, | 54 | public SQLiteGenericTableHandler(string connectionString, |
52 | string realm, string storeName) : base(connectionString) | 55 | string realm, string storeName) : base(connectionString) |
53 | { | 56 | { |
54 | m_Realm = realm; | 57 | m_Realm = realm; |
55 | if (storeName != String.Empty) | 58 | |
59 | if (!m_initialized) | ||
56 | { | 60 | { |
57 | Assembly assem = GetType().Assembly; | 61 | m_Connection = new SqliteConnection(connectionString); |
62 | m_Connection.Open(); | ||
63 | |||
64 | if (storeName != String.Empty) | ||
65 | { | ||
66 | Assembly assem = GetType().Assembly; | ||
67 | SqliteConnection newConnection = | ||
68 | (SqliteConnection)((ICloneable)m_Connection).Clone(); | ||
69 | newConnection.Open(); | ||
70 | |||
71 | Migration m = new Migration(newConnection, assem, storeName); | ||
72 | m.Update(); | ||
73 | newConnection.Close(); | ||
74 | newConnection.Dispose(); | ||
75 | } | ||
58 | 76 | ||
59 | Migration m = new Migration(m_Connection, assem, storeName); | 77 | m_initialized = true; |
60 | m.Update(); | ||
61 | } | 78 | } |
62 | 79 | ||
63 | Type t = typeof(T); | 80 | Type t = typeof(T); |
@@ -125,7 +142,7 @@ namespace OpenSim.Data.SQLite | |||
125 | 142 | ||
126 | protected T[] DoQuery(SqliteCommand cmd) | 143 | protected T[] DoQuery(SqliteCommand cmd) |
127 | { | 144 | { |
128 | IDataReader reader = ExecuteReader(cmd); | 145 | IDataReader reader = ExecuteReader(cmd, m_Connection); |
129 | if (reader == null) | 146 | if (reader == null) |
130 | return new T[0]; | 147 | return new T[0]; |
131 | 148 | ||
@@ -180,7 +197,7 @@ namespace OpenSim.Data.SQLite | |||
180 | result.Add(row); | 197 | result.Add(row); |
181 | } | 198 | } |
182 | 199 | ||
183 | CloseReaderCommand(cmd); | 200 | CloseCommand(cmd); |
184 | 201 | ||
185 | return result.ToArray(); | 202 | return result.ToArray(); |
186 | } | 203 | } |
@@ -229,7 +246,7 @@ namespace OpenSim.Data.SQLite | |||
229 | 246 | ||
230 | cmd.CommandText = query; | 247 | cmd.CommandText = query; |
231 | 248 | ||
232 | if (ExecuteNonQuery(cmd) > 0) | 249 | if (ExecuteNonQuery(cmd, m_Connection) > 0) |
233 | return true; | 250 | return true; |
234 | 251 | ||
235 | return false; | 252 | return false; |
@@ -242,7 +259,7 @@ namespace OpenSim.Data.SQLite | |||
242 | cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); | 259 | cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field); |
243 | cmd.Parameters.Add(new SqliteParameter(field, val)); | 260 | cmd.Parameters.Add(new SqliteParameter(field, val)); |
244 | 261 | ||
245 | if (ExecuteNonQuery(cmd) > 0) | 262 | if (ExecuteNonQuery(cmd, m_Connection) > 0) |
246 | return true; | 263 | return true; |
247 | 264 | ||
248 | return false; | 265 | return false; |
diff --git a/OpenSim/Data/SQLite/SQLiteGridData.cs b/OpenSim/Data/SQLite/SQLiteGridData.cs deleted file mode 100644 index 18abb88..0000000 --- a/OpenSim/Data/SQLite/SQLiteGridData.cs +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
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 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// A Grid Interface to the SQLite database | ||
40 | /// </summary> | ||
41 | public class SQLiteGridData : GridDataBase | ||
42 | { | ||
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | /// <summary> | ||
46 | /// SQLite database manager | ||
47 | /// </summary> | ||
48 | private SQLiteManager database; | ||
49 | |||
50 | override public void Initialise() | ||
51 | { | ||
52 | m_log.Info("[SQLite]: " + Name + " cannot be default-initialized!"); | ||
53 | throw new PluginNotInitialisedException (Name); | ||
54 | } | ||
55 | |||
56 | /// <summary> | ||
57 | /// <list type="bullet"> | ||
58 | /// <item>Initialises Inventory interface</item> | ||
59 | /// <item>Loads and initialises a new SQLite connection and maintains it.</item> | ||
60 | /// <item>use default URI if connect string is empty.</item> | ||
61 | /// </list> | ||
62 | /// </summary> | ||
63 | /// <param name="dbconnect">connect string</param> | ||
64 | override public void Initialise(string connect) | ||
65 | { | ||
66 | database = new SQLiteManager(connect); | ||
67 | } | ||
68 | |||
69 | /// <summary> | ||
70 | /// Shuts down the grid interface | ||
71 | /// </summary> | ||
72 | override public void Dispose() | ||
73 | { | ||
74 | database.Close(); | ||
75 | } | ||
76 | |||
77 | /// <summary> | ||
78 | /// Returns the name of this grid interface | ||
79 | /// </summary> | ||
80 | /// <returns>A string containing the grid interface</returns> | ||
81 | override public string Name | ||
82 | { | ||
83 | get { return "SQLite OpenGridData"; } | ||
84 | } | ||
85 | |||
86 | /// <summary> | ||
87 | /// Returns the version of this grid interface | ||
88 | /// </summary> | ||
89 | /// <returns>A string containing the version</returns> | ||
90 | override public string Version | ||
91 | { | ||
92 | get { return "0.1"; } | ||
93 | } | ||
94 | |||
95 | /// <summary> | ||
96 | /// Returns a list of regions within the specified ranges | ||
97 | /// </summary> | ||
98 | /// <param name="a">minimum X coordinate</param> | ||
99 | /// <param name="b">minimum Y coordinate</param> | ||
100 | /// <param name="c">maximum X coordinate</param> | ||
101 | /// <param name="d">maximum Y coordinate</param> | ||
102 | /// <returns>An array of region profiles</returns> | ||
103 | /// <remarks>NOT IMPLEMENTED ? always return null</remarks> | ||
104 | override public RegionProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) | ||
105 | { | ||
106 | return null; | ||
107 | } | ||
108 | |||
109 | |||
110 | /// <summary> | ||
111 | /// Returns up to maxNum profiles of regions that have a name starting with namePrefix | ||
112 | /// </summary> | ||
113 | /// <param name="name">The name to match against</param> | ||
114 | /// <param name="maxNum">Maximum number of profiles to return</param> | ||
115 | /// <returns>A list of sim profiles</returns> | ||
116 | override public List<RegionProfileData> GetRegionsByName (string namePrefix, uint maxNum) | ||
117 | { | ||
118 | return null; | ||
119 | } | ||
120 | |||
121 | /// <summary> | ||
122 | /// Returns a sim profile from it's handle | ||
123 | /// </summary> | ||
124 | /// <param name="handle">Region location handle</param> | ||
125 | /// <returns>Sim profile</returns> | ||
126 | override public RegionProfileData GetProfileByHandle(ulong handle) | ||
127 | { | ||
128 | Dictionary<string, string> param = new Dictionary<string, string>(); | ||
129 | param["handle"] = handle.ToString(); | ||
130 | |||
131 | IDbCommand result = database.Query("SELECT * FROM regions WHERE handle = @handle", param); | ||
132 | IDataReader reader = result.ExecuteReader(); | ||
133 | |||
134 | RegionProfileData row = database.getRow(reader); | ||
135 | reader.Close(); | ||
136 | result.Dispose(); | ||
137 | |||
138 | return row; | ||
139 | } | ||
140 | |||
141 | /// <summary> | ||
142 | /// Returns a sim profile from it's Region name string | ||
143 | /// </summary> | ||
144 | /// <param name="regionName">The region name search query</param> | ||
145 | /// <returns>The sim profile</returns> | ||
146 | override public RegionProfileData GetProfileByString(string regionName) | ||
147 | { | ||
148 | if (regionName.Length > 2) | ||
149 | { | ||
150 | Dictionary<string, string> param = new Dictionary<string, string>(); | ||
151 | // Add % because this is a like query. | ||
152 | param["?regionName"] = regionName + "%"; | ||
153 | // Only returns one record or no record. | ||
154 | IDbCommand result = database.Query("SELECT * FROM regions WHERE regionName like ?regionName LIMIT 1", param); | ||
155 | IDataReader reader = result.ExecuteReader(); | ||
156 | |||
157 | RegionProfileData row = database.getRow(reader); | ||
158 | reader.Close(); | ||
159 | result.Dispose(); | ||
160 | |||
161 | return row; | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | //m_log.Error("[DATABASE]: Searched for a Region Name shorter then 3 characters"); | ||
166 | return null; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /// <summary> | ||
171 | /// Returns a sim profile from it's UUID | ||
172 | /// </summary> | ||
173 | /// <param name="uuid">The region UUID</param> | ||
174 | /// <returns>The sim profile</returns> | ||
175 | override public RegionProfileData GetProfileByUUID(UUID uuid) | ||
176 | { | ||
177 | Dictionary<string, string> param = new Dictionary<string, string>(); | ||
178 | param["uuid"] = uuid.ToString(); | ||
179 | |||
180 | IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param); | ||
181 | IDataReader reader = result.ExecuteReader(); | ||
182 | |||
183 | RegionProfileData row = database.getRow(reader); | ||
184 | reader.Close(); | ||
185 | result.Dispose(); | ||
186 | |||
187 | return row; | ||
188 | } | ||
189 | |||
190 | /// <summary> | ||
191 | /// Returns a list of avatar and UUIDs that match the query | ||
192 | /// </summary> | ||
193 | /// <remarks>do nothing yet</remarks> | ||
194 | public List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query) | ||
195 | { | ||
196 | //Do nothing yet | ||
197 | List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>(); | ||
198 | return returnlist; | ||
199 | } | ||
200 | |||
201 | /// <summary> | ||
202 | /// Adds a new specified region to the database | ||
203 | /// </summary> | ||
204 | /// <param name="profile">The profile to add</param> | ||
205 | /// <returns>A dataresponse enum indicating success</returns> | ||
206 | override public DataResponse StoreProfile(RegionProfileData profile) | ||
207 | { | ||
208 | if (database.insertRow(profile)) | ||
209 | { | ||
210 | return DataResponse.RESPONSE_OK; | ||
211 | } | ||
212 | else | ||
213 | { | ||
214 | return DataResponse.RESPONSE_ERROR; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | /// <summary> | ||
219 | /// Deletes a sim profile from the database | ||
220 | /// </summary> | ||
221 | /// <param name="uuid">the sim UUID</param> | ||
222 | /// <returns>Successful?</returns> | ||
223 | override public DataResponse DeleteProfile(string uuid) | ||
224 | { | ||
225 | Dictionary<string, string> param = new Dictionary<string, string>(); | ||
226 | param["uuid"] = uuid; | ||
227 | |||
228 | IDbCommand result = database.Query("DELETE FROM regions WHERE uuid = @uuid", param); | ||
229 | if (result.ExecuteNonQuery() > 0) | ||
230 | { | ||
231 | return DataResponse.RESPONSE_OK; | ||
232 | } | ||
233 | return DataResponse.RESPONSE_ERROR; | ||
234 | } | ||
235 | |||
236 | /// <summary> | ||
237 | /// DEPRECATED. Attempts to authenticate a region by comparing a shared secret. | ||
238 | /// </summary> | ||
239 | /// <param name="uuid">The UUID of the challenger</param> | ||
240 | /// <param name="handle">The attempted regionHandle of the challenger</param> | ||
241 | /// <param name="authkey">The secret</param> | ||
242 | /// <returns>Whether the secret and regionhandle match the database entry for UUID</returns> | ||
243 | override public bool AuthenticateSim(UUID uuid, ulong handle, string authkey) | ||
244 | { | ||
245 | bool throwHissyFit = false; // Should be true by 1.0 | ||
246 | |||
247 | if (throwHissyFit) | ||
248 | throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); | ||
249 | |||
250 | RegionProfileData data = GetProfileByUUID(uuid); | ||
251 | |||
252 | return (handle == data.regionHandle && authkey == data.regionSecret); | ||
253 | } | ||
254 | |||
255 | /// <summary> | ||
256 | /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region | ||
257 | /// </summary> | ||
258 | /// <remarks>This requires a security audit.</remarks> | ||
259 | /// <param name="uuid"></param> | ||
260 | /// <param name="handle"></param> | ||
261 | /// <param name="authhash"></param> | ||
262 | /// <param name="challenge"></param> | ||
263 | /// <returns></returns> | ||
264 | public bool AuthenticateSim(UUID uuid, ulong handle, string authhash, string challenge) | ||
265 | { | ||
266 | // SHA512Managed HashProvider = new SHA512Managed(); | ||
267 | // Encoding TextProvider = new UTF8Encoding(); | ||
268 | |||
269 | // byte[] stream = TextProvider.GetBytes(uuid.ToString() + ":" + handle.ToString() + ":" + challenge); | ||
270 | // byte[] hash = HashProvider.ComputeHash(stream); | ||
271 | |||
272 | return false; | ||
273 | } | ||
274 | |||
275 | /// <summary> | ||
276 | /// NOT IMPLEMENTED | ||
277 | /// </summary> | ||
278 | /// <param name="x">x coordinate</param> | ||
279 | /// <param name="y">y coordinate</param> | ||
280 | /// <returns>always return null</returns> | ||
281 | override public ReservationData GetReservationAtPoint(uint x, uint y) | ||
282 | { | ||
283 | return null; | ||
284 | } | ||
285 | } | ||
286 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs index 64591fd..a5e0517 100644 --- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs | |||
@@ -46,10 +46,12 @@ namespace OpenSim.Data.SQLite | |||
46 | private const string invItemsSelect = "select * from inventoryitems"; | 46 | private const string invItemsSelect = "select * from inventoryitems"; |
47 | private const string invFoldersSelect = "select * from inventoryfolders"; | 47 | private const string invFoldersSelect = "select * from inventoryfolders"; |
48 | 48 | ||
49 | private SqliteConnection conn; | 49 | private static SqliteConnection conn; |
50 | private DataSet ds; | 50 | private static DataSet ds; |
51 | private SqliteDataAdapter invItemsDa; | 51 | private static SqliteDataAdapter invItemsDa; |
52 | private SqliteDataAdapter invFoldersDa; | 52 | private static SqliteDataAdapter invFoldersDa; |
53 | |||
54 | private static bool m_Initialized = false; | ||
53 | 55 | ||
54 | public void Initialise() | 56 | public void Initialise() |
55 | { | 57 | { |
@@ -67,39 +69,44 @@ namespace OpenSim.Data.SQLite | |||
67 | /// <param name="dbconnect">connect string</param> | 69 | /// <param name="dbconnect">connect string</param> |
68 | public void Initialise(string dbconnect) | 70 | public void Initialise(string dbconnect) |
69 | { | 71 | { |
70 | if (dbconnect == string.Empty) | 72 | if (!m_Initialized) |
71 | { | 73 | { |
72 | dbconnect = "URI=file:inventoryStore.db,version=3"; | 74 | m_Initialized = true; |
73 | } | 75 | |
74 | m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect); | 76 | if (dbconnect == string.Empty) |
75 | conn = new SqliteConnection(dbconnect); | 77 | { |
78 | dbconnect = "URI=file:inventoryStore.db,version=3"; | ||
79 | } | ||
80 | m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect); | ||
81 | conn = new SqliteConnection(dbconnect); | ||
76 | 82 | ||
77 | conn.Open(); | 83 | conn.Open(); |
78 | 84 | ||
79 | Assembly assem = GetType().Assembly; | 85 | Assembly assem = GetType().Assembly; |
80 | Migration m = new Migration(conn, assem, "InventoryStore"); | 86 | Migration m = new Migration(conn, assem, "InventoryStore"); |
81 | m.Update(); | 87 | m.Update(); |
82 | 88 | ||
83 | SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); | 89 | SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); |
84 | invItemsDa = new SqliteDataAdapter(itemsSelectCmd); | 90 | invItemsDa = new SqliteDataAdapter(itemsSelectCmd); |
85 | // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); | 91 | // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); |
86 | 92 | ||
87 | SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); | 93 | SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); |
88 | invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); | 94 | invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); |
89 | 95 | ||
90 | ds = new DataSet(); | 96 | ds = new DataSet(); |
91 | 97 | ||
92 | ds.Tables.Add(createInventoryFoldersTable()); | 98 | ds.Tables.Add(createInventoryFoldersTable()); |
93 | invFoldersDa.Fill(ds.Tables["inventoryfolders"]); | 99 | invFoldersDa.Fill(ds.Tables["inventoryfolders"]); |
94 | setupFoldersCommands(invFoldersDa, conn); | 100 | setupFoldersCommands(invFoldersDa, conn); |
95 | m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); | 101 | m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); |
96 | 102 | ||
97 | ds.Tables.Add(createInventoryItemsTable()); | 103 | ds.Tables.Add(createInventoryItemsTable()); |
98 | invItemsDa.Fill(ds.Tables["inventoryitems"]); | 104 | invItemsDa.Fill(ds.Tables["inventoryitems"]); |
99 | setupItemsCommands(invItemsDa, conn); | 105 | setupItemsCommands(invItemsDa, conn); |
100 | m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); | 106 | m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); |
101 | 107 | ||
102 | ds.AcceptChanges(); | 108 | ds.AcceptChanges(); |
109 | } | ||
103 | } | 110 | } |
104 | 111 | ||
105 | /// <summary> | 112 | /// <summary> |
diff --git a/OpenSim/Data/SQLite/SQLiteManager.cs b/OpenSim/Data/SQLite/SQLiteManager.cs deleted file mode 100644 index b6d4a1c..0000000 --- a/OpenSim/Data/SQLite/SQLiteManager.cs +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
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.Data.SQLite; | ||
32 | using System.Reflection; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// SQLite Manager | ||
40 | /// </summary> | ||
41 | internal class SQLiteManager : SQLiteUtil | ||
42 | { | ||
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
44 | |||
45 | private IDbConnection dbcon; | ||
46 | |||
47 | /// <summary> | ||
48 | /// <list type="bullet"> | ||
49 | /// <item>Initialises and creates a new SQLite connection and maintains it.</item> | ||
50 | /// <item>use default URI if connect string is empty.</item> | ||
51 | /// </list> | ||
52 | /// </summary> | ||
53 | /// <param name="connect">connect string</param> | ||
54 | public SQLiteManager(string connect) | ||
55 | { | ||
56 | try | ||
57 | { | ||
58 | string connectionString = String.Empty; | ||
59 | if (connect != String.Empty) | ||
60 | { | ||
61 | connectionString = connect; | ||
62 | } | ||
63 | else | ||
64 | { | ||
65 | m_log.Warn("[SQLITE] grid db not specified, using default"); | ||
66 | connectionString = "URI=file:GridServerSqlite.db;"; | ||
67 | } | ||
68 | |||
69 | dbcon = new SQLiteConnection(connectionString); | ||
70 | |||
71 | dbcon.Open(); | ||
72 | } | ||
73 | catch (Exception e) | ||
74 | { | ||
75 | throw new Exception("Error initialising SQLite Database: " + e.ToString()); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /// <summary> | ||
80 | /// Shuts down the database connection | ||
81 | /// </summary> | ||
82 | public void Close() | ||
83 | { | ||
84 | dbcon.Close(); | ||
85 | dbcon = null; | ||
86 | } | ||
87 | |||
88 | /// <summary> | ||
89 | /// Runs a query with protection against SQL Injection by using parameterised input. | ||
90 | /// </summary> | ||
91 | /// <param name="sql">The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y</param> | ||
92 | /// <param name="parameters">The parameters - index so that @y is indexed as 'y'</param> | ||
93 | /// <returns>A SQLite DB Command</returns> | ||
94 | public IDbCommand Query(string sql, Dictionary<string, string> parameters) | ||
95 | { | ||
96 | SQLiteCommand dbcommand = (SQLiteCommand) dbcon.CreateCommand(); | ||
97 | dbcommand.CommandText = sql; | ||
98 | foreach (KeyValuePair<string, string> param in parameters) | ||
99 | { | ||
100 | SQLiteParameter paramx = new SQLiteParameter(param.Key, param.Value); | ||
101 | dbcommand.Parameters.Add(paramx); | ||
102 | } | ||
103 | |||
104 | return (IDbCommand) dbcommand; | ||
105 | } | ||
106 | |||
107 | /// <summary> | ||
108 | /// Reads a region row from a database reader | ||
109 | /// </summary> | ||
110 | /// <param name="reader">An active database reader</param> | ||
111 | /// <returns>A region profile</returns> | ||
112 | public RegionProfileData getRow(IDataReader reader) | ||
113 | { | ||
114 | RegionProfileData retval = new RegionProfileData(); | ||
115 | |||
116 | if (reader.Read()) | ||
117 | { | ||
118 | // Region Main | ||
119 | retval.regionHandle = (ulong) reader["regionHandle"]; | ||
120 | retval.regionName = (string) reader["regionName"]; | ||
121 | retval.UUID = new UUID((string) reader["uuid"]); | ||
122 | |||
123 | // Secrets | ||
124 | retval.regionRecvKey = (string) reader["regionRecvKey"]; | ||
125 | retval.regionSecret = (string) reader["regionSecret"]; | ||
126 | retval.regionSendKey = (string) reader["regionSendKey"]; | ||
127 | |||
128 | // Region Server | ||
129 | retval.regionDataURI = (string) reader["regionDataURI"]; | ||
130 | retval.regionOnline = false; // Needs to be pinged before this can be set. | ||
131 | retval.serverIP = (string) reader["serverIP"]; | ||
132 | retval.serverPort = (uint) reader["serverPort"]; | ||
133 | retval.serverURI = (string) reader["serverURI"]; | ||
134 | |||
135 | // Location | ||
136 | retval.regionLocX = (uint) ((int) reader["locX"]); | ||
137 | retval.regionLocY = (uint) ((int) reader["locY"]); | ||
138 | retval.regionLocZ = (uint) ((int) reader["locZ"]); | ||
139 | |||
140 | // Neighbours - 0 = No Override | ||
141 | retval.regionEastOverrideHandle = (ulong) reader["eastOverrideHandle"]; | ||
142 | retval.regionWestOverrideHandle = (ulong) reader["westOverrideHandle"]; | ||
143 | retval.regionSouthOverrideHandle = (ulong) reader["southOverrideHandle"]; | ||
144 | retval.regionNorthOverrideHandle = (ulong) reader["northOverrideHandle"]; | ||
145 | |||
146 | // Assets | ||
147 | retval.regionAssetURI = (string) reader["regionAssetURI"]; | ||
148 | retval.regionAssetRecvKey = (string) reader["regionAssetRecvKey"]; | ||
149 | retval.regionAssetSendKey = (string) reader["regionAssetSendKey"]; | ||
150 | |||
151 | // Userserver | ||
152 | retval.regionUserURI = (string) reader["regionUserURI"]; | ||
153 | retval.regionUserRecvKey = (string) reader["regionUserRecvKey"]; | ||
154 | retval.regionUserSendKey = (string) reader["regionUserSendKey"]; | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | throw new Exception("No rows to return"); | ||
159 | } | ||
160 | return retval; | ||
161 | } | ||
162 | |||
163 | /// <summary> | ||
164 | /// Inserts a new region into the database | ||
165 | /// </summary> | ||
166 | /// <param name="profile">The region to insert</param> | ||
167 | /// <returns>Success?</returns> | ||
168 | public bool insertRow(RegionProfileData profile) | ||
169 | { | ||
170 | string sql = | ||
171 | "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; | ||
172 | sql += | ||
173 | "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; | ||
174 | sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES "; | ||
175 | |||
176 | sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; | ||
177 | sql += | ||
178 | "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; | ||
179 | sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);"; | ||
180 | |||
181 | Dictionary<string, string> parameters = new Dictionary<string, string>(); | ||
182 | |||
183 | parameters["regionHandle"] = profile.regionHandle.ToString(); | ||
184 | parameters["regionName"] = profile.regionName; | ||
185 | parameters["uuid"] = profile.UUID.ToString(); | ||
186 | parameters["regionRecvKey"] = profile.regionRecvKey; | ||
187 | parameters["regionSendKey"] = profile.regionSendKey; | ||
188 | parameters["regionDataURI"] = profile.regionDataURI; | ||
189 | parameters["serverIP"] = profile.serverIP; | ||
190 | parameters["serverPort"] = profile.serverPort.ToString(); | ||
191 | parameters["serverURI"] = profile.serverURI; | ||
192 | parameters["locX"] = profile.regionLocX.ToString(); | ||
193 | parameters["locY"] = profile.regionLocY.ToString(); | ||
194 | parameters["locZ"] = profile.regionLocZ.ToString(); | ||
195 | parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); | ||
196 | parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); | ||
197 | parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); | ||
198 | parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); | ||
199 | parameters["regionAssetURI"] = profile.regionAssetURI; | ||
200 | parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; | ||
201 | parameters["regionAssetSendKey"] = profile.regionAssetSendKey; | ||
202 | parameters["regionUserURI"] = profile.regionUserURI; | ||
203 | parameters["regionUserRecvKey"] = profile.regionUserRecvKey; | ||
204 | parameters["regionUserSendKey"] = profile.regionUserSendKey; | ||
205 | |||
206 | bool returnval = false; | ||
207 | |||
208 | try | ||
209 | { | ||
210 | IDbCommand result = Query(sql, parameters); | ||
211 | |||
212 | if (result.ExecuteNonQuery() == 1) | ||
213 | returnval = true; | ||
214 | |||
215 | result.Dispose(); | ||
216 | } | ||
217 | catch (Exception) | ||
218 | { | ||
219 | return false; | ||
220 | } | ||
221 | |||
222 | return returnval; | ||
223 | } | ||
224 | } | ||
225 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs new file mode 100644 index 0000000..50e8c23 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs | |||
@@ -0,0 +1,81 @@ | |||
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; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Data; | ||
32 | using OpenMetaverse; | ||
33 | using OpenSim.Framework; | ||
34 | using Mono.Data.SqliteClient; | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | public class SQLiteUserAccountData : SQLiteGenericTableHandler<UserAccountData>, IUserAccountData | ||
39 | { | ||
40 | public SQLiteUserAccountData(string connectionString, string realm) | ||
41 | : base(connectionString, realm, "UserAccount") | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public UserAccountData[] GetUsers(UUID scopeID, string query) | ||
46 | { | ||
47 | string[] words = query.Split(new char[] {' '}); | ||
48 | |||
49 | for (int i = 0 ; i < words.Length ; i++) | ||
50 | { | ||
51 | if (words[i].Length < 3) | ||
52 | { | ||
53 | if (i != words.Length - 1) | ||
54 | Array.Copy(words, i + 1, words, i, words.Length - i - 1); | ||
55 | Array.Resize(ref words, words.Length - 1); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (words.Length == 0) | ||
60 | return new UserAccountData[0]; | ||
61 | |||
62 | if (words.Length > 2) | ||
63 | return new UserAccountData[0]; | ||
64 | |||
65 | SqliteCommand cmd = new SqliteCommand(); | ||
66 | |||
67 | if (words.Length == 1) | ||
68 | { | ||
69 | cmd.CommandText = String.Format("select * from {0} where ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{2}%')", | ||
70 | m_Realm, scopeID.ToString(), words[0]); | ||
71 | } | ||
72 | else | ||
73 | { | ||
74 | cmd.CommandText = String.Format("select * from {0} where (ScopeID='{1}' or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like '{2}%' or LastName like '{3}%')", | ||
75 | m_Realm, scopeID.ToString(), words[0], words[1]); | ||
76 | } | ||
77 | |||
78 | return DoQuery(cmd); | ||
79 | } | ||
80 | } | ||
81 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs deleted file mode 100644 index caddcf8..0000000 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ /dev/null | |||
@@ -1,1262 +0,0 @@ | |||
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 | using Mono.Data.SqliteClient; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | |||
37 | namespace OpenSim.Data.SQLite | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// A User storage interface for the SQLite database system | ||
41 | /// </summary> | ||
42 | public class SQLiteUserData : UserDataBase | ||
43 | { | ||
44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
46 | /// <summary> | ||
47 | /// The database manager | ||
48 | /// </summary> | ||
49 | /// <summary> | ||
50 | /// Artificial constructor called upon plugin load | ||
51 | /// </summary> | ||
52 | private const string SelectUserByUUID = "select * from users where UUID=:UUID"; | ||
53 | private const string SelectUserByName = "select * from users where username=:username and surname=:surname"; | ||
54 | private const string SelectFriendsByUUID = "select a.friendID, a.friendPerms, b.friendPerms from userfriends as a, userfriends as b where a.ownerID=:ownerID and b.ownerID=a.friendID and b.friendID=a.ownerID"; | ||
55 | |||
56 | private const string userSelect = "select * from users"; | ||
57 | private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b"; | ||
58 | private const string userAgentSelect = "select * from useragents"; | ||
59 | private const string AvatarAppearanceSelect = "select * from avatarappearance"; | ||
60 | |||
61 | private const string AvatarPickerAndSQL = "select * from users where username like :username and surname like :surname"; | ||
62 | private const string AvatarPickerOrSQL = "select * from users where username like :username or surname like :surname"; | ||
63 | |||
64 | private DataSet ds; | ||
65 | private SqliteDataAdapter da; | ||
66 | private SqliteDataAdapter daf; | ||
67 | private SqliteDataAdapter dua; | ||
68 | private SqliteDataAdapter daa; | ||
69 | SqliteConnection g_conn; | ||
70 | |||
71 | public override void Initialise() | ||
72 | { | ||
73 | m_log.Info("[SQLiteUserData]: " + Name + " cannot be default-initialized!"); | ||
74 | throw new PluginNotInitialisedException (Name); | ||
75 | } | ||
76 | |||
77 | /// <summary> | ||
78 | /// <list type="bullet"> | ||
79 | /// <item>Initialises User Interface</item> | ||
80 | /// <item>Loads and initialises a new SQLite connection and maintains it.</item> | ||
81 | /// <item>use default URI if connect string string is empty.</item> | ||
82 | /// </list> | ||
83 | /// </summary> | ||
84 | /// <param name="connect">connect string</param> | ||
85 | override public void Initialise(string connect) | ||
86 | { | ||
87 | // default to something sensible | ||
88 | if (connect == "") | ||
89 | connect = "URI=file:userprofiles.db,version=3"; | ||
90 | |||
91 | SqliteConnection conn = new SqliteConnection(connect); | ||
92 | |||
93 | // This sucks, but It doesn't seem to work with the dataset Syncing :P | ||
94 | g_conn = conn; | ||
95 | g_conn.Open(); | ||
96 | |||
97 | Assembly assem = GetType().Assembly; | ||
98 | Migration m = new Migration(g_conn, assem, "UserStore"); | ||
99 | m.Update(); | ||
100 | |||
101 | |||
102 | ds = new DataSet(); | ||
103 | da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn)); | ||
104 | dua = new SqliteDataAdapter(new SqliteCommand(userAgentSelect, conn)); | ||
105 | daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn)); | ||
106 | daa = new SqliteDataAdapter(new SqliteCommand(AvatarAppearanceSelect, conn)); | ||
107 | //if (daa == null) m_log.Info("[SQLiteUserData]: daa = null"); | ||
108 | |||
109 | lock (ds) | ||
110 | { | ||
111 | ds.Tables.Add(createUsersTable()); | ||
112 | ds.Tables.Add(createUserAgentsTable()); | ||
113 | ds.Tables.Add(createUserFriendsTable()); | ||
114 | ds.Tables.Add(createAvatarAppearanceTable()); | ||
115 | |||
116 | setupUserCommands(da, conn); | ||
117 | da.Fill(ds.Tables["users"]); | ||
118 | |||
119 | setupAgentCommands(dua, conn); | ||
120 | dua.Fill(ds.Tables["useragents"]); | ||
121 | |||
122 | setupUserFriendsCommands(daf, conn); | ||
123 | daf.Fill(ds.Tables["userfriends"]); | ||
124 | |||
125 | setupAvatarAppearanceCommands(daa, conn); | ||
126 | daa.Fill(ds.Tables["avatarappearance"]); | ||
127 | } | ||
128 | |||
129 | return; | ||
130 | } | ||
131 | |||
132 | public override void Dispose () | ||
133 | { | ||
134 | if (g_conn != null) | ||
135 | { | ||
136 | g_conn.Close(); | ||
137 | g_conn = null; | ||
138 | } | ||
139 | if (ds != null) | ||
140 | { | ||
141 | ds.Dispose(); | ||
142 | ds = null; | ||
143 | } | ||
144 | if (da != null) | ||
145 | { | ||
146 | da.Dispose(); | ||
147 | da = null; | ||
148 | } | ||
149 | if (daf != null) | ||
150 | { | ||
151 | daf.Dispose(); | ||
152 | daf = null; | ||
153 | } | ||
154 | if (dua != null) | ||
155 | { | ||
156 | dua.Dispose(); | ||
157 | dua = null; | ||
158 | } | ||
159 | if (daa != null) | ||
160 | { | ||
161 | daa.Dispose(); | ||
162 | daa = null; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /// <summary> | ||
167 | /// see IUserDataPlugin, | ||
168 | /// Get user data profile by UUID | ||
169 | /// </summary> | ||
170 | /// <param name="uuid">User UUID</param> | ||
171 | /// <returns>user profile data</returns> | ||
172 | override public UserProfileData GetUserByUUID(UUID uuid) | ||
173 | { | ||
174 | lock (ds) | ||
175 | { | ||
176 | DataRow row = ds.Tables["users"].Rows.Find(uuid.ToString()); | ||
177 | if (row != null) | ||
178 | { | ||
179 | UserProfileData user = buildUserProfile(row); | ||
180 | return user; | ||
181 | } | ||
182 | else | ||
183 | { | ||
184 | return null; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /// <summary> | ||
190 | /// see IUserDataPlugin, | ||
191 | /// Get user data profile by name | ||
192 | /// </summary> | ||
193 | /// <param name="fname">first name</param> | ||
194 | /// <param name="lname">last name</param> | ||
195 | /// <returns>user profile data</returns> | ||
196 | override public UserProfileData GetUserByName(string fname, string lname) | ||
197 | { | ||
198 | string select = "surname = '" + lname + "' and username = '" + fname + "'"; | ||
199 | lock (ds) | ||
200 | { | ||
201 | DataRow[] rows = ds.Tables["users"].Select(select); | ||
202 | if (rows.Length > 0) | ||
203 | { | ||
204 | UserProfileData user = buildUserProfile(rows[0]); | ||
205 | return user; | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | return null; | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | |||
214 | #region User Friends List Data | ||
215 | |||
216 | private bool ExistsFriend(UUID owner, UUID friend) | ||
217 | { | ||
218 | string FindFriends = "select * from userfriends where (ownerID=:ownerID and friendID=:friendID) or (ownerID=:friendID and friendID=:ownerID)"; | ||
219 | using (SqliteCommand cmd = new SqliteCommand(FindFriends, g_conn)) | ||
220 | { | ||
221 | cmd.Parameters.Add(new SqliteParameter(":ownerID", owner.ToString())); | ||
222 | cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString())); | ||
223 | try | ||
224 | { | ||
225 | using (IDataReader reader = cmd.ExecuteReader()) | ||
226 | { | ||
227 | if (reader.Read()) | ||
228 | { | ||
229 | reader.Close(); | ||
230 | return true; | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | reader.Close(); | ||
235 | return false; | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | catch (Exception ex) | ||
240 | { | ||
241 | m_log.Error("[USER DB]: Exception getting friends list for user: " + ex.ToString()); | ||
242 | return false; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | /// <summary> | ||
247 | /// Add a new friend in the friendlist | ||
248 | /// </summary> | ||
249 | /// <param name="friendlistowner">UUID of the friendlist owner</param> | ||
250 | /// <param name="friend">UUID of the friend to add</param> | ||
251 | /// <param name="perms">permission flag</param> | ||
252 | override public void AddNewUserFriend(UUID friendlistowner, UUID friend, uint perms) | ||
253 | { | ||
254 | if (ExistsFriend(friendlistowner, friend)) | ||
255 | return; | ||
256 | |||
257 | string InsertFriends = "insert into userfriends(ownerID, friendID, friendPerms) values(:ownerID, :friendID, :perms)"; | ||
258 | using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn)) | ||
259 | { | ||
260 | cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString())); | ||
261 | cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString())); | ||
262 | cmd.Parameters.Add(new SqliteParameter(":perms", perms)); | ||
263 | cmd.ExecuteNonQuery(); | ||
264 | } | ||
265 | using (SqliteCommand cmd = new SqliteCommand(InsertFriends, g_conn)) | ||
266 | { | ||
267 | cmd.Parameters.Add(new SqliteParameter(":ownerID", friend.ToString())); | ||
268 | cmd.Parameters.Add(new SqliteParameter(":friendID", friendlistowner.ToString())); | ||
269 | cmd.Parameters.Add(new SqliteParameter(":perms", perms)); | ||
270 | cmd.ExecuteNonQuery(); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /// <summary> | ||
275 | /// Remove a user from the friendlist | ||
276 | /// </summary> | ||
277 | /// <param name="friendlistowner">UUID of the friendlist owner</param> | ||
278 | /// <param name="friend">UUID of the friend to remove</param> | ||
279 | override public void RemoveUserFriend(UUID friendlistowner, UUID friend) | ||
280 | { | ||
281 | string DeletePerms = "delete from userfriends where (ownerID=:ownerID and friendID=:friendID) or (ownerID=:friendID and friendID=:ownerID)"; | ||
282 | using (SqliteCommand cmd = new SqliteCommand(DeletePerms, g_conn)) | ||
283 | { | ||
284 | cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString())); | ||
285 | cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString())); | ||
286 | cmd.ExecuteNonQuery(); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | /// <summary> | ||
291 | /// Update the friendlist permission | ||
292 | /// </summary> | ||
293 | /// <param name="friendlistowner">UUID of the friendlist owner</param> | ||
294 | /// <param name="friend">UUID of the friend to modify</param> | ||
295 | /// <param name="perms">updated permission flag</param> | ||
296 | override public void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms) | ||
297 | { | ||
298 | string UpdatePerms = "update userfriends set friendPerms=:perms where ownerID=:ownerID and friendID=:friendID"; | ||
299 | using (SqliteCommand cmd = new SqliteCommand(UpdatePerms, g_conn)) | ||
300 | { | ||
301 | cmd.Parameters.Add(new SqliteParameter(":perms", perms)); | ||
302 | cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString())); | ||
303 | cmd.Parameters.Add(new SqliteParameter(":friendID", friend.ToString())); | ||
304 | cmd.ExecuteNonQuery(); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | /// <summary> | ||
309 | /// Get (fetch?) the friendlist for a user | ||
310 | /// </summary> | ||
311 | /// <param name="friendlistowner">UUID of the friendlist owner</param> | ||
312 | /// <returns>The friendlist list</returns> | ||
313 | override public List<FriendListItem> GetUserFriendList(UUID friendlistowner) | ||
314 | { | ||
315 | List<FriendListItem> returnlist = new List<FriendListItem>(); | ||
316 | |||
317 | using (SqliteCommand cmd = new SqliteCommand(SelectFriendsByUUID, g_conn)) | ||
318 | { | ||
319 | cmd.Parameters.Add(new SqliteParameter(":ownerID", friendlistowner.ToString())); | ||
320 | |||
321 | try | ||
322 | { | ||
323 | using (IDataReader reader = cmd.ExecuteReader()) | ||
324 | { | ||
325 | while (reader.Read()) | ||
326 | { | ||
327 | FriendListItem user = new FriendListItem(); | ||
328 | user.FriendListOwner = friendlistowner; | ||
329 | user.Friend = new UUID((string)reader[0]); | ||
330 | user.FriendPerms = Convert.ToUInt32(reader[1]); | ||
331 | user.FriendListOwnerPerms = Convert.ToUInt32(reader[2]); | ||
332 | returnlist.Add(user); | ||
333 | } | ||
334 | reader.Close(); | ||
335 | } | ||
336 | } | ||
337 | catch (Exception ex) | ||
338 | { | ||
339 | m_log.Error("[USER DB]: Exception getting friends list for user: " + ex.ToString()); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | return returnlist; | ||
344 | } | ||
345 | |||
346 | override public Dictionary<UUID, FriendRegionInfo> GetFriendRegionInfos (List<UUID> uuids) | ||
347 | { | ||
348 | Dictionary<UUID, FriendRegionInfo> infos = new Dictionary<UUID,FriendRegionInfo>(); | ||
349 | |||
350 | DataTable agents = ds.Tables["useragents"]; | ||
351 | foreach (UUID uuid in uuids) | ||
352 | { | ||
353 | lock (ds) | ||
354 | { | ||
355 | DataRow row = agents.Rows.Find(uuid.ToString()); | ||
356 | if (row == null) infos[uuid] = null; | ||
357 | else | ||
358 | { | ||
359 | FriendRegionInfo fri = new FriendRegionInfo(); | ||
360 | fri.isOnline = (bool)row["agentOnline"]; | ||
361 | fri.regionHandle = Convert.ToUInt64(row["currentHandle"]); | ||
362 | infos[uuid] = fri; | ||
363 | } | ||
364 | } | ||
365 | } | ||
366 | return infos; | ||
367 | } | ||
368 | |||
369 | #endregion | ||
370 | |||
371 | /// <summary> | ||
372 | /// | ||
373 | /// </summary> | ||
374 | /// <param name="queryID"></param> | ||
375 | /// <param name="query"></param> | ||
376 | /// <returns></returns> | ||
377 | override public List<AvatarPickerAvatar> GeneratePickerResults(UUID queryID, string query) | ||
378 | { | ||
379 | List<AvatarPickerAvatar> returnlist = new List<AvatarPickerAvatar>(); | ||
380 | string[] querysplit; | ||
381 | querysplit = query.Split(' '); | ||
382 | if (querysplit.Length == 2) | ||
383 | { | ||
384 | using (SqliteCommand cmd = new SqliteCommand(AvatarPickerAndSQL, g_conn)) | ||
385 | { | ||
386 | cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%")); | ||
387 | cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[1] + "%")); | ||
388 | |||
389 | using (IDataReader reader = cmd.ExecuteReader()) | ||
390 | { | ||
391 | while (reader.Read()) | ||
392 | { | ||
393 | AvatarPickerAvatar user = new AvatarPickerAvatar(); | ||
394 | user.AvatarID = new UUID((string) reader["UUID"]); | ||
395 | user.firstName = (string) reader["username"]; | ||
396 | user.lastName = (string) reader["surname"]; | ||
397 | returnlist.Add(user); | ||
398 | } | ||
399 | reader.Close(); | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | else if (querysplit.Length == 1) | ||
404 | { | ||
405 | using (SqliteCommand cmd = new SqliteCommand(AvatarPickerOrSQL, g_conn)) | ||
406 | { | ||
407 | cmd.Parameters.Add(new SqliteParameter(":username", querysplit[0] + "%")); | ||
408 | cmd.Parameters.Add(new SqliteParameter(":surname", querysplit[0] + "%")); | ||
409 | |||
410 | using (IDataReader reader = cmd.ExecuteReader()) | ||
411 | { | ||
412 | while (reader.Read()) | ||
413 | { | ||
414 | AvatarPickerAvatar user = new AvatarPickerAvatar(); | ||
415 | user.AvatarID = new UUID((string) reader["UUID"]); | ||
416 | user.firstName = (string) reader["username"]; | ||
417 | user.lastName = (string) reader["surname"]; | ||
418 | returnlist.Add(user); | ||
419 | } | ||
420 | reader.Close(); | ||
421 | } | ||
422 | } | ||
423 | } | ||
424 | return returnlist; | ||
425 | } | ||
426 | |||
427 | /// <summary> | ||
428 | /// Returns a user by UUID direct | ||
429 | /// </summary> | ||
430 | /// <param name="uuid">The user's account ID</param> | ||
431 | /// <returns>A matching user profile</returns> | ||
432 | override public UserAgentData GetAgentByUUID(UUID uuid) | ||
433 | { | ||
434 | lock (ds) | ||
435 | { | ||
436 | DataRow row = ds.Tables["useragents"].Rows.Find(uuid.ToString()); | ||
437 | if (row != null) | ||
438 | { | ||
439 | return buildUserAgent(row); | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | return null; | ||
444 | } | ||
445 | } | ||
446 | } | ||
447 | |||
448 | /// <summary> | ||
449 | /// Returns a session by account name | ||
450 | /// </summary> | ||
451 | /// <param name="name">The account name</param> | ||
452 | /// <returns>The user's session agent</returns> | ||
453 | override public UserAgentData GetAgentByName(string name) | ||
454 | { | ||
455 | return GetAgentByName(name.Split(' ')[0], name.Split(' ')[1]); | ||
456 | } | ||
457 | |||
458 | /// <summary> | ||
459 | /// Returns a session by account name | ||
460 | /// </summary> | ||
461 | /// <param name="fname">The first part of the user's account name</param> | ||
462 | /// <param name="lname">The second part of the user's account name</param> | ||
463 | /// <returns>A user agent</returns> | ||
464 | override public UserAgentData GetAgentByName(string fname, string lname) | ||
465 | { | ||
466 | UserAgentData agent = null; | ||
467 | |||
468 | UserProfileData profile = GetUserByName(fname, lname); | ||
469 | if (profile != null) | ||
470 | { | ||
471 | agent = GetAgentByUUID(profile.ID); | ||
472 | } | ||
473 | return agent; | ||
474 | } | ||
475 | |||
476 | /// <summary> | ||
477 | /// DEPRECATED? Store the weblogin key | ||
478 | /// </summary> | ||
479 | /// <param name="AgentID">UUID of the user</param> | ||
480 | /// <param name="WebLoginKey">UUID of the weblogin</param> | ||
481 | override public void StoreWebLoginKey(UUID AgentID, UUID WebLoginKey) | ||
482 | { | ||
483 | DataTable users = ds.Tables["users"]; | ||
484 | lock (ds) | ||
485 | { | ||
486 | DataRow row = users.Rows.Find(AgentID.ToString()); | ||
487 | if (row == null) | ||
488 | { | ||
489 | m_log.Warn("[USER DB]: Unable to store new web login key for non-existant user"); | ||
490 | } | ||
491 | else | ||
492 | { | ||
493 | UserProfileData user = GetUserByUUID(AgentID); | ||
494 | user.WebLoginKey = WebLoginKey; | ||
495 | fillUserRow(row, user); | ||
496 | da.Update(ds, "users"); | ||
497 | } | ||
498 | } | ||
499 | } | ||
500 | |||
501 | private bool ExistsFirstLastName(String fname, String lname) | ||
502 | { | ||
503 | string FindUser = "select * from users where (username=:username and surname=:surname)"; | ||
504 | using (SqliteCommand cmd = new SqliteCommand(FindUser, g_conn)) | ||
505 | { | ||
506 | cmd.Parameters.Add(new SqliteParameter(":username", fname)); | ||
507 | cmd.Parameters.Add(new SqliteParameter(":surname", lname)); | ||
508 | try | ||
509 | { | ||
510 | using (IDataReader reader = cmd.ExecuteReader()) | ||
511 | { | ||
512 | if (reader.Read()) | ||
513 | { | ||
514 | reader.Close(); | ||
515 | return true; | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | reader.Close(); | ||
520 | return false; | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | catch (Exception ex) | ||
525 | { | ||
526 | m_log.Error("[USER DB]: Exception searching for user's first and last name: " + ex.ToString()); | ||
527 | return false; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | |||
532 | /// <summary> | ||
533 | /// Creates a new user profile | ||
534 | /// </summary> | ||
535 | /// <param name="user">The profile to add to the database</param> | ||
536 | override public void AddNewUserProfile(UserProfileData user) | ||
537 | { | ||
538 | DataTable users = ds.Tables["users"]; | ||
539 | UUID zero = UUID.Zero; | ||
540 | if (ExistsFirstLastName(user.FirstName, user.SurName) || user.ID == zero) | ||
541 | return; | ||
542 | |||
543 | lock (ds) | ||
544 | { | ||
545 | DataRow row = users.Rows.Find(user.ID.ToString()); | ||
546 | if (row == null) | ||
547 | { | ||
548 | row = users.NewRow(); | ||
549 | fillUserRow(row, user); | ||
550 | users.Rows.Add(row); | ||
551 | |||
552 | m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored"); | ||
553 | |||
554 | // save changes off to disk | ||
555 | da.Update(ds, "users"); | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | m_log.WarnFormat("[USER DB]: Ignoring add since user with id {0} already exists", user.ID); | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | |||
564 | /// <summary> | ||
565 | /// Creates a new user profile | ||
566 | /// </summary> | ||
567 | /// <param name="user">The profile to add to the database</param> | ||
568 | /// <returns>True on success, false on error</returns> | ||
569 | override public bool UpdateUserProfile(UserProfileData user) | ||
570 | { | ||
571 | DataTable users = ds.Tables["users"]; | ||
572 | lock (ds) | ||
573 | { | ||
574 | DataRow row = users.Rows.Find(user.ID.ToString()); | ||
575 | if (row == null) | ||
576 | { | ||
577 | return false; | ||
578 | } | ||
579 | else | ||
580 | { | ||
581 | fillUserRow(row, user); | ||
582 | da.Update(ds, "users"); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | //AddNewUserProfile(user); | ||
587 | return true; | ||
588 | } | ||
589 | |||
590 | /// <summary> | ||
591 | /// Creates a new user agent | ||
592 | /// </summary> | ||
593 | /// <param name="agent">The agent to add to the database</param> | ||
594 | override public void AddNewUserAgent(UserAgentData agent) | ||
595 | { | ||
596 | UUID zero = UUID.Zero; | ||
597 | if (agent.SessionID == zero || agent.ProfileID == zero) | ||
598 | return; | ||
599 | |||
600 | DataTable agents = ds.Tables["useragents"]; | ||
601 | lock (ds) | ||
602 | { | ||
603 | DataRow row = agents.Rows.Find(agent.ProfileID.ToString()); | ||
604 | if (row == null) | ||
605 | { | ||
606 | row = agents.NewRow(); | ||
607 | fillUserAgentRow(row, agent); | ||
608 | agents.Rows.Add(row); | ||
609 | } | ||
610 | else | ||
611 | { | ||
612 | fillUserAgentRow(row, agent); | ||
613 | |||
614 | } | ||
615 | m_log.Info("[USER DB]: Syncing useragent database: " + ds.Tables["useragents"].Rows.Count + " agents stored"); | ||
616 | // save changes off to disk | ||
617 | dua.Update(ds, "useragents"); | ||
618 | } | ||
619 | } | ||
620 | |||
621 | /// <summary> | ||
622 | /// Transfers money between two user accounts | ||
623 | /// </summary> | ||
624 | /// <param name="from">Starting account</param> | ||
625 | /// <param name="to">End account</param> | ||
626 | /// <param name="amount">The amount to move</param> | ||
627 | /// <returns>Success?</returns> | ||
628 | override public bool MoneyTransferRequest(UUID from, UUID to, uint amount) | ||
629 | { | ||
630 | return false; // for consistency with the MySQL impl | ||
631 | } | ||
632 | |||
633 | /// <summary> | ||
634 | /// Transfers inventory between two accounts | ||
635 | /// </summary> | ||
636 | /// <remarks>Move to inventory server</remarks> | ||
637 | /// <param name="from">Senders account</param> | ||
638 | /// <param name="to">Receivers account</param> | ||
639 | /// <param name="item">Inventory item</param> | ||
640 | /// <returns>Success?</returns> | ||
641 | override public bool InventoryTransferRequest(UUID from, UUID to, UUID item) | ||
642 | { | ||
643 | return false; //for consistency with the MySQL impl | ||
644 | } | ||
645 | |||
646 | |||
647 | /// <summary> | ||
648 | /// Appearance. | ||
649 | /// TODO: stubs for now to do in memory appearance. | ||
650 | /// </summary> | ||
651 | /// <param name="user">The user UUID</param> | ||
652 | /// <returns>Avatar Appearence</returns> | ||
653 | override public AvatarAppearance GetUserAppearance(UUID user) | ||
654 | { | ||
655 | m_log.Info("[APPEARANCE] GetUserAppearance " + user.ToString()); | ||
656 | |||
657 | AvatarAppearance aa = new AvatarAppearance(user); | ||
658 | //try { | ||
659 | aa.Owner = user; | ||
660 | |||
661 | DataTable aap = ds.Tables["avatarappearance"]; | ||
662 | lock (ds) | ||
663 | { | ||
664 | DataRow row = aap.Rows.Find(Util.ToRawUuidString(user)); | ||
665 | if (row == null) | ||
666 | { | ||
667 | m_log.Info("[APPEARANCE] Could not find appearance for " + user.ToString()); | ||
668 | |||
669 | //m_log.Debug("[USER DB]: Creating avatarappearance For: " + user.ToString()); | ||
670 | |||
671 | //row = aap.NewRow(); | ||
672 | //fillAvatarAppearanceRow(row, user, appearance); | ||
673 | //aap.Rows.Add(row); | ||
674 | // m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored"); | ||
675 | // save changes off to disk | ||
676 | //daa.Update(ds, "avatarappearance"); | ||
677 | } | ||
678 | else | ||
679 | { | ||
680 | m_log.InfoFormat("[APPEARANCE] appearance found for {0}", user.ToString()); | ||
681 | |||
682 | aa.BodyAsset = new UUID((String)row["BodyAsset"]); | ||
683 | aa.BodyItem = new UUID((String)row["BodyItem"]); | ||
684 | aa.SkinItem = new UUID((String)row["SkinItem"]); | ||
685 | aa.SkinAsset = new UUID((String)row["SkinAsset"]); | ||
686 | aa.HairItem = new UUID((String)row["HairItem"]); | ||
687 | aa.HairAsset = new UUID((String)row["HairAsset"]); | ||
688 | aa.EyesItem = new UUID((String)row["EyesItem"]); | ||
689 | aa.EyesAsset = new UUID((String)row["EyesAsset"]); | ||
690 | aa.ShirtItem = new UUID((String)row["ShirtItem"]); | ||
691 | aa.ShirtAsset = new UUID((String)row["ShirtAsset"]); | ||
692 | aa.PantsItem = new UUID((String)row["PantsItem"]); | ||
693 | aa.PantsAsset = new UUID((String)row["PantsAsset"]); | ||
694 | aa.ShoesItem = new UUID((String)row["ShoesItem"]); | ||
695 | aa.ShoesAsset = new UUID((String)row["ShoesAsset"]); | ||
696 | aa.SocksItem = new UUID((String)row["SocksItem"]); | ||
697 | aa.SocksAsset = new UUID((String)row["SocksAsset"]); | ||
698 | aa.JacketItem = new UUID((String)row["JacketItem"]); | ||
699 | aa.JacketAsset = new UUID((String)row["JacketAsset"]); | ||
700 | aa.GlovesItem = new UUID((String)row["GlovesItem"]); | ||
701 | aa.GlovesAsset = new UUID((String)row["GlovesAsset"]); | ||
702 | aa.UnderShirtItem = new UUID((String)row["UnderShirtItem"]); | ||
703 | aa.UnderShirtAsset = new UUID((String)row["UnderShirtAsset"]); | ||
704 | aa.UnderPantsItem = new UUID((String)row["UnderPantsItem"]); | ||
705 | aa.UnderPantsAsset = new UUID((String)row["UnderPantsAsset"]); | ||
706 | aa.SkirtItem = new UUID((String)row["SkirtItem"]); | ||
707 | aa.SkirtAsset = new UUID((String)row["SkirtAsset"]); | ||
708 | |||
709 | // Ewe Loon | ||
710 | // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) | ||
711 | |||
712 | String str = (String)row["Texture"]; | ||
713 | byte[] texture = Convert.FromBase64String(str); | ||
714 | aa.Texture = new Primitive.TextureEntry(texture, 0, texture.Length); | ||
715 | |||
716 | str = (String)row["VisualParams"]; | ||
717 | byte[] VisualParams = Convert.FromBase64String(str); | ||
718 | aa.VisualParams = VisualParams; | ||
719 | |||
720 | aa.Serial = Convert.ToInt32(row["Serial"]); | ||
721 | aa.AvatarHeight = Convert.ToSingle(row["AvatarHeight"]); | ||
722 | m_log.InfoFormat("[APPEARANCE] appearance set for {0}", user.ToString()); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | // m_log.Info("[APPEARANCE] Found appearance for " + user.ToString() + aa.ToString()); | ||
727 | // } catch (KeyNotFoundException) { | ||
728 | // m_log.InfoFormat("[APPEARANCE] No appearance found for {0}", user.ToString()); | ||
729 | // } | ||
730 | return aa; | ||
731 | } | ||
732 | |||
733 | /// <summary> | ||
734 | /// Update a user appearence | ||
735 | /// </summary> | ||
736 | /// <param name="user">the user UUID</param> | ||
737 | /// <param name="appearance">appearence</param> | ||
738 | override public void UpdateUserAppearance(UUID user, AvatarAppearance appearance) | ||
739 | { | ||
740 | appearance.Owner = user; | ||
741 | DataTable aap = ds.Tables["avatarappearance"]; | ||
742 | lock (ds) | ||
743 | { | ||
744 | DataRow row = aap.Rows.Find(Util.ToRawUuidString(user)); | ||
745 | if (row == null) | ||
746 | { | ||
747 | m_log.Debug("[USER DB]: Creating UserAppearance For: " + user.ToString()); | ||
748 | |||
749 | row = aap.NewRow(); | ||
750 | fillAvatarAppearanceRow(row, user, appearance); | ||
751 | aap.Rows.Add(row); | ||
752 | // m_log.Debug("[USER DB]: Syncing user database: " + ds.Tables["users"].Rows.Count + " users stored"); | ||
753 | // save changes off to disk | ||
754 | daa.Update(ds, "avatarappearance"); | ||
755 | } | ||
756 | else | ||
757 | { | ||
758 | m_log.Debug("[USER DB]: Updating UserAppearance For: " + user.ToString()); | ||
759 | fillAvatarAppearanceRow(row, user, appearance); | ||
760 | daa.Update(ds, "avatarappearance"); | ||
761 | } | ||
762 | } | ||
763 | } | ||
764 | |||
765 | /// <summary> | ||
766 | /// Returns the name of the storage provider | ||
767 | /// </summary> | ||
768 | /// <returns>Storage provider name</returns> | ||
769 | override public string Name | ||
770 | { | ||
771 | get {return "Sqlite Userdata";} | ||
772 | } | ||
773 | |||
774 | /// <summary> | ||
775 | /// Returns the version of the storage provider | ||
776 | /// </summary> | ||
777 | /// <returns>Storage provider version</returns> | ||
778 | override public string Version | ||
779 | { | ||
780 | get {return "0.1";} | ||
781 | } | ||
782 | |||
783 | /*********************************************************************** | ||
784 | * | ||
785 | * DataTable creation | ||
786 | * | ||
787 | **********************************************************************/ | ||
788 | /*********************************************************************** | ||
789 | * | ||
790 | * Database Definition Functions | ||
791 | * | ||
792 | * This should be db agnostic as we define them in ADO.NET terms | ||
793 | * | ||
794 | **********************************************************************/ | ||
795 | |||
796 | /// <summary> | ||
797 | /// Create the "users" table | ||
798 | /// </summary> | ||
799 | /// <returns>DataTable</returns> | ||
800 | private static DataTable createUsersTable() | ||
801 | { | ||
802 | DataTable users = new DataTable("users"); | ||
803 | |||
804 | SQLiteUtil.createCol(users, "UUID", typeof (String)); | ||
805 | SQLiteUtil.createCol(users, "username", typeof (String)); | ||
806 | SQLiteUtil.createCol(users, "surname", typeof (String)); | ||
807 | SQLiteUtil.createCol(users, "email", typeof (String)); | ||
808 | SQLiteUtil.createCol(users, "passwordHash", typeof (String)); | ||
809 | SQLiteUtil.createCol(users, "passwordSalt", typeof (String)); | ||
810 | |||
811 | SQLiteUtil.createCol(users, "homeRegionX", typeof (Int32)); | ||
812 | SQLiteUtil.createCol(users, "homeRegionY", typeof (Int32)); | ||
813 | SQLiteUtil.createCol(users, "homeRegionID", typeof (String)); | ||
814 | SQLiteUtil.createCol(users, "homeLocationX", typeof (Double)); | ||
815 | SQLiteUtil.createCol(users, "homeLocationY", typeof (Double)); | ||
816 | SQLiteUtil.createCol(users, "homeLocationZ", typeof (Double)); | ||
817 | SQLiteUtil.createCol(users, "homeLookAtX", typeof (Double)); | ||
818 | SQLiteUtil.createCol(users, "homeLookAtY", typeof (Double)); | ||
819 | SQLiteUtil.createCol(users, "homeLookAtZ", typeof (Double)); | ||
820 | SQLiteUtil.createCol(users, "created", typeof (Int32)); | ||
821 | SQLiteUtil.createCol(users, "lastLogin", typeof (Int32)); | ||
822 | |||
823 | //TODO: Please delete this column. It's now a brick | ||
824 | SQLiteUtil.createCol(users, "rootInventoryFolderID", typeof (String)); | ||
825 | |||
826 | SQLiteUtil.createCol(users, "userInventoryURI", typeof (String)); | ||
827 | SQLiteUtil.createCol(users, "userAssetURI", typeof (String)); | ||
828 | SQLiteUtil.createCol(users, "profileCanDoMask", typeof (Int32)); | ||
829 | SQLiteUtil.createCol(users, "profileWantDoMask", typeof (Int32)); | ||
830 | SQLiteUtil.createCol(users, "profileAboutText", typeof (String)); | ||
831 | SQLiteUtil.createCol(users, "profileFirstText", typeof (String)); | ||
832 | SQLiteUtil.createCol(users, "profileImage", typeof (String)); | ||
833 | SQLiteUtil.createCol(users, "profileFirstImage", typeof (String)); | ||
834 | SQLiteUtil.createCol(users, "webLoginKey", typeof(String)); | ||
835 | SQLiteUtil.createCol(users, "userFlags", typeof (Int32)); | ||
836 | SQLiteUtil.createCol(users, "godLevel", typeof (Int32)); | ||
837 | SQLiteUtil.createCol(users, "customType", typeof (String)); | ||
838 | SQLiteUtil.createCol(users, "partner", typeof (String)); | ||
839 | // Add in contraints | ||
840 | users.PrimaryKey = new DataColumn[] {users.Columns["UUID"]}; | ||
841 | return users; | ||
842 | } | ||
843 | |||
844 | /// <summary> | ||
845 | /// Create the "useragents" table | ||
846 | /// </summary> | ||
847 | /// <returns>Data Table</returns> | ||
848 | private static DataTable createUserAgentsTable() | ||
849 | { | ||
850 | DataTable ua = new DataTable("useragents"); | ||
851 | // this is the UUID of the user | ||
852 | SQLiteUtil.createCol(ua, "UUID", typeof (String)); | ||
853 | SQLiteUtil.createCol(ua, "agentIP", typeof (String)); | ||
854 | SQLiteUtil.createCol(ua, "agentPort", typeof (Int32)); | ||
855 | SQLiteUtil.createCol(ua, "agentOnline", typeof (Boolean)); | ||
856 | SQLiteUtil.createCol(ua, "sessionID", typeof (String)); | ||
857 | SQLiteUtil.createCol(ua, "secureSessionID", typeof (String)); | ||
858 | SQLiteUtil.createCol(ua, "regionID", typeof (String)); | ||
859 | SQLiteUtil.createCol(ua, "loginTime", typeof (Int32)); | ||
860 | SQLiteUtil.createCol(ua, "logoutTime", typeof (Int32)); | ||
861 | SQLiteUtil.createCol(ua, "currentRegion", typeof (String)); | ||
862 | SQLiteUtil.createCol(ua, "currentHandle", typeof (String)); | ||
863 | // vectors | ||
864 | SQLiteUtil.createCol(ua, "currentPosX", typeof (Double)); | ||
865 | SQLiteUtil.createCol(ua, "currentPosY", typeof (Double)); | ||
866 | SQLiteUtil.createCol(ua, "currentPosZ", typeof (Double)); | ||
867 | // constraints | ||
868 | ua.PrimaryKey = new DataColumn[] {ua.Columns["UUID"]}; | ||
869 | |||
870 | return ua; | ||
871 | } | ||
872 | |||
873 | /// <summary> | ||
874 | /// Create the "userfriends" table | ||
875 | /// </summary> | ||
876 | /// <returns>Data Table</returns> | ||
877 | private static DataTable createUserFriendsTable() | ||
878 | { | ||
879 | DataTable ua = new DataTable("userfriends"); | ||
880 | // table contains user <----> user relationship with perms | ||
881 | SQLiteUtil.createCol(ua, "ownerID", typeof(String)); | ||
882 | SQLiteUtil.createCol(ua, "friendID", typeof(String)); | ||
883 | SQLiteUtil.createCol(ua, "friendPerms", typeof(Int32)); | ||
884 | SQLiteUtil.createCol(ua, "ownerPerms", typeof(Int32)); | ||
885 | SQLiteUtil.createCol(ua, "datetimestamp", typeof(Int32)); | ||
886 | |||
887 | return ua; | ||
888 | } | ||
889 | |||
890 | /// <summary> | ||
891 | /// Create the "avatarappearance" table | ||
892 | /// </summary> | ||
893 | /// <returns>Data Table</returns> | ||
894 | private static DataTable createAvatarAppearanceTable() | ||
895 | { | ||
896 | DataTable aa = new DataTable("avatarappearance"); | ||
897 | // table contains user appearance items | ||
898 | |||
899 | SQLiteUtil.createCol(aa, "Owner", typeof(String)); | ||
900 | SQLiteUtil.createCol(aa, "BodyItem", typeof(String)); | ||
901 | SQLiteUtil.createCol(aa, "BodyAsset", typeof(String)); | ||
902 | SQLiteUtil.createCol(aa, "SkinItem", typeof(String)); | ||
903 | SQLiteUtil.createCol(aa, "SkinAsset", typeof(String)); | ||
904 | SQLiteUtil.createCol(aa, "HairItem", typeof(String)); | ||
905 | SQLiteUtil.createCol(aa, "HairAsset", typeof(String)); | ||
906 | SQLiteUtil.createCol(aa, "EyesItem", typeof(String)); | ||
907 | SQLiteUtil.createCol(aa, "EyesAsset", typeof(String)); | ||
908 | SQLiteUtil.createCol(aa, "ShirtItem", typeof(String)); | ||
909 | SQLiteUtil.createCol(aa, "ShirtAsset", typeof(String)); | ||
910 | SQLiteUtil.createCol(aa, "PantsItem", typeof(String)); | ||
911 | SQLiteUtil.createCol(aa, "PantsAsset", typeof(String)); | ||
912 | SQLiteUtil.createCol(aa, "ShoesItem", typeof(String)); | ||
913 | SQLiteUtil.createCol(aa, "ShoesAsset", typeof(String)); | ||
914 | SQLiteUtil.createCol(aa, "SocksItem", typeof(String)); | ||
915 | SQLiteUtil.createCol(aa, "SocksAsset", typeof(String)); | ||
916 | SQLiteUtil.createCol(aa, "JacketItem", typeof(String)); | ||
917 | SQLiteUtil.createCol(aa, "JacketAsset", typeof(String)); | ||
918 | SQLiteUtil.createCol(aa, "GlovesItem", typeof(String)); | ||
919 | SQLiteUtil.createCol(aa, "GlovesAsset", typeof(String)); | ||
920 | SQLiteUtil.createCol(aa, "UnderShirtItem", typeof(String)); | ||
921 | SQLiteUtil.createCol(aa, "UnderShirtAsset", typeof(String)); | ||
922 | SQLiteUtil.createCol(aa, "UnderPantsItem", typeof(String)); | ||
923 | SQLiteUtil.createCol(aa, "UnderPantsAsset", typeof(String)); | ||
924 | SQLiteUtil.createCol(aa, "SkirtItem", typeof(String)); | ||
925 | SQLiteUtil.createCol(aa, "SkirtAsset", typeof(String)); | ||
926 | |||
927 | // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) | ||
928 | SQLiteUtil.createCol(aa, "Texture", typeof (String)); | ||
929 | SQLiteUtil.createCol(aa, "VisualParams", typeof (String)); | ||
930 | |||
931 | SQLiteUtil.createCol(aa, "Serial", typeof(Int32)); | ||
932 | SQLiteUtil.createCol(aa, "AvatarHeight", typeof(Double)); | ||
933 | |||
934 | aa.PrimaryKey = new DataColumn[] { aa.Columns["Owner"] }; | ||
935 | |||
936 | return aa; | ||
937 | } | ||
938 | |||
939 | /*********************************************************************** | ||
940 | * | ||
941 | * Convert between ADO.NET <=> OpenSim Objects | ||
942 | * | ||
943 | * These should be database independant | ||
944 | * | ||
945 | **********************************************************************/ | ||
946 | |||
947 | /// <summary> | ||
948 | /// TODO: this doesn't work yet because something more | ||
949 | /// interesting has to be done to actually get these values | ||
950 | /// back out. Not enough time to figure it out yet. | ||
951 | /// </summary> | ||
952 | /// <param name="row"></param> | ||
953 | /// <returns></returns> | ||
954 | private static UserProfileData buildUserProfile(DataRow row) | ||
955 | { | ||
956 | UserProfileData user = new UserProfileData(); | ||
957 | UUID tmp; | ||
958 | UUID.TryParse((String)row["UUID"], out tmp); | ||
959 | user.ID = tmp; | ||
960 | user.FirstName = (String) row["username"]; | ||
961 | user.SurName = (String) row["surname"]; | ||
962 | user.Email = (row.IsNull("email")) ? "" : (String) row["email"]; | ||
963 | |||
964 | user.PasswordHash = (String) row["passwordHash"]; | ||
965 | user.PasswordSalt = (String) row["passwordSalt"]; | ||
966 | |||
967 | user.HomeRegionX = Convert.ToUInt32(row["homeRegionX"]); | ||
968 | user.HomeRegionY = Convert.ToUInt32(row["homeRegionY"]); | ||
969 | user.HomeLocation = new Vector3( | ||
970 | Convert.ToSingle(row["homeLocationX"]), | ||
971 | Convert.ToSingle(row["homeLocationY"]), | ||
972 | Convert.ToSingle(row["homeLocationZ"]) | ||
973 | ); | ||
974 | user.HomeLookAt = new Vector3( | ||
975 | Convert.ToSingle(row["homeLookAtX"]), | ||
976 | Convert.ToSingle(row["homeLookAtY"]), | ||
977 | Convert.ToSingle(row["homeLookAtZ"]) | ||
978 | ); | ||
979 | |||
980 | UUID regionID = UUID.Zero; | ||
981 | UUID.TryParse(row["homeRegionID"].ToString(), out regionID); // it's ok if it doesn't work; just use UUID.Zero | ||
982 | user.HomeRegionID = regionID; | ||
983 | |||
984 | user.Created = Convert.ToInt32(row["created"]); | ||
985 | user.LastLogin = Convert.ToInt32(row["lastLogin"]); | ||
986 | user.UserInventoryURI = (String) row["userInventoryURI"]; | ||
987 | user.UserAssetURI = (String) row["userAssetURI"]; | ||
988 | user.CanDoMask = Convert.ToUInt32(row["profileCanDoMask"]); | ||
989 | user.WantDoMask = Convert.ToUInt32(row["profileWantDoMask"]); | ||
990 | user.AboutText = (String) row["profileAboutText"]; | ||
991 | user.FirstLifeAboutText = (String) row["profileFirstText"]; | ||
992 | UUID.TryParse((String)row["profileImage"], out tmp); | ||
993 | user.Image = tmp; | ||
994 | UUID.TryParse((String)row["profileFirstImage"], out tmp); | ||
995 | user.FirstLifeImage = tmp; | ||
996 | user.WebLoginKey = new UUID((String) row["webLoginKey"]); | ||
997 | user.UserFlags = Convert.ToInt32(row["userFlags"]); | ||
998 | user.GodLevel = Convert.ToInt32(row["godLevel"]); | ||
999 | user.CustomType = row["customType"].ToString(); | ||
1000 | user.Partner = new UUID((String) row["partner"]); | ||
1001 | |||
1002 | return user; | ||
1003 | } | ||
1004 | |||
1005 | /// <summary> | ||
1006 | /// Persist user profile data | ||
1007 | /// </summary> | ||
1008 | /// <param name="row"></param> | ||
1009 | /// <param name="user"></param> | ||
1010 | private void fillUserRow(DataRow row, UserProfileData user) | ||
1011 | { | ||
1012 | row["UUID"] = user.ID.ToString(); | ||
1013 | row["username"] = user.FirstName; | ||
1014 | row["surname"] = user.SurName; | ||
1015 | row["email"] = user.Email; | ||
1016 | row["passwordHash"] = user.PasswordHash; | ||
1017 | row["passwordSalt"] = user.PasswordSalt; | ||
1018 | |||
1019 | row["homeRegionX"] = user.HomeRegionX; | ||
1020 | row["homeRegionY"] = user.HomeRegionY; | ||
1021 | row["homeRegionID"] = user.HomeRegionID.ToString(); | ||
1022 | row["homeLocationX"] = user.HomeLocation.X; | ||
1023 | row["homeLocationY"] = user.HomeLocation.Y; | ||
1024 | row["homeLocationZ"] = user.HomeLocation.Z; | ||
1025 | row["homeLookAtX"] = user.HomeLookAt.X; | ||
1026 | row["homeLookAtY"] = user.HomeLookAt.Y; | ||
1027 | row["homeLookAtZ"] = user.HomeLookAt.Z; | ||
1028 | |||
1029 | row["created"] = user.Created; | ||
1030 | row["lastLogin"] = user.LastLogin; | ||
1031 | //TODO: Get rid of rootInventoryFolderID in a safe way. | ||
1032 | row["rootInventoryFolderID"] = UUID.Zero.ToString(); | ||
1033 | row["userInventoryURI"] = user.UserInventoryURI; | ||
1034 | row["userAssetURI"] = user.UserAssetURI; | ||
1035 | row["profileCanDoMask"] = user.CanDoMask; | ||
1036 | row["profileWantDoMask"] = user.WantDoMask; | ||
1037 | row["profileAboutText"] = user.AboutText; | ||
1038 | row["profileFirstText"] = user.FirstLifeAboutText; | ||
1039 | row["profileImage"] = user.Image.ToString(); | ||
1040 | row["profileFirstImage"] = user.FirstLifeImage.ToString(); | ||
1041 | row["webLoginKey"] = user.WebLoginKey.ToString(); | ||
1042 | row["userFlags"] = user.UserFlags; | ||
1043 | row["godLevel"] = user.GodLevel; | ||
1044 | row["customType"] = user.CustomType == null ? "" : user.CustomType; | ||
1045 | row["partner"] = user.Partner.ToString(); | ||
1046 | |||
1047 | // ADO.NET doesn't handle NULL very well | ||
1048 | foreach (DataColumn col in ds.Tables["users"].Columns) | ||
1049 | { | ||
1050 | if (row[col] == null) | ||
1051 | { | ||
1052 | row[col] = String.Empty; | ||
1053 | } | ||
1054 | } | ||
1055 | } | ||
1056 | |||
1057 | /// <summary> | ||
1058 | /// | ||
1059 | /// </summary> | ||
1060 | /// <param name="row"></param> | ||
1061 | /// <param name="user"></param> | ||
1062 | private void fillAvatarAppearanceRow(DataRow row, UUID user, AvatarAppearance appearance) | ||
1063 | { | ||
1064 | row["Owner"] = Util.ToRawUuidString(user); | ||
1065 | row["BodyItem"] = appearance.BodyItem.ToString(); | ||
1066 | row["BodyAsset"] = appearance.BodyAsset.ToString(); | ||
1067 | row["SkinItem"] = appearance.SkinItem.ToString(); | ||
1068 | row["SkinAsset"] = appearance.SkinAsset.ToString(); | ||
1069 | row["HairItem"] = appearance.HairItem.ToString(); | ||
1070 | row["HairAsset"] = appearance.HairAsset.ToString(); | ||
1071 | row["EyesItem"] = appearance.EyesItem.ToString(); | ||
1072 | row["EyesAsset"] = appearance.EyesAsset.ToString(); | ||
1073 | row["ShirtItem"] = appearance.ShirtItem.ToString(); | ||
1074 | row["ShirtAsset"] = appearance.ShirtAsset.ToString(); | ||
1075 | row["PantsItem"] = appearance.PantsItem.ToString(); | ||
1076 | row["PantsAsset"] = appearance.PantsAsset.ToString(); | ||
1077 | row["ShoesItem"] = appearance.ShoesItem.ToString(); | ||
1078 | row["ShoesAsset"] = appearance.ShoesAsset.ToString(); | ||
1079 | row["SocksItem"] = appearance.SocksItem.ToString(); | ||
1080 | row["SocksAsset"] = appearance.SocksAsset.ToString(); | ||
1081 | row["JacketItem"] = appearance.JacketItem.ToString(); | ||
1082 | row["JacketAsset"] = appearance.JacketAsset.ToString(); | ||
1083 | row["GlovesItem"] = appearance.GlovesItem.ToString(); | ||
1084 | row["GlovesAsset"] = appearance.GlovesAsset.ToString(); | ||
1085 | row["UnderShirtItem"] = appearance.UnderShirtItem.ToString(); | ||
1086 | row["UnderShirtAsset"] = appearance.UnderShirtAsset.ToString(); | ||
1087 | row["UnderPantsItem"] = appearance.UnderPantsItem.ToString(); | ||
1088 | row["UnderPantsAsset"] = appearance.UnderPantsAsset.ToString(); | ||
1089 | row["SkirtItem"] = appearance.SkirtItem.ToString(); | ||
1090 | row["SkirtAsset"] = appearance.SkirtAsset.ToString(); | ||
1091 | |||
1092 | // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) | ||
1093 | row["Texture"] = Convert.ToBase64String(appearance.Texture.GetBytes()); | ||
1094 | row["VisualParams"] = Convert.ToBase64String(appearance.VisualParams); | ||
1095 | |||
1096 | row["Serial"] = appearance.Serial; | ||
1097 | row["AvatarHeight"] = appearance.AvatarHeight; | ||
1098 | |||
1099 | // ADO.NET doesn't handle NULL very well | ||
1100 | foreach (DataColumn col in ds.Tables["avatarappearance"].Columns) | ||
1101 | { | ||
1102 | if (row[col] == null) | ||
1103 | { | ||
1104 | row[col] = String.Empty; | ||
1105 | } | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | /// <summary> | ||
1110 | /// | ||
1111 | /// </summary> | ||
1112 | /// <param name="row"></param> | ||
1113 | /// <returns></returns> | ||
1114 | private static UserAgentData buildUserAgent(DataRow row) | ||
1115 | { | ||
1116 | UserAgentData ua = new UserAgentData(); | ||
1117 | |||
1118 | UUID tmp; | ||
1119 | UUID.TryParse((String)row["UUID"], out tmp); | ||
1120 | ua.ProfileID = tmp; | ||
1121 | ua.AgentIP = (String)row["agentIP"]; | ||
1122 | ua.AgentPort = Convert.ToUInt32(row["agentPort"]); | ||
1123 | ua.AgentOnline = Convert.ToBoolean(row["agentOnline"]); | ||
1124 | ua.SessionID = new UUID((String) row["sessionID"]); | ||
1125 | ua.SecureSessionID = new UUID((String) row["secureSessionID"]); | ||
1126 | ua.InitialRegion = new UUID((String) row["regionID"]); | ||
1127 | ua.LoginTime = Convert.ToInt32(row["loginTime"]); | ||
1128 | ua.LogoutTime = Convert.ToInt32(row["logoutTime"]); | ||
1129 | ua.Region = new UUID((String) row["currentRegion"]); | ||
1130 | ua.Handle = Convert.ToUInt64(row["currentHandle"]); | ||
1131 | ua.Position = new Vector3( | ||
1132 | Convert.ToSingle(row["currentPosX"]), | ||
1133 | Convert.ToSingle(row["currentPosY"]), | ||
1134 | Convert.ToSingle(row["currentPosZ"]) | ||
1135 | ); | ||
1136 | ua.LookAt = new Vector3( | ||
1137 | Convert.ToSingle(row["currentLookAtX"]), | ||
1138 | Convert.ToSingle(row["currentLookAtY"]), | ||
1139 | Convert.ToSingle(row["currentLookAtZ"]) | ||
1140 | ); | ||
1141 | return ua; | ||
1142 | } | ||
1143 | |||
1144 | /// <summary> | ||
1145 | /// | ||
1146 | /// </summary> | ||
1147 | /// <param name="row"></param> | ||
1148 | /// <param name="ua"></param> | ||
1149 | private static void fillUserAgentRow(DataRow row, UserAgentData ua) | ||
1150 | { | ||
1151 | row["UUID"] = ua.ProfileID.ToString(); | ||
1152 | row["agentIP"] = ua.AgentIP; | ||
1153 | row["agentPort"] = ua.AgentPort; | ||
1154 | row["agentOnline"] = ua.AgentOnline; | ||
1155 | row["sessionID"] = ua.SessionID.ToString(); | ||
1156 | row["secureSessionID"] = ua.SecureSessionID.ToString(); | ||
1157 | row["regionID"] = ua.InitialRegion.ToString(); | ||
1158 | row["loginTime"] = ua.LoginTime; | ||
1159 | row["logoutTime"] = ua.LogoutTime; | ||
1160 | row["currentRegion"] = ua.Region.ToString(); | ||
1161 | row["currentHandle"] = ua.Handle.ToString(); | ||
1162 | // vectors | ||
1163 | row["currentPosX"] = ua.Position.X; | ||
1164 | row["currentPosY"] = ua.Position.Y; | ||
1165 | row["currentPosZ"] = ua.Position.Z; | ||
1166 | row["currentLookAtX"] = ua.LookAt.X; | ||
1167 | row["currentLookAtY"] = ua.LookAt.Y; | ||
1168 | row["currentLookAtZ"] = ua.LookAt.Z; | ||
1169 | } | ||
1170 | |||
1171 | /*********************************************************************** | ||
1172 | * | ||
1173 | * Database Binding functions | ||
1174 | * | ||
1175 | * These will be db specific due to typing, and minor differences | ||
1176 | * in databases. | ||
1177 | * | ||
1178 | **********************************************************************/ | ||
1179 | |||
1180 | /// <summary> | ||
1181 | /// | ||
1182 | /// </summary> | ||
1183 | /// <param name="da"></param> | ||
1184 | /// <param name="conn"></param> | ||
1185 | private void setupUserCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
1186 | { | ||
1187 | da.InsertCommand = SQLiteUtil.createInsertCommand("users", ds.Tables["users"]); | ||
1188 | da.InsertCommand.Connection = conn; | ||
1189 | |||
1190 | da.UpdateCommand = SQLiteUtil.createUpdateCommand("users", "UUID=:UUID", ds.Tables["users"]); | ||
1191 | da.UpdateCommand.Connection = conn; | ||
1192 | |||
1193 | SqliteCommand delete = new SqliteCommand("delete from users where UUID = :UUID"); | ||
1194 | delete.Parameters.Add(SQLiteUtil.createSqliteParameter("UUID", typeof(String))); | ||
1195 | delete.Connection = conn; | ||
1196 | da.DeleteCommand = delete; | ||
1197 | } | ||
1198 | |||
1199 | private void setupAgentCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
1200 | { | ||
1201 | da.InsertCommand = SQLiteUtil.createInsertCommand("useragents", ds.Tables["useragents"]); | ||
1202 | da.InsertCommand.Connection = conn; | ||
1203 | |||
1204 | da.UpdateCommand = SQLiteUtil.createUpdateCommand("useragents", "UUID=:UUID", ds.Tables["useragents"]); | ||
1205 | da.UpdateCommand.Connection = conn; | ||
1206 | |||
1207 | SqliteCommand delete = new SqliteCommand("delete from useragents where UUID = :ProfileID"); | ||
1208 | delete.Parameters.Add(SQLiteUtil.createSqliteParameter("ProfileID", typeof(String))); | ||
1209 | delete.Connection = conn; | ||
1210 | da.DeleteCommand = delete; | ||
1211 | } | ||
1212 | |||
1213 | /// <summary> | ||
1214 | /// | ||
1215 | /// </summary> | ||
1216 | /// <param name="daf"></param> | ||
1217 | /// <param name="conn"></param> | ||
1218 | private void setupUserFriendsCommands(SqliteDataAdapter daf, SqliteConnection conn) | ||
1219 | { | ||
1220 | daf.InsertCommand = SQLiteUtil.createInsertCommand("userfriends", ds.Tables["userfriends"]); | ||
1221 | daf.InsertCommand.Connection = conn; | ||
1222 | |||
1223 | daf.UpdateCommand = SQLiteUtil.createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]); | ||
1224 | daf.UpdateCommand.Connection = conn; | ||
1225 | |||
1226 | SqliteCommand delete = new SqliteCommand("delete from userfriends where ownerID=:ownerID and friendID=:friendID"); | ||
1227 | delete.Parameters.Add(SQLiteUtil.createSqliteParameter("ownerID", typeof(String))); | ||
1228 | delete.Parameters.Add(SQLiteUtil.createSqliteParameter("friendID", typeof(String))); | ||
1229 | delete.Connection = conn; | ||
1230 | daf.DeleteCommand = delete; | ||
1231 | |||
1232 | } | ||
1233 | |||
1234 | /// <summary> | ||
1235 | /// | ||
1236 | /// </summary> | ||
1237 | /// <param name="daf"></param> | ||
1238 | /// <param name="conn"></param> | ||
1239 | private void setupAvatarAppearanceCommands(SqliteDataAdapter daa, SqliteConnection conn) | ||
1240 | { | ||
1241 | daa.InsertCommand = SQLiteUtil.createInsertCommand("avatarappearance", ds.Tables["avatarappearance"]); | ||
1242 | daa.InsertCommand.Connection = conn; | ||
1243 | |||
1244 | daa.UpdateCommand = SQLiteUtil.createUpdateCommand("avatarappearance", "Owner=:Owner", ds.Tables["avatarappearance"]); | ||
1245 | daa.UpdateCommand.Connection = conn; | ||
1246 | |||
1247 | SqliteCommand delete = new SqliteCommand("delete from avatarappearance where Owner=:Owner"); | ||
1248 | delete.Parameters.Add(SQLiteUtil.createSqliteParameter("Owner", typeof(String))); | ||
1249 | delete.Connection = conn; | ||
1250 | daa.DeleteCommand = delete; | ||
1251 | } | ||
1252 | |||
1253 | |||
1254 | override public void ResetAttachments(UUID userID) | ||
1255 | { | ||
1256 | } | ||
1257 | |||
1258 | override public void LogoutUsers(UUID regionID) | ||
1259 | { | ||
1260 | } | ||
1261 | } | ||
1262 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 5c93f88..a66e0c6 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs | |||
@@ -115,7 +115,7 @@ namespace OpenSim.Data.SQLite | |||
115 | cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); | 115 | cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); |
116 | cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); | 116 | cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); |
117 | 117 | ||
118 | return ExecuteNonQuery(cmd) == 0 ? false : true; | 118 | return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true; |
119 | } | 119 | } |
120 | 120 | ||
121 | public XInventoryItem[] GetActiveGestures(UUID principalID) | 121 | public XInventoryItem[] GetActiveGestures(UUID principalID) |
@@ -137,7 +137,7 @@ namespace OpenSim.Data.SQLite | |||
137 | cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); | 137 | cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); |
138 | cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); | 138 | cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); |
139 | 139 | ||
140 | IDataReader reader = ExecuteReader(cmd); | 140 | IDataReader reader = ExecuteReader(cmd, m_Connection); |
141 | 141 | ||
142 | int perms = 0; | 142 | int perms = 0; |
143 | 143 | ||
@@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLite | |||
147 | } | 147 | } |
148 | 148 | ||
149 | reader.Close(); | 149 | reader.Close(); |
150 | CloseReaderCommand(cmd); | 150 | CloseCommand(cmd); |
151 | 151 | ||
152 | return perms; | 152 | return perms; |
153 | } | 153 | } |
diff --git a/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs b/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs deleted file mode 100644 index c9953c5..0000000 --- a/OpenSim/Data/SQLite/Tests/SQLiteUserTest.cs +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
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.IO; | ||
29 | using NUnit.Framework; | ||
30 | using OpenSim.Data.Tests; | ||
31 | using OpenSim.Tests.Common; | ||
32 | |||
33 | namespace OpenSim.Data.SQLite.Tests | ||
34 | { | ||
35 | [TestFixture, DatabaseTest] | ||
36 | public class SQLiteUserTest : BasicUserTest | ||
37 | { | ||
38 | public string file; | ||
39 | public string connect; | ||
40 | |||
41 | [TestFixtureSetUp] | ||
42 | public void Init() | ||
43 | { | ||
44 | // SQLite doesn't work on power or z linux | ||
45 | if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd")) | ||
46 | { | ||
47 | Assert.Ignore(); | ||
48 | } | ||
49 | |||
50 | SuperInit(); | ||
51 | file = Path.GetTempFileName() + ".db"; | ||
52 | connect = "URI=file:" + file + ",version=3"; | ||
53 | db = new SQLiteUserData(); | ||
54 | db.Initialise(connect); | ||
55 | } | ||
56 | |||
57 | [TestFixtureTearDown] | ||
58 | public void Cleanup() | ||
59 | { | ||
60 | db.Dispose(); | ||
61 | File.Delete(file); | ||
62 | } | ||
63 | } | ||
64 | } | ||