diff options
Diffstat (limited to 'OpenSim/Data/SQLite')
28 files changed, 7568 insertions, 0 deletions
diff --git a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9884f74 --- /dev/null +++ b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs | |||
@@ -0,0 +1,65 @@ | |||
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.Reflection; | ||
29 | using System.Runtime.InteropServices; | ||
30 | |||
31 | // General information about an assembly is controlled through the following | ||
32 | // set of attributes. Change these attribute values to modify the information | ||
33 | // associated with an assembly. | ||
34 | |||
35 | [assembly : AssemblyTitle("OpenSim.Data.SQLite")] | ||
36 | [assembly : AssemblyDescription("")] | ||
37 | [assembly : AssemblyConfiguration("")] | ||
38 | [assembly : AssemblyCompany("http://opensimulator.org")] | ||
39 | [assembly : AssemblyProduct("OpenSim.Data.SQLite")] | ||
40 | [assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] | ||
41 | [assembly : AssemblyTrademark("")] | ||
42 | [assembly : AssemblyCulture("")] | ||
43 | |||
44 | // Setting ComVisible to false makes the types in this assembly not visible | ||
45 | // to COM components. If you need to access a type in this assembly from | ||
46 | // COM, set the ComVisible attribute to true on that type. | ||
47 | |||
48 | [assembly : ComVisible(false)] | ||
49 | |||
50 | // The following GUID is for the ID of the typelib if this project is exposed to COM | ||
51 | |||
52 | [assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")] | ||
53 | |||
54 | // Version information for an assembly consists of the following four values: | ||
55 | // | ||
56 | // Major Version | ||
57 | // Minor Version | ||
58 | // Build Number | ||
59 | // Revision | ||
60 | // | ||
61 | // You can specify all the values or you can default the Revision and Build Numbers | ||
62 | // by using the '*' as shown below: | ||
63 | |||
64 | [assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)] | ||
65 | |||
diff --git a/OpenSim/Data/SQLite/Resources/001_GridUserStore.sql b/OpenSim/Data/SQLite/Resources/001_GridUserStore.sql new file mode 100644 index 0000000..1a24613 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/001_GridUserStore.sql | |||
@@ -0,0 +1,16 @@ | |||
1 | BEGIN TRANSACTION; | ||
2 | |||
3 | CREATE TABLE GridUser ( | ||
4 | UserID VARCHAR(255) primary key, | ||
5 | HomeRegionID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
6 | HomePosition CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
7 | HomeLookAt CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
8 | LastRegionID CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
9 | LastPosition CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
10 | LastLookAt CHAR(64) NOT NULL DEFAULT '<0,0,0>', | ||
11 | Online CHAR(5) NOT NULL DEFAULT 'false', | ||
12 | Login CHAR(16) NOT NULL DEFAULT '0', | ||
13 | Logout CHAR(16) NOT NULL DEFAULT '0' | ||
14 | ) ; | ||
15 | |||
16 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations b/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations new file mode 100644 index 0000000..8c2663e --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/AgentPrefs.migrations | |||
@@ -0,0 +1,36 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE `AgentPrefs` ( | ||
6 | `PrincipalID` CHAR(36) NOT NULL, | ||
7 | `AccessPrefs` CHAR(2) NOT NULL DEFAULT 'M', | ||
8 | `HoverHeight` DOUBLE(30, 27) NOT NULL DEFAULT 0, | ||
9 | `Language` CHAR(5) NOT NULL DEFAULT 'en-us', | ||
10 | `LanguageIsPublic` BOOLEAN NOT NULL DEFAULT 1, | ||
11 | `PermEveryone` INT(6) NOT NULL DEFAULT 0, | ||
12 | `PermGroup` INT(6) NOT NULL DEFAULT 0, | ||
13 | `PermNextOwner` INT(6) NOT NULL DEFAULT 532480, | ||
14 | UNIQUE (`PrincipalID`), | ||
15 | PRIMARY KEY(`PrincipalID`)); | ||
16 | |||
17 | COMMIT; | ||
18 | |||
19 | :VERSION 2 | ||
20 | |||
21 | BEGIN; | ||
22 | |||
23 | CREATE TABLE AgentPrefs( | ||
24 | PrincipalID CHAR(36) NOT NULL, | ||
25 | AccessPrefs CHAR(2) NOT NULL DEFAULT 'M', | ||
26 | HoverHeight DOUBLE(30, 27) NOT NULL DEFAULT 0, | ||
27 | Language CHAR(5) NOT NULL DEFAULT 'en-us', | ||
28 | LanguageIsPublic BOOLEAN NOT NULL DEFAULT 1, | ||
29 | PermEveryone INT(6) NOT NULL DEFAULT 0, | ||
30 | PermGroup INT(6) NOT NULL DEFAULT 0, | ||
31 | PermNextOwner INT(6) NOT NULL DEFAULT 532480, | ||
32 | UNIQUE(PrincipalID), | ||
33 | PRIMARY KEY(PrincipalID) | ||
34 | ); | ||
35 | |||
36 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/AssetStore.migrations b/OpenSim/Data/SQLite/Resources/AssetStore.migrations new file mode 100644 index 0000000..0743c45 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/AssetStore.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | :VERSION 6 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS assets( | ||
6 | UUID NOT NULL PRIMARY KEY, | ||
7 | Name, | ||
8 | Description, | ||
9 | Type, | ||
10 | Local, | ||
11 | Temporary, | ||
12 | asset_flags INTEGER NOT NULL DEFAULT 0, | ||
13 | CreatorID varchar(128) default '', | ||
14 | Data); | ||
15 | |||
16 | COMMIT; | ||
17 | |||
18 | |||
diff --git a/OpenSim/Data/SQLite/Resources/AuthStore.migrations b/OpenSim/Data/SQLite/Resources/AuthStore.migrations new file mode 100644 index 0000000..ca6bdf5 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/AuthStore.migrations | |||
@@ -0,0 +1,29 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE auth ( | ||
6 | UUID char(36) NOT NULL, | ||
7 | passwordHash char(32) NOT NULL default '', | ||
8 | passwordSalt char(32) NOT NULL default '', | ||
9 | webLoginKey varchar(255) NOT NULL default '', | ||
10 | accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount', | ||
11 | PRIMARY KEY (`UUID`) | ||
12 | ); | ||
13 | |||
14 | CREATE TABLE tokens ( | ||
15 | UUID char(36) NOT NULL, | ||
16 | token varchar(255) NOT NULL, | ||
17 | validity datetime NOT NULL | ||
18 | ); | ||
19 | |||
20 | COMMIT; | ||
21 | |||
22 | :VERSION 2 | ||
23 | |||
24 | BEGIN TRANSACTION; | ||
25 | |||
26 | INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users; | ||
27 | |||
28 | COMMIT; | ||
29 | |||
diff --git a/OpenSim/Data/SQLite/Resources/Avatar.migrations b/OpenSim/Data/SQLite/Resources/Avatar.migrations new file mode 100644 index 0000000..13b4196 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/Avatar.migrations | |||
@@ -0,0 +1,11 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE Avatars ( | ||
6 | PrincipalID CHAR(36) NOT NULL, | ||
7 | Name VARCHAR(32) NOT NULL, | ||
8 | Value VARCHAR(255) NOT NULL DEFAULT '', | ||
9 | PRIMARY KEY(PrincipalID, Name)); | ||
10 | |||
11 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/EstateStore.migrations b/OpenSim/Data/SQLite/Resources/EstateStore.migrations new file mode 100644 index 0000000..37fa1d9 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/EstateStore.migrations | |||
@@ -0,0 +1,69 @@ | |||
1 | :VERSION 10 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS estate_groups ( | ||
6 | EstateID int(10) NOT NULL, | ||
7 | uuid char(36) NOT NULL | ||
8 | ); | ||
9 | CREATE INDEX estate_groups_estate_id on estate_groups(EstateID); | ||
10 | |||
11 | CREATE TABLE IF NOT EXISTS estate_managers ( | ||
12 | EstateID int(10) NOT NULL, | ||
13 | uuid char(36) NOT NULL | ||
14 | ); | ||
15 | CREATE INDEX estate_managers_estate_id on estate_managers(EstateID); | ||
16 | |||
17 | CREATE TABLE IF NOT EXISTS estate_map ( | ||
18 | RegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
19 | EstateID int(11) NOT NULL | ||
20 | ); | ||
21 | CREATE INDEX estate_map_estate_id on estate_map(EstateID); | ||
22 | CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID); | ||
23 | |||
24 | CREATE TABLE IF NOT EXISTS estate_settings ( | ||
25 | EstateID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, | ||
26 | EstateName varchar(64) default NULL, | ||
27 | AbuseEmailToEstateOwner tinyint(4) NOT NULL, | ||
28 | DenyAnonymous tinyint(4) NOT NULL, | ||
29 | ResetHomeOnTeleport tinyint(4) NOT NULL, | ||
30 | FixedSun tinyint(4) NOT NULL, | ||
31 | DenyTransacted tinyint(4) NOT NULL, | ||
32 | BlockDwell tinyint(4) NOT NULL, | ||
33 | DenyIdentified tinyint(4) NOT NULL, | ||
34 | AllowVoice tinyint(4) NOT NULL, | ||
35 | UseGlobalTime tinyint(4) NOT NULL, | ||
36 | PricePerMeter int(11) NOT NULL, | ||
37 | TaxFree tinyint(4) NOT NULL, | ||
38 | AllowDirectTeleport tinyint(4) NOT NULL, | ||
39 | RedirectGridX int(11) NOT NULL, | ||
40 | RedirectGridY int(11) NOT NULL, | ||
41 | ParentEstateID int(10) NOT NULL, | ||
42 | SunPosition double NOT NULL, | ||
43 | EstateSkipScripts tinyint(4) NOT NULL, | ||
44 | BillableFactor float NOT NULL, | ||
45 | PublicAccess tinyint(4) NOT NULL, | ||
46 | AbuseEmail varchar(255) not null default '', | ||
47 | EstateOwner varchar(36) not null default '', | ||
48 | DenyMinors tinyint not null default 0, | ||
49 | AllowLandmark tinyint not null default '1', | ||
50 | AllowParcelChanges tinyint not null default '1', | ||
51 | AllowSetHome tinyint not null default '1'); | ||
52 | |||
53 | CREATE TABLE IF NOT EXISTS estate_users ( | ||
54 | EstateID int(10) NOT NULL, | ||
55 | uuid char(36) NOT NULL | ||
56 | ); | ||
57 | CREATE INDEX estate_users_estate_id on estate_users(EstateID); | ||
58 | |||
59 | CREATE TABLE IF NOT EXISTS estateban ( | ||
60 | EstateID int(10) NOT NULL, | ||
61 | bannedUUID varchar(36) NOT NULL, | ||
62 | bannedIp varchar(16) NOT NULL, | ||
63 | bannedIpHostMask varchar(16) NOT NULL, | ||
64 | bannedNameMask varchar(64) default NULL | ||
65 | ); | ||
66 | CREATE INDEX estate_ban_estate_id on estateban(EstateID); | ||
67 | |||
68 | COMMIT; | ||
69 | |||
diff --git a/OpenSim/Data/SQLite/Resources/FriendsStore.migrations b/OpenSim/Data/SQLite/Resources/FriendsStore.migrations new file mode 100644 index 0000000..3eb4352 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/FriendsStore.migrations | |||
@@ -0,0 +1,20 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE `Friends` ( | ||
6 | `PrincipalID` CHAR(36) NOT NULL, | ||
7 | `Friend` VARCHAR(255) NOT NULL, | ||
8 | `Flags` VARCHAR(16) NOT NULL DEFAULT 0, | ||
9 | `Offered` VARCHAR(32) NOT NULL DEFAULT 0, | ||
10 | PRIMARY KEY(`PrincipalID`, `Friend`)); | ||
11 | |||
12 | COMMIT; | ||
13 | |||
14 | :VERSION 2 | ||
15 | |||
16 | BEGIN TRANSACTION; | ||
17 | |||
18 | INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`; | ||
19 | |||
20 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations new file mode 100644 index 0000000..02612ce --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations | |||
@@ -0,0 +1,18 @@ | |||
1 | :VERSION 2 # -------------------------- | ||
2 | |||
3 | BEGIN; | ||
4 | |||
5 | CREATE TABLE hg_traveling_data( | ||
6 | SessionID VARCHAR(36) NOT NULL, | ||
7 | UserID VARCHAR(36) NOT NULL, | ||
8 | GridExternalName VARCHAR(255) NOT NULL DEFAULT "", | ||
9 | ServiceToken VARCHAR(255) NOT NULL DEFAULT "", | ||
10 | ClientIPAddress VARCHAR(16) NOT NULL DEFAULT "", | ||
11 | MyIPAddress VARCHAR(16) NOT NULL DEFAULT "", | ||
12 | TMStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
13 | PRIMARY KEY(SessionID), | ||
14 | UNIQUE(UserID) | ||
15 | ); | ||
16 | |||
17 | COMMIT; | ||
18 | |||
diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations new file mode 100644 index 0000000..fb154cf --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations | |||
@@ -0,0 +1,379 @@ | |||
1 | :VERSION 31 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS prims( | ||
6 | UUID varchar(255) primary key, | ||
7 | RegionUUID varchar(255), | ||
8 | CreationDate integer, | ||
9 | Name varchar(255), | ||
10 | SceneGroupID varchar(255), | ||
11 | Text varchar(255), | ||
12 | Description varchar(255), | ||
13 | SitName varchar(255), | ||
14 | TouchName varchar(255), | ||
15 | CreatorID varchar(255), | ||
16 | OwnerID varchar(255), | ||
17 | GroupID varchar(255), | ||
18 | LastOwnerID varchar(255), | ||
19 | OwnerMask integer, | ||
20 | NextOwnerMask integer, | ||
21 | GroupMask integer, | ||
22 | EveryoneMask integer, | ||
23 | BaseMask integer, | ||
24 | PositionX float, | ||
25 | PositionY float, | ||
26 | PositionZ float, | ||
27 | GroupPositionX float, | ||
28 | GroupPositionY float, | ||
29 | GroupPositionZ float, | ||
30 | VelocityX float, | ||
31 | VelocityY float, | ||
32 | VelocityZ float, | ||
33 | AngularVelocityX float, | ||
34 | AngularVelocityY float, | ||
35 | AngularVelocityZ float, | ||
36 | AccelerationX float, | ||
37 | AccelerationY float, | ||
38 | AccelerationZ float, | ||
39 | RotationX float, | ||
40 | RotationY float, | ||
41 | RotationZ float, | ||
42 | RotationW float, | ||
43 | ObjectFlags integer, | ||
44 | SitTargetOffsetX float NOT NULL default 0, | ||
45 | SitTargetOffsetY float NOT NULL default 0, | ||
46 | SitTargetOffsetZ float NOT NULL default 0, | ||
47 | SitTargetOrientW float NOT NULL default 0, | ||
48 | SitTargetOrientX float NOT NULL default 0, | ||
49 | SitTargetOrientY float NOT NULL default 0, | ||
50 | SitTargetOrientZ float NOT NULL default 0, | ||
51 | ColorR integer not null default 0, | ||
52 | ColorG integer not null default 0, | ||
53 | ColorB integer not null default 0, | ||
54 | ColorA integer not null default 0, | ||
55 | ClickAction integer not null default 0, | ||
56 | PayPrice integer not null default 0, | ||
57 | PayButton1 integer not null default 0, | ||
58 | PayButton2 integer not null default 0, | ||
59 | PayButton3 integer not null default 0, | ||
60 | PayButton4 integer not null default 0, | ||
61 | LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
62 | LoopedSoundGain float NOT NULL default 0, | ||
63 | TextureAnimation string, | ||
64 | ParticleSystem string, | ||
65 | OmegaX float NOT NULL default 0, | ||
66 | OmegaY float NOT NULL default 0, | ||
67 | OmegaZ float NOT NULL default 0, | ||
68 | CameraEyeOffsetX float NOT NULL default 0, | ||
69 | CameraEyeOffsetY float NOT NULL default 0, | ||
70 | CameraEyeOffsetZ float NOT NULL default 0, | ||
71 | CameraAtOffsetX float NOT NULL default 0, | ||
72 | CameraAtOffsetY float NOT NULL default 0, | ||
73 | CameraAtOffsetZ float NOT NULL default 0, | ||
74 | ForceMouselook string NOT NULL default 0, | ||
75 | ScriptAccessPin INTEGER NOT NULL default 0, | ||
76 | AllowedDrop INTEGER NOT NULL default 0, | ||
77 | DieAtEdge string NOT NULL default 0, | ||
78 | SalePrice INTEGER NOT NULL default 0, | ||
79 | SaleType string NOT NULL default 0, | ||
80 | Material INTEGER NOT NULL default 3, | ||
81 | CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
82 | CollisionSoundVolume float NOT NULL default 0, | ||
83 | VolumeDetect INTEGER NOT NULL DEFAULT 0, | ||
84 | MediaURL varchar(255), | ||
85 | DynAttrs TEXT, | ||
86 | `PhysicsShapeType` tinyint(4) NOT NULL default '0', | ||
87 | `Density` double NOT NULL default '1000', | ||
88 | `GravityModifier` double NOT NULL default '1', | ||
89 | `Friction` double NOT NULL default '0.6', | ||
90 | `Restitution` double NOT NULL default '0.5', | ||
91 | `KeyframeMotion` blob, | ||
92 | AttachedPosX double default '0', | ||
93 | AttachedPosY double default '0', | ||
94 | AttachedPosZ double default '0'); | ||
95 | |||
96 | CREATE TABLE IF NOT EXISTS primshapes( | ||
97 | UUID varchar(255) primary key, | ||
98 | Shape integer, | ||
99 | ScaleX float, | ||
100 | ScaleY float, | ||
101 | ScaleZ float, | ||
102 | PCode integer, | ||
103 | PathBegin integer, | ||
104 | PathEnd integer, | ||
105 | PathScaleX integer, | ||
106 | PathScaleY integer, | ||
107 | PathShearX integer, | ||
108 | PathShearY integer, | ||
109 | PathSkew integer, | ||
110 | PathCurve integer, | ||
111 | PathRadiusOffset integer, | ||
112 | PathRevolutions integer, | ||
113 | PathTaperX integer, | ||
114 | PathTaperY integer, | ||
115 | PathTwist integer, | ||
116 | PathTwistBegin integer, | ||
117 | ProfileBegin integer, | ||
118 | ProfileEnd integer, | ||
119 | ProfileCurve integer, | ||
120 | ProfileHollow integer, | ||
121 | Texture blob, | ||
122 | ExtraParams blob, | ||
123 | State Integer NOT NULL default 0, | ||
124 | Media TEXT, | ||
125 | LastAttachPoint int not null default '0'); | ||
126 | |||
127 | CREATE TABLE IF NOT EXISTS primitems( | ||
128 | itemID varchar(255) primary key, | ||
129 | primID varchar(255), | ||
130 | assetID varchar(255), | ||
131 | parentFolderID varchar(255), | ||
132 | invType integer, | ||
133 | assetType integer, | ||
134 | name varchar(255), | ||
135 | description varchar(255), | ||
136 | creationDate integer, | ||
137 | creatorID varchar(255), | ||
138 | ownerID varchar(255), | ||
139 | lastOwnerID varchar(255), | ||
140 | groupID varchar(255), | ||
141 | nextPermissions string, | ||
142 | currentPermissions string, | ||
143 | basePermissions string, | ||
144 | everyonePermissions string, | ||
145 | groupPermissions string, | ||
146 | flags integer not null default 0); | ||
147 | |||
148 | CREATE TABLE IF NOT EXISTS terrain( | ||
149 | RegionUUID varchar(255), | ||
150 | Revision integer, | ||
151 | Heightfield blob); | ||
152 | |||
153 | CREATE TABLE IF NOT EXISTS land( | ||
154 | UUID varchar(255) primary key, | ||
155 | RegionUUID varchar(255), | ||
156 | LocalLandID string, | ||
157 | Bitmap blob, | ||
158 | Name varchar(255), | ||
159 | Desc varchar(255), | ||
160 | OwnerUUID varchar(255), | ||
161 | IsGroupOwned string, | ||
162 | Area integer, | ||
163 | AuctionID integer, | ||
164 | Category integer, | ||
165 | ClaimDate integer, | ||
166 | ClaimPrice integer, | ||
167 | GroupUUID varchar(255), | ||
168 | SalePrice integer, | ||
169 | LandStatus integer, | ||
170 | LandFlags string, | ||
171 | LandingType string, | ||
172 | MediaAutoScale string, | ||
173 | MediaTextureUUID varchar(255), | ||
174 | MediaURL varchar(255), | ||
175 | MusicURL varchar(255), | ||
176 | PassHours float, | ||
177 | PassPrice string, | ||
178 | SnapshotUUID varchar(255), | ||
179 | UserLocationX float, | ||
180 | UserLocationY float, | ||
181 | UserLocationZ float, | ||
182 | UserLookAtX float, | ||
183 | UserLookAtY float, | ||
184 | UserLookAtZ float, | ||
185 | AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
186 | OtherCleanTime INTEGER NOT NULL default 0, | ||
187 | Dwell INTEGER NOT NULL default 0, | ||
188 | `MediaType` VARCHAR(32) NOT NULL DEFAULT 'none/none', | ||
189 | `MediaDescription` VARCHAR(255) NOT NULL DEFAULT '', | ||
190 | `MediaSize` VARCHAR(16) NOT NULL DEFAULT '0,0', | ||
191 | `MediaLoop` BOOLEAN NOT NULL DEFAULT FALSE, | ||
192 | `ObscureMusic` BOOLEAN NOT NULL DEFAULT FALSE, | ||
193 | `ObscureMedia` BOOLEAN NOT NULL DEFAULT FALSE); | ||
194 | |||
195 | CREATE TABLE IF NOT EXISTS landaccesslist( | ||
196 | LandUUID varchar(255), | ||
197 | AccessUUID varchar(255), | ||
198 | Flags string); | ||
199 | |||
200 | CREATE TABLE IF NOT EXISTS regionban( | ||
201 | regionUUID varchar (255), | ||
202 | bannedUUID varchar (255), | ||
203 | bannedIp varchar (255), | ||
204 | bannedIpHostMask varchar (255) | ||
205 | ); | ||
206 | |||
207 | CREATE TABLE IF NOT EXISTS regionsettings ( | ||
208 | regionUUID char(36) NOT NULL, | ||
209 | block_terraform int(11) NOT NULL, | ||
210 | block_fly int(11) NOT NULL, | ||
211 | allow_damage int(11) NOT NULL, | ||
212 | restrict_pushing int(11) NOT NULL, | ||
213 | allow_land_resell int(11) NOT NULL, | ||
214 | allow_land_join_divide int(11) NOT NULL, | ||
215 | block_show_in_search int(11) NOT NULL, | ||
216 | agent_limit int(11) NOT NULL, | ||
217 | object_bonus float NOT NULL, | ||
218 | maturity int(11) NOT NULL, | ||
219 | disable_scripts int(11) NOT NULL, | ||
220 | disable_collisions int(11) NOT NULL, | ||
221 | disable_physics int(11) NOT NULL, | ||
222 | terrain_texture_1 char(36) NOT NULL, | ||
223 | terrain_texture_2 char(36) NOT NULL, | ||
224 | terrain_texture_3 char(36) NOT NULL, | ||
225 | terrain_texture_4 char(36) NOT NULL, | ||
226 | elevation_1_nw float NOT NULL, | ||
227 | elevation_2_nw float NOT NULL, | ||
228 | elevation_1_ne float NOT NULL, | ||
229 | elevation_2_ne float NOT NULL, | ||
230 | elevation_1_se float NOT NULL, | ||
231 | elevation_2_se float NOT NULL, | ||
232 | elevation_1_sw float NOT NULL, | ||
233 | elevation_2_sw float NOT NULL, | ||
234 | water_height float NOT NULL, | ||
235 | terrain_raise_limit float NOT NULL, | ||
236 | terrain_lower_limit float NOT NULL, | ||
237 | use_estate_sun int(11) NOT NULL, | ||
238 | fixed_sun int(11) NOT NULL, | ||
239 | sun_position float NOT NULL, | ||
240 | covenant char(36) default NULL, | ||
241 | sandbox tinyint(4) NOT NULL, | ||
242 | sunvectorx double NOT NULL default 0, | ||
243 | sunvectory double NOT NULL default 0, | ||
244 | sunvectorz double NOT NULL default 0, | ||
245 | map_tile_ID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000', | ||
246 | covenant_datetime INTEGER NOT NULL default 0, | ||
247 | `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
248 | `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', | ||
249 | PRIMARY KEY (regionUUID) | ||
250 | ); | ||
251 | |||
252 | CREATE TABLE IF NOT EXISTS regionwindlight ( | ||
253 | region_id VARCHAR(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, | ||
254 | water_color_r FLOAT NOT NULL DEFAULT '4.000000', | ||
255 | water_color_g FLOAT NOT NULL DEFAULT '38.000000', | ||
256 | water_color_b FLOAT NOT NULL DEFAULT '64.000000', | ||
257 | water_color_i FLOAT NOT NULL DEFAULT '1.000000', | ||
258 | water_fog_density_exponent FLOAT NOT NULL DEFAULT '4.0', | ||
259 | underwater_fog_modifier FLOAT NOT NULL DEFAULT '0.25', | ||
260 | reflection_wavelet_scale_1 FLOAT NOT NULL DEFAULT '2.0', | ||
261 | reflection_wavelet_scale_2 FLOAT NOT NULL DEFAULT '2.0', | ||
262 | reflection_wavelet_scale_3 FLOAT NOT NULL DEFAULT '2.0', | ||
263 | fresnel_scale FLOAT NOT NULL DEFAULT '0.40', | ||
264 | fresnel_offset FLOAT NOT NULL DEFAULT '0.50', | ||
265 | refract_scale_above FLOAT NOT NULL DEFAULT '0.03', | ||
266 | refract_scale_below FLOAT NOT NULL DEFAULT '0.20', | ||
267 | blur_multiplier FLOAT NOT NULL DEFAULT '0.040', | ||
268 | big_wave_direction_x FLOAT NOT NULL DEFAULT '1.05', | ||
269 | big_wave_direction_y FLOAT NOT NULL DEFAULT '-0.42', | ||
270 | little_wave_direction_x FLOAT NOT NULL DEFAULT '1.11', | ||
271 | little_wave_direction_y FLOAT NOT NULL DEFAULT '-1.16', | ||
272 | normal_map_texture VARCHAR(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4', | ||
273 | horizon_r FLOAT NOT NULL DEFAULT '0.25', | ||
274 | horizon_g FLOAT NOT NULL DEFAULT '0.25', | ||
275 | horizon_b FLOAT NOT NULL DEFAULT '0.32', | ||
276 | horizon_i FLOAT NOT NULL DEFAULT '0.32', | ||
277 | haze_horizon FLOAT NOT NULL DEFAULT '0.19', | ||
278 | blue_density_r FLOAT NOT NULL DEFAULT '0.12', | ||
279 | blue_density_g FLOAT NOT NULL DEFAULT '0.22', | ||
280 | blue_density_b FLOAT NOT NULL DEFAULT '0.38', | ||
281 | blue_density_i FLOAT NOT NULL DEFAULT '0.38', | ||
282 | haze_density FLOAT NOT NULL DEFAULT '0.70', | ||
283 | density_multiplier FLOAT NOT NULL DEFAULT '0.18', | ||
284 | distance_multiplier FLOAT NOT NULL DEFAULT '0.8', | ||
285 | max_altitude INTEGER NOT NULL DEFAULT '1605', | ||
286 | sun_moon_color_r FLOAT NOT NULL DEFAULT '0.24', | ||
287 | sun_moon_color_g FLOAT NOT NULL DEFAULT '0.26', | ||
288 | sun_moon_color_b FLOAT NOT NULL DEFAULT '0.30', | ||
289 | sun_moon_color_i FLOAT NOT NULL DEFAULT '0.30', | ||
290 | sun_moon_position FLOAT NOT NULL DEFAULT '0.317', | ||
291 | ambient_r FLOAT NOT NULL DEFAULT '0.35', | ||
292 | ambient_g FLOAT NOT NULL DEFAULT '0.35', | ||
293 | ambient_b FLOAT NOT NULL DEFAULT '0.35', | ||
294 | ambient_i FLOAT NOT NULL DEFAULT '0.35', | ||
295 | east_angle FLOAT NOT NULL DEFAULT '0.00', | ||
296 | sun_glow_focus FLOAT NOT NULL DEFAULT '0.10', | ||
297 | sun_glow_size FLOAT NOT NULL DEFAULT '1.75', | ||
298 | scene_gamma FLOAT NOT NULL DEFAULT '1.00', | ||
299 | star_brightness FLOAT NOT NULL DEFAULT '0.00', | ||
300 | cloud_color_r FLOAT NOT NULL DEFAULT '0.41', | ||
301 | cloud_color_g FLOAT NOT NULL DEFAULT '0.41', | ||
302 | cloud_color_b FLOAT NOT NULL DEFAULT '0.41', | ||
303 | cloud_color_i FLOAT NOT NULL DEFAULT '0.41', | ||
304 | cloud_x FLOAT NOT NULL DEFAULT '1.00', | ||
305 | cloud_y FLOAT NOT NULL DEFAULT '0.53', | ||
306 | cloud_density FLOAT NOT NULL DEFAULT '1.00', | ||
307 | cloud_coverage FLOAT NOT NULL DEFAULT '0.27', | ||
308 | cloud_scale FLOAT NOT NULL DEFAULT '0.42', | ||
309 | cloud_detail_x FLOAT NOT NULL DEFAULT '1.00', | ||
310 | cloud_detail_y FLOAT NOT NULL DEFAULT '0.53', | ||
311 | cloud_detail_density FLOAT NOT NULL DEFAULT '0.12', | ||
312 | cloud_scroll_x FLOAT NOT NULL DEFAULT '0.20', | ||
313 | cloud_scroll_x_lock INTEGER NOT NULL DEFAULT '0', | ||
314 | cloud_scroll_y FLOAT NOT NULL DEFAULT '0.01', | ||
315 | cloud_scroll_y_lock INTEGER NOT NULL DEFAULT '0', | ||
316 | draw_classic_clouds INTEGER NOT NULL DEFAULT '1'); | ||
317 | |||
318 | CREATE TABLE IF NOT EXISTS `spawn_points` ( | ||
319 | `RegionID` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', | ||
320 | `Yaw` float NOT NULL, | ||
321 | `Pitch` float NOT NULL, | ||
322 | `Distance` float NOT NULL | ||
323 | ); | ||
324 | |||
325 | CREATE TABLE IF NOT EXISTS `regionenvironment` ( | ||
326 | `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY, | ||
327 | `llsd_settings` TEXT NOT NULL | ||
328 | ); | ||
329 | |||
330 | COMMIT; | ||
331 | |||
332 | |||
333 | :VERSION 32 #---- avination fields plus a few others | ||
334 | |||
335 | BEGIN; | ||
336 | |||
337 | ALTER TABLE `prims` ADD COLUMN `PassTouches` BOOLEAN NOT NULL DEFAULT FALSE; | ||
338 | ALTER TABLE `prims` ADD COLUMN `PassCollisions`BOOLEAN NOT NULL DEFAULT FALSE; | ||
339 | ALTER TABLE `prims` ADD COLUMN `Vehicle` TEXT default NULL; | ||
340 | ALTER TABLE `regionsettings` ADD COLUMN `block_search` BOOLEAN NOT NULL DEFAULT FALSE;; | ||
341 | ALTER TABLE `regionsettings` ADD COLUMN `casino` BOOLEAN NOT NULL DEFAULT FALSE;; | ||
342 | ALTER TABLE `land` ADD COLUMN `SeeAVs` BOOLEAN NOT NULL DEFAULT TRUE; | ||
343 | ALTER TABLE `land` ADD COLUMN `AnyAVSounds` BOOLEAN NOT NULL DEFAULT TRUE; | ||
344 | ALTER TABLE `land` ADD COLUMN `GroupAVSounds` BOOLEAN NOT NULL DEFAULT TRUE; | ||
345 | |||
346 | COMMIT; | ||
347 | |||
348 | :VERSION 33 #---- Rotation axis locks | ||
349 | |||
350 | BEGIN; | ||
351 | |||
352 | ALTER TABLE prims ADD COLUMN `RotationAxisLocks` tinyint(4) NOT NULL default '0'; | ||
353 | |||
354 | COMMIT; | ||
355 | |||
356 | :VERSION 34 #---- add baked terrain store | ||
357 | |||
358 | BEGIN; | ||
359 | |||
360 | CREATE TABLE IF NOT EXISTS bakedterrain( | ||
361 | RegionUUID varchar(255), | ||
362 | Revision integer, | ||
363 | Heightfield blob); | ||
364 | |||
365 | COMMIT; | ||
366 | |||
367 | :VERSION 35 #----- Add RezzerID field in table prims | ||
368 | |||
369 | BEGIN; | ||
370 | |||
371 | ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; | ||
372 | |||
373 | COMMIT; | ||
374 | |||
375 | :VERSION 36 #----- Add physics inertia data | ||
376 | |||
377 | BEGIN; | ||
378 | ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; | ||
379 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/Resources/UserAccount.migrations b/OpenSim/Data/SQLite/Resources/UserAccount.migrations new file mode 100644 index 0000000..f37a222 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/UserAccount.migrations | |||
@@ -0,0 +1,35 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | -- useraccounts table | ||
6 | CREATE TABLE UserAccounts ( | ||
7 | PrincipalID CHAR(36) primary key, | ||
8 | ScopeID CHAR(36) NOT NULL, | ||
9 | FirstName VARCHAR(64) NOT NULL, | ||
10 | LastName VARCHAR(64) NOT NULL, | ||
11 | Email VARCHAR(64), | ||
12 | ServiceURLs TEXT, | ||
13 | Created INT(11), | ||
14 | UserLevel integer NOT NULL DEFAULT 0, | ||
15 | UserFlags integer NOT NULL DEFAULT 0, | ||
16 | UserTitle varchar(64) NOT NULL DEFAULT '' | ||
17 | ); | ||
18 | |||
19 | COMMIT; | ||
20 | |||
21 | :VERSION 2 | ||
22 | |||
23 | BEGIN TRANSACTION; | ||
24 | |||
25 | 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; | ||
26 | |||
27 | COMMIT; | ||
28 | |||
29 | :VERSION 3 # ------------------------- | ||
30 | |||
31 | BEGIN; | ||
32 | |||
33 | ALTER TABLE `UserAccounts` ADD `active` BOOLEAN NOT NULL DEFAULT TRUE; | ||
34 | |||
35 | COMMIT; \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/Resources/UserProfiles.migrations b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations new file mode 100644 index 0000000..207dde0 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/UserProfiles.migrations | |||
@@ -0,0 +1,102 @@ | |||
1 | :VERSION 1 # ------------------------------- | ||
2 | |||
3 | begin; | ||
4 | |||
5 | CREATE TABLE IF NOT EXISTS classifieds ( | ||
6 | classifieduuid char(36) NOT NULL PRIMARY KEY, | ||
7 | creatoruuid char(36) NOT NULL, | ||
8 | creationdate int(20) NOT NULL, | ||
9 | expirationdate int(20) NOT NULL, | ||
10 | category varchar(20) NOT NULL, | ||
11 | name varchar(255) NOT NULL, | ||
12 | description text NOT NULL, | ||
13 | parceluuid char(36) NOT NULL, | ||
14 | parentestate int(11) NOT NULL, | ||
15 | snapshotuuid char(36) NOT NULL, | ||
16 | simname varchar(255) NOT NULL, | ||
17 | posglobal varchar(255) NOT NULL, | ||
18 | parcelname varchar(255) NOT NULL, | ||
19 | classifiedflags int(8) NOT NULL, | ||
20 | priceforlisting int(5) NOT NULL | ||
21 | ); | ||
22 | |||
23 | commit; | ||
24 | |||
25 | begin; | ||
26 | |||
27 | CREATE TABLE IF NOT EXISTS usernotes ( | ||
28 | useruuid varchar(36) NOT NULL, | ||
29 | targetuuid varchar(36) NOT NULL, | ||
30 | notes text NOT NULL, | ||
31 | UNIQUE (useruuid,targetuuid) ON CONFLICT REPLACE | ||
32 | ); | ||
33 | |||
34 | commit; | ||
35 | |||
36 | begin; | ||
37 | |||
38 | CREATE TABLE IF NOT EXISTS userpicks ( | ||
39 | pickuuid varchar(36) NOT NULL PRIMARY KEY, | ||
40 | creatoruuid varchar(36) NOT NULL, | ||
41 | toppick int NOT NULL, | ||
42 | parceluuid varchar(36) NOT NULL, | ||
43 | name varchar(255) NOT NULL, | ||
44 | description text NOT NULL, | ||
45 | snapshotuuid varchar(36) NOT NULL, | ||
46 | user varchar(255) NOT NULL, | ||
47 | originalname varchar(255) NOT NULL, | ||
48 | simname varchar(255) NOT NULL, | ||
49 | posglobal varchar(255) NOT NULL, | ||
50 | sortorder int(2) NOT NULL, | ||
51 | enabled int NOT NULL | ||
52 | ); | ||
53 | |||
54 | commit; | ||
55 | |||
56 | begin; | ||
57 | |||
58 | CREATE TABLE IF NOT EXISTS userprofile ( | ||
59 | useruuid varchar(36) NOT NULL PRIMARY KEY, | ||
60 | profilePartner varchar(36) NOT NULL, | ||
61 | profileAllowPublish binary(1) NOT NULL, | ||
62 | profileMaturePublish binary(1) NOT NULL, | ||
63 | profileURL varchar(255) NOT NULL, | ||
64 | profileWantToMask int(3) NOT NULL, | ||
65 | profileWantToText text NOT NULL, | ||
66 | profileSkillsMask int(3) NOT NULL, | ||
67 | profileSkillsText text NOT NULL, | ||
68 | profileLanguages text NOT NULL, | ||
69 | profileImage varchar(36) NOT NULL, | ||
70 | profileAboutText text NOT NULL, | ||
71 | profileFirstImage varchar(36) NOT NULL, | ||
72 | profileFirstText text NOT NULL | ||
73 | ); | ||
74 | |||
75 | commit; | ||
76 | |||
77 | :VERSION 2 # ------------------------------- | ||
78 | |||
79 | begin; | ||
80 | |||
81 | CREATE TABLE IF NOT EXISTS userdata ( | ||
82 | UserId char(36) NOT NULL, | ||
83 | TagId varchar(64) NOT NULL, | ||
84 | DataKey varchar(255), | ||
85 | DataVal varchar(255), | ||
86 | PRIMARY KEY (UserId,TagId) | ||
87 | ); | ||
88 | |||
89 | commit; | ||
90 | |||
91 | |||
92 | :VERSION 3 # ------------------------------- | ||
93 | |||
94 | begin; | ||
95 | CREATE TABLE IF NOT EXISTS usersettings ( | ||
96 | useruuid char(36) NOT NULL, | ||
97 | imviaemail binary(1) NOT NULL, | ||
98 | visible binary(1) NOT NULL, | ||
99 | email varchar(254) NOT NULL, | ||
100 | PRIMARY KEY (useruuid) | ||
101 | ) | ||
102 | commit; | ||
diff --git a/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations b/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations new file mode 100644 index 0000000..de44982 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/XInventoryStore.migrations | |||
@@ -0,0 +1,49 @@ | |||
1 | :VERSION 1 | ||
2 | |||
3 | BEGIN TRANSACTION; | ||
4 | |||
5 | CREATE TABLE inventoryfolders( | ||
6 | folderName varchar(64), | ||
7 | type integer, | ||
8 | version integer, | ||
9 | folderID varchar(36) primary key, | ||
10 | agentID varchar(36) not null default '00000000-0000-0000-0000-000000000000', | ||
11 | parentFolderID varchar(36) not null default '00000000-0000-0000-0000-000000000000'); | ||
12 | |||
13 | CREATE TABLE inventoryitems( | ||
14 | assetID varchar(36), | ||
15 | assetType integer, | ||
16 | inventoryName varchar(64), | ||
17 | inventoryDescription varchar(128), | ||
18 | inventoryNextPermissions integer, | ||
19 | inventoryCurrentPermissions integer, | ||
20 | invType integer, | ||
21 | creatorID varchar(128), | ||
22 | inventoryBasePermissions integer, | ||
23 | inventoryEveryOnePermissions integer, | ||
24 | salePrice integer default 99, | ||
25 | saleType integer default 0, | ||
26 | creationDate integer default 2000, | ||
27 | groupID varchar(36) default '00000000-0000-0000-0000-000000000000', | ||
28 | groupOwned integer default 0, | ||
29 | flags integer default 0, | ||
30 | inventoryID varchar(36) primary key, | ||
31 | parentFolderID varchar(36) not null default '00000000-0000-0000-0000-000000000000', | ||
32 | avatarID varchar(36) not null default '00000000-0000-0000-0000-000000000000', | ||
33 | inventoryGroupPermissions integer not null default 0); | ||
34 | |||
35 | create index inventoryfolders_agentid on inventoryfolders(agentID); | ||
36 | create index inventoryfolders_parentid on inventoryfolders(parentFolderID); | ||
37 | create index inventoryitems_parentfolderid on inventoryitems(parentFolderID); | ||
38 | create index inventoryitems_avatarid on inventoryitems(avatarID); | ||
39 | |||
40 | COMMIT; | ||
41 | |||
42 | :VERSION 2 | ||
43 | |||
44 | BEGIN TRANSACTION; | ||
45 | |||
46 | INSERT INTO inventoryfolders (folderName, type, version, folderID, agentID, parentFolderID) SELECT `name` AS folderName, `type` AS type, `version` AS version, `UUID` AS folderID, `agentID` AS agentID, `parentID` AS parentFolderID from old.inventoryfolders; | ||
47 | INSERT INTO inventoryitems (assetID, assetType, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, salePrice, saleType, creationDate, groupID, groupOwned, flags, inventoryID, parentFolderID, avatarID, inventoryGroupPermissions) SELECT `assetID`, `assetType` AS assetType, `inventoryName` AS inventoryName, `inventoryDescription` AS inventoryDescription, `inventoryNextPermissions` AS inventoryNextPermissions, `inventoryCurrentPermissions` AS inventoryCurrentPermissions, `invType` AS invType, `creatorsID` AS creatorID, `inventoryBasePermissions` AS inventoryBasePermissions, `inventoryEveryOnePermissions` AS inventoryEveryOnePermissions, `salePrice` AS salePrice, `saleType` AS saleType, `creationDate` AS creationDate, `groupID` AS groupID, `groupOwned` AS groupOwned, `flags` AS flags, `UUID` AS inventoryID, `parentFolderID` AS parentFolderID, `avatarID` AS avatarID, `inventoryGroupPermissions` AS inventoryGroupPermissions FROM old.inventoryitems; | ||
48 | |||
49 | COMMIT; | ||
diff --git a/OpenSim/Data/SQLite/SQLiteAgentPreferencesData.cs b/OpenSim/Data/SQLite/SQLiteAgentPreferencesData.cs new file mode 100644 index 0000000..d22393d --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteAgentPreferencesData.cs | |||
@@ -0,0 +1,60 @@ | |||
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 | #if CSharpSqlite | ||
35 | using Community.CsharpSqlite.Sqlite; | ||
36 | #else | ||
37 | using Mono.Data.Sqlite; | ||
38 | #endif | ||
39 | |||
40 | namespace OpenSim.Data.SQLite | ||
41 | { | ||
42 | public class SQLiteAgentPreferencesData : SQLiteGenericTableHandler<AgentPreferencesData>, IAgentPreferencesData | ||
43 | { | ||
44 | public SQLiteAgentPreferencesData(string connectionString, string realm) | ||
45 | : base(connectionString, realm, "AgentPrefs") | ||
46 | { | ||
47 | } | ||
48 | |||
49 | public AgentPreferencesData GetPrefs(UUID agentID) | ||
50 | { | ||
51 | AgentPreferencesData[] ret = Get("PrincipalID", agentID.ToString()); | ||
52 | |||
53 | if (ret.Length == 0) | ||
54 | return null; | ||
55 | |||
56 | return ret[0]; | ||
57 | } | ||
58 | |||
59 | } | ||
60 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs new file mode 100644 index 0000000..51d1030 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs | |||
@@ -0,0 +1,406 @@ | |||
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.Data; | ||
30 | using System.Reflection; | ||
31 | using System.Collections.Generic; | ||
32 | using log4net; | ||
33 | #if CSharpSqlite | ||
34 | using Community.CsharpSqlite.Sqlite; | ||
35 | #else | ||
36 | using Mono.Data.Sqlite; | ||
37 | #endif | ||
38 | |||
39 | using OpenMetaverse; | ||
40 | using OpenSim.Framework; | ||
41 | |||
42 | namespace OpenSim.Data.SQLite | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// An asset storage interface for the SQLite database system | ||
46 | /// </summary> | ||
47 | public class SQLiteAssetData : AssetDataBase | ||
48 | { | ||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | private const string SelectAssetSQL = "select * from assets where UUID=:UUID"; | ||
52 | private const string SelectAssetMetadataSQL = "select Name, Description, Type, Temporary, asset_flags, UUID, CreatorID from assets limit :start, :count"; | ||
53 | private const string DeleteAssetSQL = "delete from assets where UUID=:UUID"; | ||
54 | private const string InsertAssetSQL = "insert into assets(UUID, Name, Description, Type, Local, Temporary, asset_flags, CreatorID, Data) values(:UUID, :Name, :Description, :Type, :Local, :Temporary, :Flags, :CreatorID, :Data)"; | ||
55 | private const string UpdateAssetSQL = "update assets set Name=:Name, Description=:Description, Type=:Type, Local=:Local, Temporary=:Temporary, asset_flags=:Flags, CreatorID=:CreatorID, Data=:Data where UUID=:UUID"; | ||
56 | private const string assetSelect = "select * from assets"; | ||
57 | |||
58 | private SqliteConnection m_conn; | ||
59 | |||
60 | protected virtual Assembly Assembly | ||
61 | { | ||
62 | get { return GetType().Assembly; } | ||
63 | } | ||
64 | |||
65 | override public void Dispose() | ||
66 | { | ||
67 | if (m_conn != null) | ||
68 | { | ||
69 | m_conn.Close(); | ||
70 | m_conn = null; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// <list type="bullet"> | ||
76 | /// <item>Initialises AssetData interface</item> | ||
77 | /// <item>Loads and initialises a new SQLite connection and maintains it.</item> | ||
78 | /// <item>use default URI if connect string is empty.</item> | ||
79 | /// </list> | ||
80 | /// </summary> | ||
81 | /// <param name="dbconnect">connect string</param> | ||
82 | override public void Initialise(string dbconnect) | ||
83 | { | ||
84 | if (Util.IsWindows()) | ||
85 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
86 | |||
87 | if (dbconnect == string.Empty) | ||
88 | { | ||
89 | dbconnect = "URI=file:" + Util.dbDir() + "Asset.db,version=3"; | ||
90 | } | ||
91 | m_conn = new SqliteConnection(dbconnect); | ||
92 | m_conn.Open(); | ||
93 | |||
94 | Migration m = new Migration(m_conn, Assembly, "AssetStore"); | ||
95 | m.Update(); | ||
96 | |||
97 | return; | ||
98 | } | ||
99 | |||
100 | /// <summary> | ||
101 | /// Fetch Asset | ||
102 | /// </summary> | ||
103 | /// <param name="uuid">UUID of ... ?</param> | ||
104 | /// <returns>Asset base</returns> | ||
105 | override public AssetBase GetAsset(UUID uuid) | ||
106 | { | ||
107 | lock (this) | ||
108 | { | ||
109 | using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn)) | ||
110 | { | ||
111 | cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString())); | ||
112 | using (IDataReader reader = cmd.ExecuteReader()) | ||
113 | { | ||
114 | if (reader.Read()) | ||
115 | { | ||
116 | AssetBase asset = buildAsset(reader); | ||
117 | reader.Close(); | ||
118 | return asset; | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | reader.Close(); | ||
123 | return null; | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | |||
130 | /// <summary> | ||
131 | /// Create an asset | ||
132 | /// </summary> | ||
133 | /// <param name="asset">Asset Base</param> | ||
134 | override public bool StoreAsset(AssetBase asset) | ||
135 | { | ||
136 | string assetName = asset.Name; | ||
137 | if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) | ||
138 | { | ||
139 | assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); | ||
140 | m_log.WarnFormat( | ||
141 | "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
142 | asset.Name, asset.ID, asset.Name.Length, assetName.Length); | ||
143 | } | ||
144 | |||
145 | string assetDescription = asset.Description; | ||
146 | if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) | ||
147 | { | ||
148 | assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); | ||
149 | m_log.WarnFormat( | ||
150 | "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", | ||
151 | asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); | ||
152 | } | ||
153 | |||
154 | //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString()); | ||
155 | if (AssetsExist(new[] { asset.FullID })[0]) | ||
156 | { | ||
157 | //LogAssetLoad(asset); | ||
158 | |||
159 | lock (this) | ||
160 | { | ||
161 | using (SqliteCommand cmd = new SqliteCommand(UpdateAssetSQL, m_conn)) | ||
162 | { | ||
163 | cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString())); | ||
164 | cmd.Parameters.Add(new SqliteParameter(":Name", assetName)); | ||
165 | cmd.Parameters.Add(new SqliteParameter(":Description", assetDescription)); | ||
166 | cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type)); | ||
167 | cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local)); | ||
168 | cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary)); | ||
169 | cmd.Parameters.Add(new SqliteParameter(":Flags", asset.Flags)); | ||
170 | cmd.Parameters.Add(new SqliteParameter(":CreatorID", asset.Metadata.CreatorID)); | ||
171 | cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); | ||
172 | |||
173 | cmd.ExecuteNonQuery(); | ||
174 | return true; | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | else | ||
179 | { | ||
180 | lock (this) | ||
181 | { | ||
182 | using (SqliteCommand cmd = new SqliteCommand(InsertAssetSQL, m_conn)) | ||
183 | { | ||
184 | cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString())); | ||
185 | cmd.Parameters.Add(new SqliteParameter(":Name", assetName)); | ||
186 | cmd.Parameters.Add(new SqliteParameter(":Description", assetDescription)); | ||
187 | cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type)); | ||
188 | cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local)); | ||
189 | cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary)); | ||
190 | cmd.Parameters.Add(new SqliteParameter(":Flags", asset.Flags)); | ||
191 | cmd.Parameters.Add(new SqliteParameter(":CreatorID", asset.Metadata.CreatorID)); | ||
192 | cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); | ||
193 | |||
194 | cmd.ExecuteNonQuery(); | ||
195 | return true; | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | // /// <summary> | ||
202 | // /// Some... logging functionnality | ||
203 | // /// </summary> | ||
204 | // /// <param name="asset"></param> | ||
205 | // private static void LogAssetLoad(AssetBase asset) | ||
206 | // { | ||
207 | // string temporary = asset.Temporary ? "Temporary" : "Stored"; | ||
208 | // string local = asset.Local ? "Local" : "Remote"; | ||
209 | // | ||
210 | // int assetLength = (asset.Data != null) ? asset.Data.Length : 0; | ||
211 | // | ||
212 | // m_log.Debug("[ASSET DB]: " + | ||
213 | // string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)", | ||
214 | // asset.FullID, asset.Name, asset.Description, asset.Type, | ||
215 | // temporary, local, assetLength)); | ||
216 | // } | ||
217 | |||
218 | /// <summary> | ||
219 | /// Check if the assets exist in the database. | ||
220 | /// </summary> | ||
221 | /// <param name="uuids">The assets' IDs</param> | ||
222 | /// <returns>For each asset: true if it exists, false otherwise</returns> | ||
223 | public override bool[] AssetsExist(UUID[] uuids) | ||
224 | { | ||
225 | if (uuids.Length == 0) | ||
226 | return new bool[0]; | ||
227 | |||
228 | HashSet<UUID> exist = new HashSet<UUID>(); | ||
229 | |||
230 | string ids = "'" + string.Join("','", uuids) + "'"; | ||
231 | string sql = string.Format("select UUID from assets where UUID in ({0})", ids); | ||
232 | |||
233 | lock (this) | ||
234 | { | ||
235 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | ||
236 | { | ||
237 | using (IDataReader reader = cmd.ExecuteReader()) | ||
238 | { | ||
239 | while (reader.Read()) | ||
240 | { | ||
241 | UUID id = new UUID((string)reader["UUID"]); | ||
242 | exist.Add(id); | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
248 | bool[] results = new bool[uuids.Length]; | ||
249 | for (int i = 0; i < uuids.Length; i++) | ||
250 | results[i] = exist.Contains(uuids[i]); | ||
251 | return results; | ||
252 | } | ||
253 | |||
254 | /// <summary> | ||
255 | /// | ||
256 | /// </summary> | ||
257 | /// <param name="row"></param> | ||
258 | /// <returns></returns> | ||
259 | private static AssetBase buildAsset(IDataReader row) | ||
260 | { | ||
261 | // TODO: this doesn't work yet because something more | ||
262 | // interesting has to be done to actually get these values | ||
263 | // back out. Not enough time to figure it out yet. | ||
264 | AssetBase asset = new AssetBase( | ||
265 | new UUID((String)row["UUID"]), | ||
266 | (String)row["Name"], | ||
267 | Convert.ToSByte(row["Type"]), | ||
268 | (String)row["CreatorID"] | ||
269 | ); | ||
270 | |||
271 | asset.Description = (String) row["Description"]; | ||
272 | asset.Local = Convert.ToBoolean(row["Local"]); | ||
273 | asset.Temporary = Convert.ToBoolean(row["Temporary"]); | ||
274 | asset.Flags = (AssetFlags)Convert.ToInt32(row["asset_flags"]); | ||
275 | asset.Data = (byte[])row["Data"]; | ||
276 | return asset; | ||
277 | } | ||
278 | |||
279 | private static AssetMetadata buildAssetMetadata(IDataReader row) | ||
280 | { | ||
281 | AssetMetadata metadata = new AssetMetadata(); | ||
282 | |||
283 | metadata.FullID = new UUID((string) row["UUID"]); | ||
284 | metadata.Name = (string) row["Name"]; | ||
285 | metadata.Description = (string) row["Description"]; | ||
286 | metadata.Type = Convert.ToSByte(row["Type"]); | ||
287 | metadata.Temporary = Convert.ToBoolean(row["Temporary"]); // Not sure if this is correct. | ||
288 | metadata.Flags = (AssetFlags)Convert.ToInt32(row["asset_flags"]); | ||
289 | metadata.CreatorID = row["CreatorID"].ToString(); | ||
290 | |||
291 | // Current SHA1s are not stored/computed. | ||
292 | metadata.SHA1 = new byte[] {}; | ||
293 | |||
294 | return metadata; | ||
295 | } | ||
296 | |||
297 | /// <summary> | ||
298 | /// Returns a list of AssetMetadata objects. The list is a subset of | ||
299 | /// the entire data set offset by <paramref name="start" /> containing | ||
300 | /// <paramref name="count" /> elements. | ||
301 | /// </summary> | ||
302 | /// <param name="start">The number of results to discard from the total data set.</param> | ||
303 | /// <param name="count">The number of rows the returned list should contain.</param> | ||
304 | /// <returns>A list of AssetMetadata objects.</returns> | ||
305 | public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count) | ||
306 | { | ||
307 | List<AssetMetadata> retList = new List<AssetMetadata>(count); | ||
308 | |||
309 | lock (this) | ||
310 | { | ||
311 | using (SqliteCommand cmd = new SqliteCommand(SelectAssetMetadataSQL, m_conn)) | ||
312 | { | ||
313 | cmd.Parameters.Add(new SqliteParameter(":start", start)); | ||
314 | cmd.Parameters.Add(new SqliteParameter(":count", count)); | ||
315 | |||
316 | using (IDataReader reader = cmd.ExecuteReader()) | ||
317 | { | ||
318 | while (reader.Read()) | ||
319 | { | ||
320 | AssetMetadata metadata = buildAssetMetadata(reader); | ||
321 | retList.Add(metadata); | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
327 | return retList; | ||
328 | } | ||
329 | |||
330 | /*********************************************************************** | ||
331 | * | ||
332 | * Database Binding functions | ||
333 | * | ||
334 | * These will be db specific due to typing, and minor differences | ||
335 | * in databases. | ||
336 | * | ||
337 | **********************************************************************/ | ||
338 | |||
339 | #region IPlugin interface | ||
340 | |||
341 | /// <summary> | ||
342 | /// | ||
343 | /// </summary> | ||
344 | override public string Version | ||
345 | { | ||
346 | get | ||
347 | { | ||
348 | Module module = GetType().Module; | ||
349 | // string dllName = module.Assembly.ManifestModule.Name; | ||
350 | Version dllVersion = module.Assembly.GetName().Version; | ||
351 | |||
352 | return | ||
353 | string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build, | ||
354 | dllVersion.Revision); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | /// <summary> | ||
359 | /// Initialise the AssetData interface using default URI | ||
360 | /// </summary> | ||
361 | override public void Initialise() | ||
362 | { | ||
363 | Initialise("URI=file:" + Util.dbDir() + "Asset.db,version=3"); | ||
364 | } | ||
365 | |||
366 | /// <summary> | ||
367 | /// Name of this DB provider | ||
368 | /// </summary> | ||
369 | override public string Name | ||
370 | { | ||
371 | get { return "SQLite Asset storage engine"; } | ||
372 | } | ||
373 | |||
374 | // TODO: (AlexRa): one of these is to be removed eventually (?) | ||
375 | |||
376 | /// <summary> | ||
377 | /// Delete an asset from database | ||
378 | /// </summary> | ||
379 | /// <param name="uuid"></param> | ||
380 | public bool DeleteAsset(UUID uuid) | ||
381 | { | ||
382 | lock (this) | ||
383 | { | ||
384 | using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn)) | ||
385 | { | ||
386 | cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString())); | ||
387 | cmd.ExecuteNonQuery(); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | return true; | ||
392 | } | ||
393 | |||
394 | public override bool Delete(string id) | ||
395 | { | ||
396 | UUID assetID; | ||
397 | |||
398 | if (!UUID.TryParse(id, out assetID)) | ||
399 | return false; | ||
400 | |||
401 | return DeleteAsset(assetID); | ||
402 | } | ||
403 | |||
404 | #endregion | ||
405 | } | ||
406 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs new file mode 100644 index 0000000..8fb955c --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs | |||
@@ -0,0 +1,259 @@ | |||
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 System.Reflection; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | |||
37 | #if CSharpSqlite | ||
38 | using Community.CsharpSqlite.Sqlite; | ||
39 | #else | ||
40 | using Mono.Data.Sqlite; | ||
41 | #endif | ||
42 | |||
43 | namespace OpenSim.Data.SQLite | ||
44 | { | ||
45 | public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData | ||
46 | { | ||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private string m_Realm; | ||
50 | private List<string> m_ColumnNames; | ||
51 | private int m_LastExpire; | ||
52 | |||
53 | protected static SqliteConnection m_Connection; | ||
54 | private static bool m_initialized = false; | ||
55 | |||
56 | protected virtual Assembly Assembly | ||
57 | { | ||
58 | get { return GetType().Assembly; } | ||
59 | } | ||
60 | |||
61 | public SQLiteAuthenticationData(string connectionString, string realm) | ||
62 | : base(connectionString) | ||
63 | { | ||
64 | m_Realm = realm; | ||
65 | |||
66 | if (!m_initialized) | ||
67 | { | ||
68 | if (Util.IsWindows()) | ||
69 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
70 | |||
71 | m_Connection = new SqliteConnection(connectionString); | ||
72 | m_Connection.Open(); | ||
73 | |||
74 | Migration m = new Migration(m_Connection, Assembly, "AuthStore"); | ||
75 | m.Update(); | ||
76 | |||
77 | m_initialized = true; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | public AuthenticationData Get(UUID principalID) | ||
82 | { | ||
83 | AuthenticationData ret = new AuthenticationData(); | ||
84 | ret.Data = new Dictionary<string, object>(); | ||
85 | IDataReader result; | ||
86 | |||
87 | using (SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID")) | ||
88 | { | ||
89 | cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); | ||
90 | |||
91 | result = ExecuteReader(cmd, m_Connection); | ||
92 | } | ||
93 | |||
94 | try | ||
95 | { | ||
96 | if (result.Read()) | ||
97 | { | ||
98 | ret.PrincipalID = principalID; | ||
99 | |||
100 | if (m_ColumnNames == null) | ||
101 | { | ||
102 | m_ColumnNames = new List<string>(); | ||
103 | |||
104 | DataTable schemaTable = result.GetSchemaTable(); | ||
105 | foreach (DataRow row in schemaTable.Rows) | ||
106 | m_ColumnNames.Add(row["ColumnName"].ToString()); | ||
107 | } | ||
108 | |||
109 | foreach (string s in m_ColumnNames) | ||
110 | { | ||
111 | if (s == "UUID") | ||
112 | continue; | ||
113 | |||
114 | ret.Data[s] = result[s].ToString(); | ||
115 | } | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | else | ||
120 | { | ||
121 | return null; | ||
122 | } | ||
123 | } | ||
124 | catch | ||
125 | { | ||
126 | } | ||
127 | |||
128 | return null; | ||
129 | } | ||
130 | |||
131 | public bool Store(AuthenticationData data) | ||
132 | { | ||
133 | if (data.Data.ContainsKey("UUID")) | ||
134 | data.Data.Remove("UUID"); | ||
135 | |||
136 | string[] fields = new List<string>(data.Data.Keys).ToArray(); | ||
137 | string[] values = new string[data.Data.Count]; | ||
138 | int i = 0; | ||
139 | foreach (object o in data.Data.Values) | ||
140 | values[i++] = o.ToString(); | ||
141 | |||
142 | using (SqliteCommand cmd = new SqliteCommand()) | ||
143 | { | ||
144 | if (Get(data.PrincipalID) != null) | ||
145 | { | ||
146 | |||
147 | |||
148 | string update = "update `" + m_Realm + "` set "; | ||
149 | bool first = true; | ||
150 | foreach (string field in fields) | ||
151 | { | ||
152 | if (!first) | ||
153 | update += ", "; | ||
154 | update += "`" + field + "` = :" + field; | ||
155 | cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); | ||
156 | |||
157 | first = false; | ||
158 | } | ||
159 | |||
160 | update += " where UUID = :UUID"; | ||
161 | cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); | ||
162 | |||
163 | cmd.CommandText = update; | ||
164 | try | ||
165 | { | ||
166 | if (ExecuteNonQuery(cmd, m_Connection) < 1) | ||
167 | { | ||
168 | //CloseCommand(cmd); | ||
169 | return false; | ||
170 | } | ||
171 | } | ||
172 | catch (Exception e) | ||
173 | { | ||
174 | m_log.Error("[SQLITE]: Exception storing authentication data", e); | ||
175 | //CloseCommand(cmd); | ||
176 | return false; | ||
177 | } | ||
178 | } | ||
179 | else | ||
180 | { | ||
181 | string insert = "insert into `" + m_Realm + "` (`UUID`, `" + | ||
182 | String.Join("`, `", fields) + | ||
183 | "`) values (:UUID, :" + String.Join(", :", fields) + ")"; | ||
184 | |||
185 | cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString())); | ||
186 | foreach (string field in fields) | ||
187 | cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field])); | ||
188 | |||
189 | cmd.CommandText = insert; | ||
190 | |||
191 | try | ||
192 | { | ||
193 | if (ExecuteNonQuery(cmd, m_Connection) < 1) | ||
194 | { | ||
195 | return false; | ||
196 | } | ||
197 | } | ||
198 | catch (Exception e) | ||
199 | { | ||
200 | Console.WriteLine(e.ToString()); | ||
201 | return false; | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | return true; | ||
207 | } | ||
208 | |||
209 | public bool SetDataItem(UUID principalID, string item, string value) | ||
210 | { | ||
211 | using (SqliteCommand cmd = new SqliteCommand("update `" + m_Realm + | ||
212 | "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'")) | ||
213 | { | ||
214 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
215 | return true; | ||
216 | } | ||
217 | |||
218 | return false; | ||
219 | } | ||
220 | |||
221 | public bool SetToken(UUID principalID, string token, int lifetime) | ||
222 | { | ||
223 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
224 | DoExpire(); | ||
225 | |||
226 | using (SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() + | ||
227 | "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))")) | ||
228 | { | ||
229 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
230 | return true; | ||
231 | } | ||
232 | |||
233 | return false; | ||
234 | } | ||
235 | |||
236 | public bool CheckToken(UUID principalID, string token, int lifetime) | ||
237 | { | ||
238 | if (System.Environment.TickCount - m_LastExpire > 30000) | ||
239 | DoExpire(); | ||
240 | |||
241 | using (SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() + | ||
242 | " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')")) | ||
243 | { | ||
244 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
245 | return true; | ||
246 | } | ||
247 | |||
248 | return false; | ||
249 | } | ||
250 | |||
251 | private void DoExpire() | ||
252 | { | ||
253 | using (SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')")) | ||
254 | ExecuteNonQuery(cmd, m_Connection); | ||
255 | |||
256 | m_LastExpire = System.Environment.TickCount; | ||
257 | } | ||
258 | } | ||
259 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteAvatarData.cs b/OpenSim/Data/SQLite/SQLiteAvatarData.cs new file mode 100644 index 0000000..c6d615b --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteAvatarData.cs | |||
@@ -0,0 +1,72 @@ | |||
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 System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | #if CSharpSqlite | ||
37 | using Community.CsharpSqlite.Sqlite; | ||
38 | #else | ||
39 | using Mono.Data.Sqlite; | ||
40 | #endif | ||
41 | |||
42 | namespace OpenSim.Data.SQLite | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// A SQLite Interface for Avatar Data | ||
46 | /// </summary> | ||
47 | public class SQLiteAvatarData : SQLiteGenericTableHandler<AvatarBaseData>, | ||
48 | IAvatarData | ||
49 | { | ||
50 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | |||
52 | public SQLiteAvatarData(string connectionString, string realm) : | ||
53 | base(connectionString, realm, "Avatar") | ||
54 | { | ||
55 | } | ||
56 | |||
57 | public bool Delete(UUID principalID, string name) | ||
58 | { | ||
59 | using (SqliteCommand cmd = new SqliteCommand()) | ||
60 | { | ||
61 | cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm); | ||
62 | cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString()); | ||
63 | cmd.Parameters.AddWithValue(":Name", name); | ||
64 | |||
65 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
66 | return true; | ||
67 | } | ||
68 | |||
69 | return false; | ||
70 | } | ||
71 | } | ||
72 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs new file mode 100644 index 0000000..0fcab21 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs | |||
@@ -0,0 +1,516 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | #if CSharpSqlite | ||
34 | using Community.CsharpSqlite.Sqlite; | ||
35 | #else | ||
36 | using Mono.Data.Sqlite; | ||
37 | #endif | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | |||
42 | namespace OpenSim.Data.SQLite | ||
43 | { | ||
44 | public class SQLiteEstateStore : IEstateDataStore | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private SqliteConnection m_connection; | ||
50 | private string m_connectionString; | ||
51 | |||
52 | private FieldInfo[] m_Fields; | ||
53 | private Dictionary<string, FieldInfo> m_FieldMap = | ||
54 | new Dictionary<string, FieldInfo>(); | ||
55 | |||
56 | protected virtual Assembly Assembly | ||
57 | { | ||
58 | get { return GetType().Assembly; } | ||
59 | } | ||
60 | |||
61 | public SQLiteEstateStore() | ||
62 | { | ||
63 | } | ||
64 | |||
65 | public SQLiteEstateStore(string connectionString) | ||
66 | { | ||
67 | Initialise(connectionString); | ||
68 | } | ||
69 | |||
70 | public void Initialise(string connectionString) | ||
71 | { | ||
72 | if (Util.IsWindows()) | ||
73 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
74 | |||
75 | m_connectionString = connectionString; | ||
76 | |||
77 | m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString); | ||
78 | |||
79 | m_connection = new SqliteConnection(m_connectionString); | ||
80 | m_connection.Open(); | ||
81 | |||
82 | Migration m = new Migration(m_connection, Assembly, "EstateStore"); | ||
83 | m.Update(); | ||
84 | |||
85 | //m_connection.Close(); | ||
86 | // m_connection.Open(); | ||
87 | |||
88 | Type t = typeof(EstateSettings); | ||
89 | m_Fields = t.GetFields(BindingFlags.NonPublic | | ||
90 | BindingFlags.Instance | | ||
91 | BindingFlags.DeclaredOnly); | ||
92 | |||
93 | foreach (FieldInfo f in m_Fields) | ||
94 | if (f.Name.Substring(0, 2) == "m_") | ||
95 | m_FieldMap[f.Name.Substring(2)] = f; | ||
96 | } | ||
97 | |||
98 | private string[] FieldList | ||
99 | { | ||
100 | get { return new List<string>(m_FieldMap.Keys).ToArray(); } | ||
101 | } | ||
102 | |||
103 | public EstateSettings LoadEstateSettings(UUID regionID, bool create) | ||
104 | { | ||
105 | string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = :RegionID"; | ||
106 | |||
107 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
108 | { | ||
109 | cmd.CommandText = sql; | ||
110 | cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); | ||
111 | |||
112 | return DoLoad(cmd, regionID, create); | ||
113 | } | ||
114 | } | ||
115 | |||
116 | private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create) | ||
117 | { | ||
118 | EstateSettings es = new EstateSettings(); | ||
119 | es.OnSave += StoreEstateSettings; | ||
120 | IDataReader r = null; | ||
121 | try | ||
122 | { | ||
123 | r = cmd.ExecuteReader(); | ||
124 | } | ||
125 | catch (SqliteException) | ||
126 | { | ||
127 | m_log.Error("[SQLITE]: There was an issue loading the estate settings. This can happen the first time running OpenSimulator with CSharpSqlite the first time. OpenSimulator will probably crash, restart it and it should be good to go."); | ||
128 | } | ||
129 | |||
130 | if (r != null && r.Read()) | ||
131 | { | ||
132 | foreach (string name in FieldList) | ||
133 | { | ||
134 | if (m_FieldMap[name].GetValue(es) is bool) | ||
135 | { | ||
136 | int v = Convert.ToInt32(r[name]); | ||
137 | if (v != 0) | ||
138 | m_FieldMap[name].SetValue(es, true); | ||
139 | else | ||
140 | m_FieldMap[name].SetValue(es, false); | ||
141 | } | ||
142 | else if (m_FieldMap[name].GetValue(es) is UUID) | ||
143 | { | ||
144 | UUID uuid = UUID.Zero; | ||
145 | |||
146 | UUID.TryParse(r[name].ToString(), out uuid); | ||
147 | m_FieldMap[name].SetValue(es, uuid); | ||
148 | } | ||
149 | else | ||
150 | { | ||
151 | m_FieldMap[name].SetValue(es, Convert.ChangeType(r[name], m_FieldMap[name].FieldType)); | ||
152 | } | ||
153 | } | ||
154 | r.Close(); | ||
155 | } | ||
156 | else if (create) | ||
157 | { | ||
158 | DoCreate(es); | ||
159 | LinkRegion(regionID, (int)es.EstateID); | ||
160 | } | ||
161 | |||
162 | LoadBanList(es); | ||
163 | |||
164 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
165 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
166 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
167 | return es; | ||
168 | } | ||
169 | |||
170 | public EstateSettings CreateNewEstate() | ||
171 | { | ||
172 | EstateSettings es = new EstateSettings(); | ||
173 | es.OnSave += StoreEstateSettings; | ||
174 | |||
175 | DoCreate(es); | ||
176 | |||
177 | LoadBanList(es); | ||
178 | |||
179 | es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers"); | ||
180 | es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users"); | ||
181 | es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups"); | ||
182 | |||
183 | return es; | ||
184 | } | ||
185 | |||
186 | private void DoCreate(EstateSettings es) | ||
187 | { | ||
188 | List<string> names = new List<string>(FieldList); | ||
189 | |||
190 | IDataReader r = null; | ||
191 | |||
192 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
193 | { | ||
194 | names.Remove("EstateID"); | ||
195 | |||
196 | string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")"; | ||
197 | |||
198 | cmd.CommandText = sql; | ||
199 | cmd.Parameters.Clear(); | ||
200 | |||
201 | foreach (string name in FieldList) | ||
202 | { | ||
203 | if (m_FieldMap[name].GetValue(es) is bool) | ||
204 | { | ||
205 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
206 | cmd.Parameters.AddWithValue(":"+name, "1"); | ||
207 | else | ||
208 | cmd.Parameters.AddWithValue(":"+name, "0"); | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | cmd.ExecuteNonQuery(); | ||
217 | |||
218 | cmd.CommandText = "select LAST_INSERT_ROWID() as id"; | ||
219 | cmd.Parameters.Clear(); | ||
220 | |||
221 | r = cmd.ExecuteReader(); | ||
222 | } | ||
223 | |||
224 | r.Read(); | ||
225 | |||
226 | es.EstateID = Convert.ToUInt32(r["id"]); | ||
227 | |||
228 | r.Close(); | ||
229 | |||
230 | es.Save(); | ||
231 | } | ||
232 | |||
233 | public void StoreEstateSettings(EstateSettings es) | ||
234 | { | ||
235 | List<string> fields = new List<string>(FieldList); | ||
236 | fields.Remove("EstateID"); | ||
237 | |||
238 | List<string> terms = new List<string>(); | ||
239 | |||
240 | foreach (string f in fields) | ||
241 | terms.Add(f+" = :"+f); | ||
242 | |||
243 | string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID"; | ||
244 | |||
245 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
246 | { | ||
247 | cmd.CommandText = sql; | ||
248 | |||
249 | foreach (string name in FieldList) | ||
250 | { | ||
251 | if (m_FieldMap[name].GetValue(es) is bool) | ||
252 | { | ||
253 | if ((bool)m_FieldMap[name].GetValue(es)) | ||
254 | cmd.Parameters.AddWithValue(":"+name, "1"); | ||
255 | else | ||
256 | cmd.Parameters.AddWithValue(":"+name, "0"); | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | cmd.ExecuteNonQuery(); | ||
265 | } | ||
266 | |||
267 | SaveBanList(es); | ||
268 | SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers); | ||
269 | SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess); | ||
270 | SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups); | ||
271 | } | ||
272 | |||
273 | private void LoadBanList(EstateSettings es) | ||
274 | { | ||
275 | es.ClearBans(); | ||
276 | |||
277 | IDataReader r; | ||
278 | |||
279 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
280 | { | ||
281 | cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; | ||
282 | cmd.Parameters.AddWithValue(":EstateID", es.EstateID); | ||
283 | |||
284 | r = cmd.ExecuteReader(); | ||
285 | } | ||
286 | |||
287 | while (r.Read()) | ||
288 | { | ||
289 | EstateBan eb = new EstateBan(); | ||
290 | |||
291 | UUID uuid = new UUID(); | ||
292 | UUID.TryParse(r["bannedUUID"].ToString(), out uuid); | ||
293 | |||
294 | eb.BannedUserID = uuid; | ||
295 | eb.BannedHostAddress = "0.0.0.0"; | ||
296 | eb.BannedHostIPMask = "0.0.0.0"; | ||
297 | es.AddBan(eb); | ||
298 | } | ||
299 | r.Close(); | ||
300 | } | ||
301 | |||
302 | private void SaveBanList(EstateSettings es) | ||
303 | { | ||
304 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
305 | { | ||
306 | cmd.CommandText = "delete from estateban where EstateID = :EstateID"; | ||
307 | cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); | ||
308 | |||
309 | cmd.ExecuteNonQuery(); | ||
310 | |||
311 | cmd.Parameters.Clear(); | ||
312 | |||
313 | cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )"; | ||
314 | |||
315 | foreach (EstateBan b in es.EstateBans) | ||
316 | { | ||
317 | cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); | ||
318 | cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); | ||
319 | |||
320 | cmd.ExecuteNonQuery(); | ||
321 | cmd.Parameters.Clear(); | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | |||
326 | void SaveUUIDList(uint EstateID, string table, UUID[] data) | ||
327 | { | ||
328 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
329 | { | ||
330 | cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; | ||
331 | cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); | ||
332 | |||
333 | cmd.ExecuteNonQuery(); | ||
334 | |||
335 | cmd.Parameters.Clear(); | ||
336 | |||
337 | cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )"; | ||
338 | |||
339 | foreach (UUID uuid in data) | ||
340 | { | ||
341 | cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); | ||
342 | cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); | ||
343 | |||
344 | cmd.ExecuteNonQuery(); | ||
345 | cmd.Parameters.Clear(); | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | UUID[] LoadUUIDList(uint EstateID, string table) | ||
351 | { | ||
352 | List<UUID> uuids = new List<UUID>(); | ||
353 | IDataReader r; | ||
354 | |||
355 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
356 | { | ||
357 | cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; | ||
358 | cmd.Parameters.AddWithValue(":EstateID", EstateID); | ||
359 | |||
360 | r = cmd.ExecuteReader(); | ||
361 | } | ||
362 | |||
363 | while (r.Read()) | ||
364 | { | ||
365 | // EstateBan eb = new EstateBan(); | ||
366 | |||
367 | UUID uuid = new UUID(); | ||
368 | UUID.TryParse(r["uuid"].ToString(), out uuid); | ||
369 | |||
370 | uuids.Add(uuid); | ||
371 | } | ||
372 | r.Close(); | ||
373 | |||
374 | return uuids.ToArray(); | ||
375 | } | ||
376 | |||
377 | public EstateSettings LoadEstateSettings(int estateID) | ||
378 | { | ||
379 | string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID = :EstateID"; | ||
380 | |||
381 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
382 | { | ||
383 | cmd.CommandText = sql; | ||
384 | cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); | ||
385 | |||
386 | return DoLoad(cmd, UUID.Zero, false); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | public List<EstateSettings> LoadEstateSettingsAll() | ||
391 | { | ||
392 | List<EstateSettings> estateSettings = new List<EstateSettings>(); | ||
393 | |||
394 | List<int> estateIds = GetEstatesAll(); | ||
395 | foreach (int estateId in estateIds) | ||
396 | estateSettings.Add(LoadEstateSettings(estateId)); | ||
397 | |||
398 | return estateSettings; | ||
399 | } | ||
400 | |||
401 | public List<int> GetEstates(string search) | ||
402 | { | ||
403 | List<int> result = new List<int>(); | ||
404 | |||
405 | string sql = "select EstateID from estate_settings where estate_settings.EstateName = :EstateName"; | ||
406 | IDataReader r; | ||
407 | |||
408 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
409 | { | ||
410 | cmd.CommandText = sql; | ||
411 | cmd.Parameters.AddWithValue(":EstateName", search); | ||
412 | |||
413 | r = cmd.ExecuteReader(); | ||
414 | } | ||
415 | |||
416 | while (r.Read()) | ||
417 | { | ||
418 | result.Add(Convert.ToInt32(r["EstateID"])); | ||
419 | } | ||
420 | r.Close(); | ||
421 | |||
422 | return result; | ||
423 | } | ||
424 | |||
425 | public List<int> GetEstatesAll() | ||
426 | { | ||
427 | List<int> result = new List<int>(); | ||
428 | |||
429 | string sql = "select EstateID from estate_settings"; | ||
430 | IDataReader r; | ||
431 | |||
432 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
433 | { | ||
434 | cmd.CommandText = sql; | ||
435 | |||
436 | r = cmd.ExecuteReader(); | ||
437 | } | ||
438 | |||
439 | while (r.Read()) | ||
440 | { | ||
441 | result.Add(Convert.ToInt32(r["EstateID"])); | ||
442 | } | ||
443 | r.Close(); | ||
444 | |||
445 | return result; | ||
446 | } | ||
447 | |||
448 | public List<int> GetEstatesByOwner(UUID ownerID) | ||
449 | { | ||
450 | List<int> result = new List<int>(); | ||
451 | |||
452 | string sql = "select EstateID from estate_settings where estate_settings.EstateOwner = :EstateOwner"; | ||
453 | IDataReader r; | ||
454 | |||
455 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
456 | { | ||
457 | cmd.CommandText = sql; | ||
458 | cmd.Parameters.AddWithValue(":EstateOwner", ownerID); | ||
459 | |||
460 | r = cmd.ExecuteReader(); | ||
461 | } | ||
462 | |||
463 | while (r.Read()) | ||
464 | { | ||
465 | result.Add(Convert.ToInt32(r["EstateID"])); | ||
466 | } | ||
467 | r.Close(); | ||
468 | |||
469 | return result; | ||
470 | } | ||
471 | |||
472 | public bool LinkRegion(UUID regionID, int estateID) | ||
473 | { | ||
474 | SqliteTransaction transaction = m_connection.BeginTransaction(); | ||
475 | |||
476 | // Delete any existing estate mapping for this region. | ||
477 | using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
478 | { | ||
479 | cmd.CommandText = "delete from estate_map where RegionID = :RegionID"; | ||
480 | cmd.Transaction = transaction; | ||
481 | cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); | ||
482 | |||
483 | cmd.ExecuteNonQuery(); | ||
484 | } | ||
485 | |||
486 | using(SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
487 | { | ||
488 | cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; | ||
489 | cmd.Transaction = transaction; | ||
490 | cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); | ||
491 | cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); | ||
492 | |||
493 | if (cmd.ExecuteNonQuery() == 0) | ||
494 | { | ||
495 | transaction.Rollback(); | ||
496 | return false; | ||
497 | } | ||
498 | else | ||
499 | { | ||
500 | transaction.Commit(); | ||
501 | return true; | ||
502 | } | ||
503 | } | ||
504 | } | ||
505 | |||
506 | public List<UUID> GetRegions(int estateID) | ||
507 | { | ||
508 | return new List<UUID>(); | ||
509 | } | ||
510 | |||
511 | public bool DeleteEstate(int estateID) | ||
512 | { | ||
513 | return false; | ||
514 | } | ||
515 | } | ||
516 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs new file mode 100644 index 0000000..35b9a2f --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteFramework.cs | |||
@@ -0,0 +1,94 @@ | |||
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 | #if CSharpSqlite | ||
35 | using Community.CsharpSqlite.Sqlite; | ||
36 | #else | ||
37 | using Mono.Data.Sqlite; | ||
38 | #endif | ||
39 | |||
40 | namespace OpenSim.Data.SQLite | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// A database interface class to a user profile storage system | ||
44 | /// </summary> | ||
45 | public class SQLiteFramework | ||
46 | { | ||
47 | protected Object m_lockObject = new Object(); | ||
48 | |||
49 | protected SQLiteFramework(string connectionString) | ||
50 | { | ||
51 | if (Util.IsWindows()) | ||
52 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
53 | } | ||
54 | |||
55 | ////////////////////////////////////////////////////////////// | ||
56 | // | ||
57 | // All non queries are funneled through one connection | ||
58 | // to increase performance a little | ||
59 | // | ||
60 | protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection) | ||
61 | { | ||
62 | lock (connection) | ||
63 | { | ||
64 | /* | ||
65 | SqliteConnection newConnection = | ||
66 | (SqliteConnection)((ICloneable)connection).Clone(); | ||
67 | newConnection.Open(); | ||
68 | |||
69 | cmd.Connection = newConnection; | ||
70 | */ | ||
71 | cmd.Connection = connection; | ||
72 | //Console.WriteLine("XXX " + cmd.CommandText); | ||
73 | |||
74 | return cmd.ExecuteNonQuery(); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection) | ||
79 | { | ||
80 | lock (connection) | ||
81 | { | ||
82 | //SqliteConnection newConnection = | ||
83 | // (SqliteConnection)((ICloneable)connection).Clone(); | ||
84 | //newConnection.Open(); | ||
85 | |||
86 | //cmd.Connection = newConnection; | ||
87 | cmd.Connection = connection; | ||
88 | //Console.WriteLine("XXX " + cmd.CommandText); | ||
89 | |||
90 | return cmd.ExecuteReader(); | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs new file mode 100644 index 0000000..331f426 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs | |||
@@ -0,0 +1,85 @@ | |||
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 | #if CSharpSqlite | ||
35 | using Community.CsharpSqlite.Sqlite; | ||
36 | #else | ||
37 | using Mono.Data.Sqlite; | ||
38 | #endif | ||
39 | |||
40 | namespace OpenSim.Data.SQLite | ||
41 | { | ||
42 | public class SQLiteFriendsData : SQLiteGenericTableHandler<FriendsData>, IFriendsData | ||
43 | { | ||
44 | public SQLiteFriendsData(string connectionString, string realm) | ||
45 | : base(connectionString, realm, "FriendsStore") | ||
46 | { | ||
47 | } | ||
48 | |||
49 | public FriendsData[] GetFriends(UUID principalID) | ||
50 | { | ||
51 | return GetFriends(principalID.ToString()); | ||
52 | } | ||
53 | |||
54 | public FriendsData[] GetFriends(string userID) | ||
55 | { | ||
56 | using (SqliteCommand cmd = new SqliteCommand()) | ||
57 | { | ||
58 | 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); | ||
59 | cmd.Parameters.AddWithValue(":PrincipalID", userID.ToString()); | ||
60 | |||
61 | return DoQuery(cmd); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | public bool Delete(UUID principalID, string friend) | ||
66 | { | ||
67 | return Delete(principalID.ToString(), friend); | ||
68 | } | ||
69 | |||
70 | public override bool Delete(string principalID, string friend) | ||
71 | { | ||
72 | using (SqliteCommand cmd = new SqliteCommand()) | ||
73 | { | ||
74 | cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm); | ||
75 | cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString()); | ||
76 | cmd.Parameters.AddWithValue(":Friend", friend); | ||
77 | |||
78 | ExecuteNonQuery(cmd, m_Connection); | ||
79 | } | ||
80 | |||
81 | return true; | ||
82 | } | ||
83 | |||
84 | } | ||
85 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs new file mode 100644 index 0000000..a4b84b1 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs | |||
@@ -0,0 +1,298 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | #if CSharpSqlite | ||
34 | using Community.CsharpSqlite.Sqlite; | ||
35 | #else | ||
36 | using Mono.Data.Sqlite; | ||
37 | #endif | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | using OpenSim.Region.Framework.Interfaces; | ||
41 | |||
42 | namespace OpenSim.Data.SQLite | ||
43 | { | ||
44 | public class SQLiteGenericTableHandler<T> : SQLiteFramework where T: class, new() | ||
45 | { | ||
46 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | protected Dictionary<string, FieldInfo> m_Fields = | ||
49 | new Dictionary<string, FieldInfo>(); | ||
50 | |||
51 | protected List<string> m_ColumnNames = null; | ||
52 | protected string m_Realm; | ||
53 | protected FieldInfo m_DataField = null; | ||
54 | |||
55 | protected static SqliteConnection m_Connection; | ||
56 | private static bool m_initialized; | ||
57 | |||
58 | protected virtual Assembly Assembly | ||
59 | { | ||
60 | get { return GetType().Assembly; } | ||
61 | } | ||
62 | |||
63 | public SQLiteGenericTableHandler(string connectionString, | ||
64 | string realm, string storeName) : base(connectionString) | ||
65 | { | ||
66 | m_Realm = realm; | ||
67 | |||
68 | if (!m_initialized) | ||
69 | { | ||
70 | m_Connection = new SqliteConnection(connectionString); | ||
71 | //Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString)); | ||
72 | m_Connection.Open(); | ||
73 | |||
74 | if (storeName != String.Empty) | ||
75 | { | ||
76 | //SqliteConnection newConnection = | ||
77 | // (SqliteConnection)((ICloneable)m_Connection).Clone(); | ||
78 | //newConnection.Open(); | ||
79 | |||
80 | //Migration m = new Migration(newConnection, Assembly, storeName); | ||
81 | Migration m = new Migration(m_Connection, Assembly, storeName); | ||
82 | m.Update(); | ||
83 | //newConnection.Close(); | ||
84 | //newConnection.Dispose(); | ||
85 | } | ||
86 | |||
87 | m_initialized = true; | ||
88 | } | ||
89 | |||
90 | Type t = typeof(T); | ||
91 | FieldInfo[] fields = t.GetFields(BindingFlags.Public | | ||
92 | BindingFlags.Instance | | ||
93 | BindingFlags.DeclaredOnly); | ||
94 | |||
95 | if (fields.Length == 0) | ||
96 | return; | ||
97 | |||
98 | foreach (FieldInfo f in fields) | ||
99 | { | ||
100 | if (f.Name != "Data") | ||
101 | m_Fields[f.Name] = f; | ||
102 | else | ||
103 | m_DataField = f; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | private void CheckColumnNames(IDataReader reader) | ||
108 | { | ||
109 | if (m_ColumnNames != null) | ||
110 | return; | ||
111 | |||
112 | m_ColumnNames = new List<string>(); | ||
113 | |||
114 | DataTable schemaTable = reader.GetSchemaTable(); | ||
115 | foreach (DataRow row in schemaTable.Rows) | ||
116 | { | ||
117 | if (row["ColumnName"] != null && | ||
118 | (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) | ||
119 | m_ColumnNames.Add(row["ColumnName"].ToString()); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | public virtual T[] Get(string field, string key) | ||
124 | { | ||
125 | return Get(new string[] { field }, new string[] { key }); | ||
126 | } | ||
127 | |||
128 | public virtual T[] Get(string[] fields, string[] keys) | ||
129 | { | ||
130 | if (fields.Length != keys.Length) | ||
131 | return new T[0]; | ||
132 | |||
133 | List<string> terms = new List<string>(); | ||
134 | |||
135 | using (SqliteCommand cmd = new SqliteCommand()) | ||
136 | { | ||
137 | for (int i = 0 ; i < fields.Length ; i++) | ||
138 | { | ||
139 | cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); | ||
140 | terms.Add("`" + fields[i] + "` = :" + fields[i]); | ||
141 | } | ||
142 | |||
143 | string where = String.Join(" and ", terms.ToArray()); | ||
144 | |||
145 | string query = String.Format("select * from {0} where {1}", | ||
146 | m_Realm, where); | ||
147 | |||
148 | cmd.CommandText = query; | ||
149 | |||
150 | return DoQuery(cmd); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | protected T[] DoQuery(SqliteCommand cmd) | ||
155 | { | ||
156 | IDataReader reader = ExecuteReader(cmd, m_Connection); | ||
157 | if (reader == null) | ||
158 | return new T[0]; | ||
159 | |||
160 | CheckColumnNames(reader); | ||
161 | |||
162 | List<T> result = new List<T>(); | ||
163 | |||
164 | while (reader.Read()) | ||
165 | { | ||
166 | T row = new T(); | ||
167 | |||
168 | foreach (string name in m_Fields.Keys) | ||
169 | { | ||
170 | if (m_Fields[name].GetValue(row) is bool) | ||
171 | { | ||
172 | int v = Convert.ToInt32(reader[name]); | ||
173 | m_Fields[name].SetValue(row, v != 0 ? true : false); | ||
174 | } | ||
175 | else if (m_Fields[name].GetValue(row) is UUID) | ||
176 | { | ||
177 | UUID uuid = UUID.Zero; | ||
178 | |||
179 | UUID.TryParse(reader[name].ToString(), out uuid); | ||
180 | m_Fields[name].SetValue(row, uuid); | ||
181 | } | ||
182 | else if (m_Fields[name].GetValue(row) is int) | ||
183 | { | ||
184 | int v = Convert.ToInt32(reader[name]); | ||
185 | m_Fields[name].SetValue(row, v); | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | m_Fields[name].SetValue(row, reader[name]); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (m_DataField != null) | ||
194 | { | ||
195 | Dictionary<string, string> data = | ||
196 | new Dictionary<string, string>(); | ||
197 | |||
198 | foreach (string col in m_ColumnNames) | ||
199 | { | ||
200 | data[col] = reader[col].ToString(); | ||
201 | if (data[col] == null) | ||
202 | data[col] = String.Empty; | ||
203 | } | ||
204 | |||
205 | m_DataField.SetValue(row, data); | ||
206 | } | ||
207 | |||
208 | result.Add(row); | ||
209 | } | ||
210 | |||
211 | //CloseCommand(cmd); | ||
212 | |||
213 | return result.ToArray(); | ||
214 | } | ||
215 | |||
216 | public virtual T[] Get(string where) | ||
217 | { | ||
218 | using (SqliteCommand cmd = new SqliteCommand()) | ||
219 | { | ||
220 | string query = String.Format("select * from {0} where {1}", | ||
221 | m_Realm, where); | ||
222 | |||
223 | cmd.CommandText = query; | ||
224 | |||
225 | return DoQuery(cmd); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | public virtual bool Store(T row) | ||
230 | { | ||
231 | using (SqliteCommand cmd = new SqliteCommand()) | ||
232 | { | ||
233 | string query = ""; | ||
234 | List<String> names = new List<String>(); | ||
235 | List<String> values = new List<String>(); | ||
236 | |||
237 | foreach (FieldInfo fi in m_Fields.Values) | ||
238 | { | ||
239 | names.Add(fi.Name); | ||
240 | values.Add(":" + fi.Name); | ||
241 | cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString())); | ||
242 | } | ||
243 | |||
244 | if (m_DataField != null) | ||
245 | { | ||
246 | Dictionary<string, string> data = | ||
247 | (Dictionary<string, string>)m_DataField.GetValue(row); | ||
248 | |||
249 | foreach (KeyValuePair<string, string> kvp in data) | ||
250 | { | ||
251 | names.Add(kvp.Key); | ||
252 | values.Add(":" + kvp.Key); | ||
253 | cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value)); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")"; | ||
258 | |||
259 | cmd.CommandText = query; | ||
260 | |||
261 | if (ExecuteNonQuery(cmd, m_Connection) > 0) | ||
262 | return true; | ||
263 | } | ||
264 | |||
265 | return false; | ||
266 | } | ||
267 | |||
268 | public virtual bool Delete(string field, string key) | ||
269 | { | ||
270 | return Delete(new string[] { field }, new string[] { key }); | ||
271 | } | ||
272 | |||
273 | public virtual bool Delete(string[] fields, string[] keys) | ||
274 | { | ||
275 | if (fields.Length != keys.Length) | ||
276 | return false; | ||
277 | |||
278 | List<string> terms = new List<string>(); | ||
279 | |||
280 | using (SqliteCommand cmd = new SqliteCommand()) | ||
281 | { | ||
282 | for (int i = 0 ; i < fields.Length ; i++) | ||
283 | { | ||
284 | cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i])); | ||
285 | terms.Add("`" + fields[i] + "` = :" + fields[i]); | ||
286 | } | ||
287 | |||
288 | string where = String.Join(" and ", terms.ToArray()); | ||
289 | |||
290 | string query = String.Format("delete from {0} where {1}", m_Realm, where); | ||
291 | |||
292 | cmd.CommandText = query; | ||
293 | |||
294 | return ExecuteNonQuery(cmd, m_Connection) > 0; | ||
295 | } | ||
296 | } | ||
297 | } | ||
298 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteGridUserData.cs b/OpenSim/Data/SQLite/SQLiteGridUserData.cs new file mode 100644 index 0000000..987240c --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteGridUserData.cs | |||
@@ -0,0 +1,65 @@ | |||
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 System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | |||
37 | namespace OpenSim.Data.SQLite | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// A SQL Interface for user grid data | ||
41 | /// </summary> | ||
42 | public class SQLiteGridUserData : SQLiteGenericTableHandler<GridUserData>, IGridUserData | ||
43 | { | ||
44 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
46 | public SQLiteGridUserData(string connectionString, string realm) | ||
47 | : base(connectionString, realm, "GridUserStore") {} | ||
48 | |||
49 | public new GridUserData Get(string userID) | ||
50 | { | ||
51 | GridUserData[] ret = Get("UserID", userID); | ||
52 | |||
53 | if (ret.Length == 0) | ||
54 | return null; | ||
55 | |||
56 | return ret[0]; | ||
57 | } | ||
58 | |||
59 | public GridUserData[] GetAll(string userID) | ||
60 | { | ||
61 | return base.Get(String.Format("UserID LIKE '{0}%'", userID)); | ||
62 | } | ||
63 | |||
64 | } | ||
65 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteHGTravelData.cs b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs new file mode 100644 index 0000000..dd34710 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs | |||
@@ -0,0 +1,82 @@ | |||
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 System.Threading; | ||
33 | using log4net; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Framework; | ||
36 | using Mono.Data.Sqlite; | ||
37 | |||
38 | namespace OpenSim.Data.SQLite | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// A SQL Interface for user grid data | ||
42 | /// </summary> | ||
43 | public class SQLiteHGTravelData : SQLiteGenericTableHandler<HGTravelingData>, IHGTravelingData | ||
44 | { | ||
45 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
46 | |||
47 | public SQLiteHGTravelData(string connectionString, string realm) | ||
48 | : base(connectionString, realm, "HGTravelStore") {} | ||
49 | |||
50 | public HGTravelingData Get(UUID sessionID) | ||
51 | { | ||
52 | HGTravelingData[] ret = Get("SessionID", sessionID.ToString()); | ||
53 | |||
54 | if (ret.Length == 0) | ||
55 | return null; | ||
56 | |||
57 | return ret[0]; | ||
58 | } | ||
59 | |||
60 | public HGTravelingData[] GetSessions(UUID userID) | ||
61 | { | ||
62 | return base.Get("UserID", userID.ToString()); | ||
63 | } | ||
64 | |||
65 | public bool Delete(UUID sessionID) | ||
66 | { | ||
67 | return Delete("SessionID", sessionID.ToString()); | ||
68 | } | ||
69 | |||
70 | public void DeleteOld() | ||
71 | { | ||
72 | using (SqliteCommand cmd = new SqliteCommand()) | ||
73 | { | ||
74 | cmd.CommandText = String.Format("delete from {0} where TMStamp < datetime('now', '-2 day') ", m_Realm); | ||
75 | |||
76 | DoQuery(cmd); | ||
77 | } | ||
78 | |||
79 | } | ||
80 | |||
81 | } | ||
82 | } \ No newline at end of file | ||
diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs new file mode 100644 index 0000000..19880de --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs | |||
@@ -0,0 +1,3082 @@ | |||
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.Drawing; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using log4net; | ||
35 | #if CSharpSqlite | ||
36 | using Community.CsharpSqlite.Sqlite; | ||
37 | #else | ||
38 | using Mono.Data.Sqlite; | ||
39 | #endif | ||
40 | using OpenMetaverse; | ||
41 | using OpenMetaverse.StructuredData; | ||
42 | using OpenSim.Framework; | ||
43 | using OpenSim.Region.Framework.Interfaces; | ||
44 | using OpenSim.Region.Framework.Scenes; | ||
45 | |||
46 | namespace OpenSim.Data.SQLite | ||
47 | { | ||
48 | /// <summary> | ||
49 | /// A RegionData Interface to the SQLite database | ||
50 | /// </summary> | ||
51 | public class SQLiteSimulationData : ISimulationDataStore | ||
52 | { | ||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
54 | private static readonly string LogHeader = "[REGION DB SQLITE]"; | ||
55 | |||
56 | private const string primSelect = "select * from prims"; | ||
57 | private const string shapeSelect = "select * from primshapes"; | ||
58 | private const string itemsSelect = "select * from primitems"; | ||
59 | private const string terrainSelect = "select * from terrain limit 1"; | ||
60 | private const string landSelect = "select * from land"; | ||
61 | private const string landAccessListSelect = "select distinct * from landaccesslist"; | ||
62 | private const string regionbanListSelect = "select * from regionban"; | ||
63 | private const string regionSettingsSelect = "select * from regionsettings"; | ||
64 | private const string regionWindlightSelect = "select * from regionwindlight"; | ||
65 | private const string regionEnvironmentSelect = "select * from regionenvironment"; | ||
66 | private const string regionSpawnPointsSelect = "select * from spawn_points"; | ||
67 | |||
68 | private DataSet ds; | ||
69 | private SqliteDataAdapter primDa; | ||
70 | private SqliteDataAdapter shapeDa; | ||
71 | private SqliteDataAdapter itemsDa; | ||
72 | private SqliteDataAdapter terrainDa; | ||
73 | private SqliteDataAdapter landDa; | ||
74 | private SqliteDataAdapter landAccessListDa; | ||
75 | private SqliteDataAdapter regionSettingsDa; | ||
76 | private SqliteDataAdapter regionWindlightDa; | ||
77 | private SqliteDataAdapter regionEnvironmentDa; | ||
78 | private SqliteDataAdapter regionSpawnPointsDa; | ||
79 | |||
80 | private SqliteConnection m_conn; | ||
81 | private String m_connectionString; | ||
82 | |||
83 | protected virtual Assembly Assembly | ||
84 | { | ||
85 | get { return GetType().Assembly; } | ||
86 | } | ||
87 | |||
88 | public SQLiteSimulationData() | ||
89 | { | ||
90 | } | ||
91 | |||
92 | public SQLiteSimulationData(string connectionString) | ||
93 | { | ||
94 | Initialise(connectionString); | ||
95 | } | ||
96 | |||
97 | // Temporary attribute while this is experimental | ||
98 | |||
99 | /*********************************************************************** | ||
100 | * | ||
101 | * Public Interface Functions | ||
102 | * | ||
103 | **********************************************************************/ | ||
104 | |||
105 | /// <summary> | ||
106 | /// <list type="bullet"> | ||
107 | /// <item>Initialises RegionData Interface</item> | ||
108 | /// <item>Loads and initialises a new SQLite connection and maintains it.</item> | ||
109 | /// </list> | ||
110 | /// </summary> | ||
111 | /// <param name="connectionString">the connection string</param> | ||
112 | public void Initialise(string connectionString) | ||
113 | { | ||
114 | try | ||
115 | { | ||
116 | if (Util.IsWindows()) | ||
117 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
118 | |||
119 | m_connectionString = connectionString; | ||
120 | |||
121 | ds = new DataSet("Region"); | ||
122 | |||
123 | m_log.Info("[SQLITE REGION DB]: Sqlite - connecting: " + connectionString); | ||
124 | m_conn = new SqliteConnection(m_connectionString); | ||
125 | m_conn.Open(); | ||
126 | |||
127 | SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); | ||
128 | primDa = new SqliteDataAdapter(primSelectCmd); | ||
129 | |||
130 | SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); | ||
131 | shapeDa = new SqliteDataAdapter(shapeSelectCmd); | ||
132 | // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); | ||
133 | |||
134 | SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn); | ||
135 | itemsDa = new SqliteDataAdapter(itemsSelectCmd); | ||
136 | |||
137 | SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn); | ||
138 | terrainDa = new SqliteDataAdapter(terrainSelectCmd); | ||
139 | |||
140 | SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn); | ||
141 | landDa = new SqliteDataAdapter(landSelectCmd); | ||
142 | |||
143 | SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn); | ||
144 | landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd); | ||
145 | |||
146 | SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn); | ||
147 | regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd); | ||
148 | |||
149 | SqliteCommand regionWindlightSelectCmd = new SqliteCommand(regionWindlightSelect, m_conn); | ||
150 | regionWindlightDa = new SqliteDataAdapter(regionWindlightSelectCmd); | ||
151 | |||
152 | SqliteCommand regionEnvironmentSelectCmd = new SqliteCommand(regionEnvironmentSelect, m_conn); | ||
153 | regionEnvironmentDa = new SqliteDataAdapter(regionEnvironmentSelectCmd); | ||
154 | |||
155 | SqliteCommand regionSpawnPointsSelectCmd = new SqliteCommand(regionSpawnPointsSelect, m_conn); | ||
156 | regionSpawnPointsDa = new SqliteDataAdapter(regionSpawnPointsSelectCmd); | ||
157 | |||
158 | // This actually does the roll forward assembly stuff | ||
159 | Migration m = new Migration(m_conn, Assembly, "RegionStore"); | ||
160 | m.Update(); | ||
161 | |||
162 | lock (ds) | ||
163 | { | ||
164 | ds.Tables.Add(createPrimTable()); | ||
165 | setupPrimCommands(primDa, m_conn); | ||
166 | |||
167 | ds.Tables.Add(createShapeTable()); | ||
168 | setupShapeCommands(shapeDa, m_conn); | ||
169 | |||
170 | ds.Tables.Add(createItemsTable()); | ||
171 | setupItemsCommands(itemsDa, m_conn); | ||
172 | |||
173 | ds.Tables.Add(createTerrainTable()); | ||
174 | setupTerrainCommands(terrainDa, m_conn); | ||
175 | |||
176 | ds.Tables.Add(createLandTable()); | ||
177 | setupLandCommands(landDa, m_conn); | ||
178 | |||
179 | ds.Tables.Add(createLandAccessListTable()); | ||
180 | setupLandAccessCommands(landAccessListDa, m_conn); | ||
181 | |||
182 | ds.Tables.Add(createRegionSettingsTable()); | ||
183 | setupRegionSettingsCommands(regionSettingsDa, m_conn); | ||
184 | |||
185 | ds.Tables.Add(createRegionWindlightTable()); | ||
186 | setupRegionWindlightCommands(regionWindlightDa, m_conn); | ||
187 | |||
188 | ds.Tables.Add(createRegionEnvironmentTable()); | ||
189 | setupRegionEnvironmentCommands(regionEnvironmentDa, m_conn); | ||
190 | |||
191 | ds.Tables.Add(createRegionSpawnPointsTable()); | ||
192 | setupRegionSpawnPointsCommands(regionSpawnPointsDa, m_conn); | ||
193 | |||
194 | // WORKAROUND: This is a work around for sqlite on | ||
195 | // windows, which gets really unhappy with blob columns | ||
196 | // that have no sample data in them. At some point we | ||
197 | // need to actually find a proper way to handle this. | ||
198 | try | ||
199 | { | ||
200 | primDa.Fill(ds.Tables["prims"]); | ||
201 | } | ||
202 | catch (Exception e) | ||
203 | { | ||
204 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on prims table :{0}", e.Message); | ||
205 | } | ||
206 | |||
207 | try | ||
208 | { | ||
209 | shapeDa.Fill(ds.Tables["primshapes"]); | ||
210 | } | ||
211 | catch (Exception e) | ||
212 | { | ||
213 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on primshapes table :{0}", e.Message); | ||
214 | } | ||
215 | |||
216 | try | ||
217 | { | ||
218 | itemsDa.Fill(ds.Tables["primitems"]); | ||
219 | } | ||
220 | catch (Exception e) | ||
221 | { | ||
222 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on primitems table :{0}", e.Message); | ||
223 | } | ||
224 | |||
225 | try | ||
226 | { | ||
227 | terrainDa.Fill(ds.Tables["terrain"]); | ||
228 | } | ||
229 | catch (Exception e) | ||
230 | { | ||
231 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on terrain table :{0}", e.Message); | ||
232 | } | ||
233 | |||
234 | try | ||
235 | { | ||
236 | landDa.Fill(ds.Tables["land"]); | ||
237 | } | ||
238 | catch (Exception e) | ||
239 | { | ||
240 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on land table :{0}", e.Message); | ||
241 | } | ||
242 | |||
243 | try | ||
244 | { | ||
245 | landAccessListDa.Fill(ds.Tables["landaccesslist"]); | ||
246 | } | ||
247 | catch (Exception e) | ||
248 | { | ||
249 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on landaccesslist table :{0}", e.Message); | ||
250 | } | ||
251 | |||
252 | try | ||
253 | { | ||
254 | regionSettingsDa.Fill(ds.Tables["regionsettings"]); | ||
255 | } | ||
256 | catch (Exception e) | ||
257 | { | ||
258 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionsettings table :{0}", e.Message); | ||
259 | } | ||
260 | |||
261 | try | ||
262 | { | ||
263 | regionWindlightDa.Fill(ds.Tables["regionwindlight"]); | ||
264 | } | ||
265 | catch (Exception e) | ||
266 | { | ||
267 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionwindlight table :{0}", e.Message); | ||
268 | } | ||
269 | |||
270 | try | ||
271 | { | ||
272 | regionEnvironmentDa.Fill(ds.Tables["regionenvironment"]); | ||
273 | } | ||
274 | catch (Exception e) | ||
275 | { | ||
276 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on regionenvironment table :{0}", e.Message); | ||
277 | } | ||
278 | |||
279 | try | ||
280 | { | ||
281 | regionSpawnPointsDa.Fill(ds.Tables["spawn_points"]); | ||
282 | } | ||
283 | catch (Exception e) | ||
284 | { | ||
285 | m_log.ErrorFormat("[SQLITE REGION DB]: Caught fill error on spawn_points table :{0}", e.Message); | ||
286 | } | ||
287 | |||
288 | // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! | ||
289 | // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409 | ||
290 | // Possibly because we manually set up our own DataTables before connecting to the database | ||
291 | CreateDataSetMapping(primDa, "prims"); | ||
292 | CreateDataSetMapping(shapeDa, "primshapes"); | ||
293 | CreateDataSetMapping(itemsDa, "primitems"); | ||
294 | CreateDataSetMapping(terrainDa, "terrain"); | ||
295 | CreateDataSetMapping(landDa, "land"); | ||
296 | CreateDataSetMapping(landAccessListDa, "landaccesslist"); | ||
297 | CreateDataSetMapping(regionSettingsDa, "regionsettings"); | ||
298 | CreateDataSetMapping(regionWindlightDa, "regionwindlight"); | ||
299 | CreateDataSetMapping(regionEnvironmentDa, "regionenvironment"); | ||
300 | CreateDataSetMapping(regionSpawnPointsDa, "spawn_points"); | ||
301 | } | ||
302 | } | ||
303 | catch (Exception e) | ||
304 | { | ||
305 | m_log.ErrorFormat("[SQLITE REGION DB]: {0} - {1}", e.Message, e.StackTrace); | ||
306 | Environment.Exit(23); | ||
307 | } | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | public void Dispose() | ||
312 | { | ||
313 | if (m_conn != null) | ||
314 | { | ||
315 | m_conn.Close(); | ||
316 | m_conn = null; | ||
317 | } | ||
318 | if (ds != null) | ||
319 | { | ||
320 | ds.Dispose(); | ||
321 | ds = null; | ||
322 | } | ||
323 | if (primDa != null) | ||
324 | { | ||
325 | primDa.Dispose(); | ||
326 | primDa = null; | ||
327 | } | ||
328 | if (shapeDa != null) | ||
329 | { | ||
330 | shapeDa.Dispose(); | ||
331 | shapeDa = null; | ||
332 | } | ||
333 | if (itemsDa != null) | ||
334 | { | ||
335 | itemsDa.Dispose(); | ||
336 | itemsDa = null; | ||
337 | } | ||
338 | if (terrainDa != null) | ||
339 | { | ||
340 | terrainDa.Dispose(); | ||
341 | terrainDa = null; | ||
342 | } | ||
343 | if (landDa != null) | ||
344 | { | ||
345 | landDa.Dispose(); | ||
346 | landDa = null; | ||
347 | } | ||
348 | if (landAccessListDa != null) | ||
349 | { | ||
350 | landAccessListDa.Dispose(); | ||
351 | landAccessListDa = null; | ||
352 | } | ||
353 | if (regionSettingsDa != null) | ||
354 | { | ||
355 | regionSettingsDa.Dispose(); | ||
356 | regionSettingsDa = null; | ||
357 | } | ||
358 | if (regionWindlightDa != null) | ||
359 | { | ||
360 | regionWindlightDa.Dispose(); | ||
361 | regionWindlightDa = null; | ||
362 | } | ||
363 | if (regionEnvironmentDa != null) | ||
364 | { | ||
365 | regionEnvironmentDa.Dispose(); | ||
366 | regionEnvironmentDa = null; | ||
367 | } | ||
368 | if (regionSpawnPointsDa != null) | ||
369 | { | ||
370 | regionSpawnPointsDa.Dispose(); | ||
371 | regionWindlightDa = null; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | public void StoreRegionSettings(RegionSettings rs) | ||
376 | { | ||
377 | lock (ds) | ||
378 | { | ||
379 | DataTable regionsettings = ds.Tables["regionsettings"]; | ||
380 | |||
381 | DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString()); | ||
382 | if (settingsRow == null) | ||
383 | { | ||
384 | settingsRow = regionsettings.NewRow(); | ||
385 | fillRegionSettingsRow(settingsRow, rs); | ||
386 | regionsettings.Rows.Add(settingsRow); | ||
387 | } | ||
388 | else | ||
389 | { | ||
390 | fillRegionSettingsRow(settingsRow, rs); | ||
391 | } | ||
392 | |||
393 | StoreSpawnPoints(rs); | ||
394 | |||
395 | Commit(); | ||
396 | } | ||
397 | |||
398 | } | ||
399 | |||
400 | public void StoreSpawnPoints(RegionSettings rs) | ||
401 | { | ||
402 | lock (ds) | ||
403 | { | ||
404 | // DataTable spawnpoints = ds.Tables["spawn_points"]; | ||
405 | |||
406 | // remove region's spawnpoints | ||
407 | using ( | ||
408 | SqliteCommand cmd = | ||
409 | new SqliteCommand("delete from spawn_points where RegionID=:RegionID", | ||
410 | m_conn)) | ||
411 | { | ||
412 | |||
413 | cmd.Parameters.Add(new SqliteParameter(":RegionID", rs.RegionUUID.ToString())); | ||
414 | cmd.ExecuteNonQuery(); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | foreach (SpawnPoint sp in rs.SpawnPoints()) | ||
419 | { | ||
420 | using (SqliteCommand cmd = new SqliteCommand("insert into spawn_points(RegionID, Yaw, Pitch, Distance)" + | ||
421 | "values ( :RegionID, :Yaw, :Pitch, :Distance)", m_conn)) | ||
422 | { | ||
423 | cmd.Parameters.Add(new SqliteParameter(":RegionID", rs.RegionUUID.ToString())); | ||
424 | cmd.Parameters.Add(new SqliteParameter(":Yaw", sp.Yaw)); | ||
425 | cmd.Parameters.Add(new SqliteParameter(":Pitch", sp.Pitch)); | ||
426 | cmd.Parameters.Add(new SqliteParameter(":Distance", sp.Distance)); | ||
427 | cmd.ExecuteNonQuery(); | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /// <summary> | ||
433 | /// Load windlight settings from region storage | ||
434 | /// </summary> | ||
435 | /// <param name="regionUUID">RegionID</param> | ||
436 | public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) | ||
437 | { | ||
438 | RegionLightShareData wl = null; | ||
439 | |||
440 | lock (ds) | ||
441 | { | ||
442 | DataTable windlightTable = ds.Tables["regionwindlight"]; | ||
443 | DataRow windlightRow = windlightTable.Rows.Find(regionUUID.ToString()); | ||
444 | if (windlightRow == null) | ||
445 | { | ||
446 | wl = new RegionLightShareData(); | ||
447 | wl.regionID = regionUUID; | ||
448 | StoreRegionWindlightSettings(wl); | ||
449 | return wl; | ||
450 | } | ||
451 | wl = buildRegionWindlight(windlightRow); | ||
452 | return wl; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | /// <summary> | ||
457 | /// Remove windlight settings from region storage | ||
458 | /// </summary> | ||
459 | /// <param name="regionID">RegionID</param> | ||
460 | public void RemoveRegionWindlightSettings(UUID regionID) | ||
461 | { | ||
462 | lock (ds) | ||
463 | { | ||
464 | DataTable windlightTable = ds.Tables["regionwindlight"]; | ||
465 | DataRow windlightRow = windlightTable.Rows.Find(regionID.ToString()); | ||
466 | |||
467 | if (windlightRow != null) | ||
468 | { | ||
469 | windlightRow.Delete(); | ||
470 | } | ||
471 | } | ||
472 | Commit(); | ||
473 | } | ||
474 | |||
475 | /// <summary> | ||
476 | /// Adds an windlight into region storage | ||
477 | /// </summary> | ||
478 | /// <param name="wl">RegionLightShareData</param> | ||
479 | public void StoreRegionWindlightSettings(RegionLightShareData wl) | ||
480 | { | ||
481 | lock (ds) | ||
482 | { | ||
483 | DataTable windlightTable = ds.Tables["regionwindlight"]; | ||
484 | DataRow windlightRow = windlightTable.Rows.Find(wl.regionID.ToString()); | ||
485 | |||
486 | if (windlightRow == null) | ||
487 | { | ||
488 | windlightRow = windlightTable.NewRow(); | ||
489 | fillRegionWindlightRow(windlightRow, wl); | ||
490 | windlightTable.Rows.Add(windlightRow); | ||
491 | } | ||
492 | else | ||
493 | { | ||
494 | fillRegionWindlightRow(windlightRow, wl); | ||
495 | } | ||
496 | |||
497 | Commit(); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | #region Region Environment Settings | ||
502 | public string LoadRegionEnvironmentSettings(UUID regionUUID) | ||
503 | { | ||
504 | lock (ds) | ||
505 | { | ||
506 | DataTable environmentTable = ds.Tables["regionenvironment"]; | ||
507 | DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); | ||
508 | if (row == null) | ||
509 | { | ||
510 | return String.Empty; | ||
511 | } | ||
512 | |||
513 | return (String)row["llsd_settings"]; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) | ||
518 | { | ||
519 | lock (ds) | ||
520 | { | ||
521 | DataTable environmentTable = ds.Tables["regionenvironment"]; | ||
522 | DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); | ||
523 | |||
524 | if (row == null) | ||
525 | { | ||
526 | row = environmentTable.NewRow(); | ||
527 | row["region_id"] = regionUUID.ToString(); | ||
528 | row["llsd_settings"] = settings; | ||
529 | environmentTable.Rows.Add(row); | ||
530 | } | ||
531 | else | ||
532 | { | ||
533 | row["llsd_settings"] = settings; | ||
534 | } | ||
535 | |||
536 | regionEnvironmentDa.Update(ds, "regionenvironment"); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | public void RemoveRegionEnvironmentSettings(UUID regionUUID) | ||
541 | { | ||
542 | lock (ds) | ||
543 | { | ||
544 | DataTable environmentTable = ds.Tables["regionenvironment"]; | ||
545 | DataRow row = environmentTable.Rows.Find(regionUUID.ToString()); | ||
546 | |||
547 | if (row != null) | ||
548 | { | ||
549 | row.Delete(); | ||
550 | } | ||
551 | |||
552 | regionEnvironmentDa.Update(ds, "regionenvironment"); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | #endregion | ||
557 | |||
558 | public RegionSettings LoadRegionSettings(UUID regionUUID) | ||
559 | { | ||
560 | lock (ds) | ||
561 | { | ||
562 | DataTable regionsettings = ds.Tables["regionsettings"]; | ||
563 | |||
564 | string searchExp = "regionUUID = '" + regionUUID.ToString() + "'"; | ||
565 | DataRow[] rawsettings = regionsettings.Select(searchExp); | ||
566 | if (rawsettings.Length == 0) | ||
567 | { | ||
568 | RegionSettings rs = new RegionSettings(); | ||
569 | rs.RegionUUID = regionUUID; | ||
570 | rs.OnSave += StoreRegionSettings; | ||
571 | |||
572 | StoreRegionSettings(rs); | ||
573 | |||
574 | return rs; | ||
575 | } | ||
576 | DataRow row = rawsettings[0]; | ||
577 | |||
578 | RegionSettings newSettings = buildRegionSettings(row); | ||
579 | newSettings.OnSave += StoreRegionSettings; | ||
580 | |||
581 | LoadSpawnPoints(newSettings); | ||
582 | |||
583 | return newSettings; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | private void LoadSpawnPoints(RegionSettings rs) | ||
588 | { | ||
589 | rs.ClearSpawnPoints(); | ||
590 | |||
591 | DataTable spawnpoints = ds.Tables["spawn_points"]; | ||
592 | string byRegion = "RegionID = '" + rs.RegionUUID + "'"; | ||
593 | DataRow[] spForRegion = spawnpoints.Select(byRegion); | ||
594 | |||
595 | foreach (DataRow spRow in spForRegion) | ||
596 | { | ||
597 | SpawnPoint sp = new SpawnPoint(); | ||
598 | sp.Pitch = (float)spRow["Pitch"]; | ||
599 | sp.Yaw = (float)spRow["Yaw"]; | ||
600 | sp.Distance = (float)spRow["Distance"]; | ||
601 | |||
602 | rs.AddSpawnPoint(sp); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | /// <summary> | ||
607 | /// Adds an object into region storage | ||
608 | /// </summary> | ||
609 | /// <param name="obj">the object</param> | ||
610 | /// <param name="regionUUID">the region UUID</param> | ||
611 | public void StoreObject(SceneObjectGroup obj, UUID regionUUID) | ||
612 | { | ||
613 | uint flags = obj.RootPart.GetEffectiveObjectFlags(); | ||
614 | |||
615 | // Eligibility check | ||
616 | // | ||
617 | if ((flags & (uint)PrimFlags.Temporary) != 0) | ||
618 | return; | ||
619 | if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0) | ||
620 | return; | ||
621 | |||
622 | lock (ds) | ||
623 | { | ||
624 | foreach (SceneObjectPart prim in obj.Parts) | ||
625 | { | ||
626 | // m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); | ||
627 | addPrim(prim, obj.UUID, regionUUID); | ||
628 | } | ||
629 | } | ||
630 | |||
631 | Commit(); | ||
632 | // m_log.Info("[Dump of prims]: " + ds.GetXml()); | ||
633 | } | ||
634 | |||
635 | /// <summary> | ||
636 | /// Removes an object from region storage | ||
637 | /// </summary> | ||
638 | /// <param name="obj">the object</param> | ||
639 | /// <param name="regionUUID">the region UUID</param> | ||
640 | public void RemoveObject(UUID obj, UUID regionUUID) | ||
641 | { | ||
642 | // m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID); | ||
643 | |||
644 | DataTable prims = ds.Tables["prims"]; | ||
645 | DataTable shapes = ds.Tables["primshapes"]; | ||
646 | |||
647 | string selectExp = "SceneGroupID = '" + obj + "' and RegionUUID = '" + regionUUID + "'"; | ||
648 | lock (ds) | ||
649 | { | ||
650 | DataRow[] primRows = prims.Select(selectExp); | ||
651 | foreach (DataRow row in primRows) | ||
652 | { | ||
653 | // Remove shape rows | ||
654 | UUID uuid = new UUID((string)row["UUID"]); | ||
655 | DataRow shapeRow = shapes.Rows.Find(uuid.ToString()); | ||
656 | if (shapeRow != null) | ||
657 | { | ||
658 | shapeRow.Delete(); | ||
659 | } | ||
660 | |||
661 | RemoveItems(uuid); | ||
662 | |||
663 | // Remove prim row | ||
664 | row.Delete(); | ||
665 | } | ||
666 | } | ||
667 | |||
668 | Commit(); | ||
669 | } | ||
670 | |||
671 | /// <summary> | ||
672 | /// Remove all persisted items of the given prim. | ||
673 | /// The caller must acquire the necessrary synchronization locks and commit or rollback changes. | ||
674 | /// </summary> | ||
675 | /// <param name="uuid">The item UUID</param> | ||
676 | private void RemoveItems(UUID uuid) | ||
677 | { | ||
678 | DataTable items = ds.Tables["primitems"]; | ||
679 | |||
680 | String sql = String.Format("primID = '{0}'", uuid); | ||
681 | DataRow[] itemRows = items.Select(sql); | ||
682 | |||
683 | foreach (DataRow itemRow in itemRows) | ||
684 | { | ||
685 | itemRow.Delete(); | ||
686 | } | ||
687 | } | ||
688 | |||
689 | /// <summary> | ||
690 | /// Load persisted objects from region storage. | ||
691 | /// </summary> | ||
692 | /// <param name="regionUUID">The region UUID</param> | ||
693 | /// <returns>List of loaded groups</returns> | ||
694 | public List<SceneObjectGroup> LoadObjects(UUID regionUUID) | ||
695 | { | ||
696 | Dictionary<UUID, SceneObjectGroup> createdObjects = new Dictionary<UUID, SceneObjectGroup>(); | ||
697 | |||
698 | List<SceneObjectGroup> retvals = new List<SceneObjectGroup>(); | ||
699 | |||
700 | DataTable prims = ds.Tables["prims"]; | ||
701 | DataTable shapes = ds.Tables["primshapes"]; | ||
702 | |||
703 | string byRegion = "RegionUUID = '" + regionUUID + "'"; | ||
704 | |||
705 | lock (ds) | ||
706 | { | ||
707 | DataRow[] primsForRegion = prims.Select(byRegion); | ||
708 | // m_log.Info("[SQLITE REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); | ||
709 | |||
710 | // First, create all groups | ||
711 | foreach (DataRow primRow in primsForRegion) | ||
712 | { | ||
713 | try | ||
714 | { | ||
715 | SceneObjectPart prim = null; | ||
716 | |||
717 | string uuid = (string)primRow["UUID"]; | ||
718 | string objID = (string)primRow["SceneGroupID"]; | ||
719 | |||
720 | if (uuid == objID) //is new SceneObjectGroup ? | ||
721 | { | ||
722 | prim = buildPrim(primRow); | ||
723 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); | ||
724 | if (shapeRow != null) | ||
725 | { | ||
726 | prim.Shape = buildShape(shapeRow); | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | m_log.Warn( | ||
731 | "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape"); | ||
732 | prim.Shape = PrimitiveBaseShape.Default; | ||
733 | } | ||
734 | |||
735 | SceneObjectGroup group = new SceneObjectGroup(prim); | ||
736 | |||
737 | createdObjects.Add(group.UUID, group); | ||
738 | retvals.Add(group); | ||
739 | LoadItems(prim); | ||
740 | |||
741 | |||
742 | } | ||
743 | } | ||
744 | catch (Exception e) | ||
745 | { | ||
746 | m_log.Error("[SQLITE REGION DB]: Failed create prim object in new group, exception and data follows"); | ||
747 | m_log.Error("[SQLITE REGION DB]: ", e); | ||
748 | foreach (DataColumn col in prims.Columns) | ||
749 | { | ||
750 | m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); | ||
751 | } | ||
752 | } | ||
753 | } | ||
754 | |||
755 | // Now fill the groups with part data | ||
756 | foreach (DataRow primRow in primsForRegion) | ||
757 | { | ||
758 | try | ||
759 | { | ||
760 | SceneObjectPart prim = null; | ||
761 | |||
762 | string uuid = (string)primRow["UUID"]; | ||
763 | string objID = (string)primRow["SceneGroupID"]; | ||
764 | if (uuid != objID) //is new SceneObjectGroup ? | ||
765 | { | ||
766 | prim = buildPrim(primRow); | ||
767 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); | ||
768 | if (shapeRow != null) | ||
769 | { | ||
770 | prim.Shape = buildShape(shapeRow); | ||
771 | } | ||
772 | else | ||
773 | { | ||
774 | m_log.Warn( | ||
775 | "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape"); | ||
776 | prim.Shape = PrimitiveBaseShape.Default; | ||
777 | } | ||
778 | |||
779 | createdObjects[new UUID(objID)].AddPart(prim); | ||
780 | LoadItems(prim); | ||
781 | } | ||
782 | } | ||
783 | catch (Exception e) | ||
784 | { | ||
785 | m_log.Error("[SQLITE REGION DB]: Failed create prim object in group, exception and data follows"); | ||
786 | m_log.Error("[SQLITE REGION DB]: ", e); | ||
787 | foreach (DataColumn col in prims.Columns) | ||
788 | { | ||
789 | m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); | ||
790 | } | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | return retvals; | ||
795 | } | ||
796 | |||
797 | /// <summary> | ||
798 | /// Load in a prim's persisted inventory. | ||
799 | /// </summary> | ||
800 | /// <param name="prim">the prim</param> | ||
801 | private void LoadItems(SceneObjectPart prim) | ||
802 | { | ||
803 | // m_log.DebugFormat("[SQLITE REGION DB]: Loading inventory for {0} {1}", prim.Name, prim.UUID); | ||
804 | |||
805 | DataTable dbItems = ds.Tables["primitems"]; | ||
806 | String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); | ||
807 | DataRow[] dbItemRows = dbItems.Select(sql); | ||
808 | IList<TaskInventoryItem> inventory = new List<TaskInventoryItem>(); | ||
809 | |||
810 | // m_log.DebugFormat("[SQLITE REGION DB]: Found {0} items for {1} {2}", dbItemRows.Length, prim.Name, prim.UUID); | ||
811 | |||
812 | foreach (DataRow row in dbItemRows) | ||
813 | { | ||
814 | TaskInventoryItem item = buildItem(row); | ||
815 | inventory.Add(item); | ||
816 | |||
817 | // m_log.DebugFormat("[SQLITE REGION DB]: Restored item {0} {1}", item.Name, item.ItemID); | ||
818 | } | ||
819 | |||
820 | prim.Inventory.RestoreInventoryItems(inventory); | ||
821 | } | ||
822 | |||
823 | // Legacy entry point for when terrain was always a 256x256 hieghtmap | ||
824 | public void StoreTerrain(double[,] ter, UUID regionID) | ||
825 | { | ||
826 | StoreTerrain(new HeightmapTerrainData(ter), regionID); | ||
827 | } | ||
828 | |||
829 | /// <summary> | ||
830 | /// Store a terrain in region storage | ||
831 | /// </summary> | ||
832 | /// <param name="ter">terrain heightfield</param> | ||
833 | /// <param name="regionID">region UUID</param> | ||
834 | public void StoreTerrain(TerrainData terrData, UUID regionID) | ||
835 | { | ||
836 | lock (ds) | ||
837 | { | ||
838 | using ( | ||
839 | SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn)) | ||
840 | { | ||
841 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
842 | cmd.ExecuteNonQuery(); | ||
843 | } | ||
844 | |||
845 | // the following is an work around for .NET. The perf | ||
846 | // issues associated with it aren't as bad as you think. | ||
847 | String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + | ||
848 | " values(:RegionUUID, :Revision, :Heightfield)"; | ||
849 | |||
850 | int terrainDBRevision; | ||
851 | Array terrainDBblob; | ||
852 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
853 | |||
854 | m_log.DebugFormat("{0} Storing terrain format {1}", LogHeader, terrainDBRevision); | ||
855 | |||
856 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | ||
857 | { | ||
858 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
859 | cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); | ||
860 | cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); | ||
861 | cmd.ExecuteNonQuery(); | ||
862 | } | ||
863 | } | ||
864 | } | ||
865 | |||
866 | /// <summary> | ||
867 | /// Store baked terrain in region storage | ||
868 | /// </summary> | ||
869 | /// <param name="ter">terrain heightfield</param> | ||
870 | /// <param name="regionID">region UUID</param> | ||
871 | public void StoreBakedTerrain(TerrainData terrData, UUID regionID) | ||
872 | { | ||
873 | lock (ds) | ||
874 | { | ||
875 | using ( | ||
876 | SqliteCommand cmd = new SqliteCommand("delete from bakedterrain where RegionUUID=:RegionUUID", m_conn)) | ||
877 | { | ||
878 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
879 | cmd.ExecuteNonQuery(); | ||
880 | } | ||
881 | |||
882 | // the following is an work around for .NET. The perf | ||
883 | // issues associated with it aren't as bad as you think. | ||
884 | String sql = "insert into bakedterrain(RegionUUID, Revision, Heightfield)" + | ||
885 | " values(:RegionUUID, :Revision, :Heightfield)"; | ||
886 | |||
887 | int terrainDBRevision; | ||
888 | Array terrainDBblob; | ||
889 | terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); | ||
890 | |||
891 | m_log.DebugFormat("{0} Storing bakedterrain format {1}", LogHeader, terrainDBRevision); | ||
892 | |||
893 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | ||
894 | { | ||
895 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
896 | cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision)); | ||
897 | cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob)); | ||
898 | cmd.ExecuteNonQuery(); | ||
899 | } | ||
900 | } | ||
901 | } | ||
902 | |||
903 | /// <summary> | ||
904 | /// Load the latest terrain revision from region storage | ||
905 | /// </summary> | ||
906 | /// <param name="regionID">the region UUID</param> | ||
907 | /// <returns>Heightfield data</returns> | ||
908 | public double[,] LoadTerrain(UUID regionID) | ||
909 | { | ||
910 | double[,] ret = null; | ||
911 | TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight); | ||
912 | if (terrData != null) | ||
913 | ret = terrData.GetDoubles(); | ||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | // Returns 'null' if region not found | ||
918 | public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
919 | { | ||
920 | TerrainData terrData = null; | ||
921 | |||
922 | lock (ds) | ||
923 | { | ||
924 | String sql = "select RegionUUID, Revision, Heightfield from terrain" + | ||
925 | " where RegionUUID=:RegionUUID order by Revision desc"; | ||
926 | |||
927 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | ||
928 | { | ||
929 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
930 | |||
931 | using (IDataReader row = cmd.ExecuteReader()) | ||
932 | { | ||
933 | int rev = 0; | ||
934 | if (row.Read()) | ||
935 | { | ||
936 | rev = Convert.ToInt32(row["Revision"]); | ||
937 | byte[] blob = (byte[])row["Heightfield"]; | ||
938 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
939 | } | ||
940 | else | ||
941 | { | ||
942 | m_log.Warn("[SQLITE REGION DB]: No terrain found for region"); | ||
943 | return null; | ||
944 | } | ||
945 | |||
946 | m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); | ||
947 | } | ||
948 | } | ||
949 | } | ||
950 | return terrData; | ||
951 | } | ||
952 | |||
953 | public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) | ||
954 | { | ||
955 | TerrainData terrData = null; | ||
956 | |||
957 | lock (ds) | ||
958 | { | ||
959 | String sql = "select RegionUUID, Revision, Heightfield from bakedterrain" + | ||
960 | " where RegionUUID=:RegionUUID"; | ||
961 | |||
962 | using (SqliteCommand cmd = new SqliteCommand(sql, m_conn)) | ||
963 | { | ||
964 | cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString())); | ||
965 | |||
966 | using (IDataReader row = cmd.ExecuteReader()) | ||
967 | { | ||
968 | int rev = 0; | ||
969 | if (row.Read()) | ||
970 | { | ||
971 | rev = Convert.ToInt32(row["Revision"]); | ||
972 | byte[] blob = (byte[])row["Heightfield"]; | ||
973 | terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); | ||
974 | } | ||
975 | } | ||
976 | } | ||
977 | } | ||
978 | return terrData; | ||
979 | } | ||
980 | |||
981 | public void RemoveLandObject(UUID globalID) | ||
982 | { | ||
983 | lock (ds) | ||
984 | { | ||
985 | // Can't use blanket SQL statements when using SqlAdapters unless you re-read the data into the adapter | ||
986 | // after you're done. | ||
987 | // replaced below code with the SqliteAdapter version. | ||
988 | //using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn)) | ||
989 | //{ | ||
990 | // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString())); | ||
991 | // cmd.ExecuteNonQuery(); | ||
992 | //} | ||
993 | |||
994 | //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn)) | ||
995 | //{ | ||
996 | // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString())); | ||
997 | // cmd.ExecuteNonQuery(); | ||
998 | //} | ||
999 | |||
1000 | DataTable land = ds.Tables["land"]; | ||
1001 | DataTable landaccesslist = ds.Tables["landaccesslist"]; | ||
1002 | DataRow landRow = land.Rows.Find(globalID.ToString()); | ||
1003 | if (landRow != null) | ||
1004 | { | ||
1005 | landRow.Delete(); | ||
1006 | } | ||
1007 | List<DataRow> rowsToDelete = new List<DataRow>(); | ||
1008 | foreach (DataRow rowToCheck in landaccesslist.Rows) | ||
1009 | { | ||
1010 | if (rowToCheck["LandUUID"].ToString() == globalID.ToString()) | ||
1011 | rowsToDelete.Add(rowToCheck); | ||
1012 | } | ||
1013 | for (int iter = 0; iter < rowsToDelete.Count; iter++) | ||
1014 | { | ||
1015 | rowsToDelete[iter].Delete(); | ||
1016 | } | ||
1017 | } | ||
1018 | Commit(); | ||
1019 | } | ||
1020 | |||
1021 | /// <summary> | ||
1022 | /// | ||
1023 | /// </summary> | ||
1024 | /// <param name="parcel"></param> | ||
1025 | public void StoreLandObject(ILandObject parcel) | ||
1026 | { | ||
1027 | lock (ds) | ||
1028 | { | ||
1029 | DataTable land = ds.Tables["land"]; | ||
1030 | DataTable landaccesslist = ds.Tables["landaccesslist"]; | ||
1031 | |||
1032 | DataRow landRow = land.Rows.Find(parcel.LandData.GlobalID.ToString()); | ||
1033 | if (landRow == null) | ||
1034 | { | ||
1035 | landRow = land.NewRow(); | ||
1036 | fillLandRow(landRow, parcel.LandData, parcel.RegionUUID); | ||
1037 | land.Rows.Add(landRow); | ||
1038 | } | ||
1039 | else | ||
1040 | { | ||
1041 | fillLandRow(landRow, parcel.LandData, parcel.RegionUUID); | ||
1042 | } | ||
1043 | |||
1044 | // I know this caused someone issues before, but OpenSim is unusable if we leave this stuff around | ||
1045 | //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn)) | ||
1046 | //{ | ||
1047 | // cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.LandData.GlobalID.ToString())); | ||
1048 | // cmd.ExecuteNonQuery(); | ||
1049 | |||
1050 | // } | ||
1051 | |||
1052 | // This is the slower.. but more appropriate thing to do | ||
1053 | |||
1054 | // We can't modify the table with direct queries before calling Commit() and re-filling them. | ||
1055 | List<DataRow> rowsToDelete = new List<DataRow>(); | ||
1056 | foreach (DataRow rowToCheck in landaccesslist.Rows) | ||
1057 | { | ||
1058 | if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString()) | ||
1059 | rowsToDelete.Add(rowToCheck); | ||
1060 | } | ||
1061 | for (int iter = 0; iter < rowsToDelete.Count; iter++) | ||
1062 | { | ||
1063 | rowsToDelete[iter].Delete(); | ||
1064 | landaccesslist.Rows.Remove(rowsToDelete[iter]); | ||
1065 | } | ||
1066 | rowsToDelete.Clear(); | ||
1067 | foreach (LandAccessEntry entry in parcel.LandData.ParcelAccessList) | ||
1068 | { | ||
1069 | DataRow newAccessRow = landaccesslist.NewRow(); | ||
1070 | fillLandAccessRow(newAccessRow, entry, parcel.LandData.GlobalID); | ||
1071 | landaccesslist.Rows.Add(newAccessRow); | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | Commit(); | ||
1076 | } | ||
1077 | |||
1078 | /// <summary> | ||
1079 | /// | ||
1080 | /// </summary> | ||
1081 | /// <param name="regionUUID"></param> | ||
1082 | /// <returns></returns> | ||
1083 | public List<LandData> LoadLandObjects(UUID regionUUID) | ||
1084 | { | ||
1085 | List<LandData> landDataForRegion = new List<LandData>(); | ||
1086 | lock (ds) | ||
1087 | { | ||
1088 | DataTable land = ds.Tables["land"]; | ||
1089 | DataTable landaccesslist = ds.Tables["landaccesslist"]; | ||
1090 | string searchExp = "RegionUUID = '" + regionUUID + "'"; | ||
1091 | DataRow[] rawDataForRegion = land.Select(searchExp); | ||
1092 | foreach (DataRow rawDataLand in rawDataForRegion) | ||
1093 | { | ||
1094 | LandData newLand = buildLandData(rawDataLand); | ||
1095 | string accessListSearchExp = "LandUUID = '" + newLand.GlobalID + "'"; | ||
1096 | DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp); | ||
1097 | foreach (DataRow rawDataLandAccess in rawDataForLandAccessList) | ||
1098 | { | ||
1099 | newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess)); | ||
1100 | } | ||
1101 | |||
1102 | landDataForRegion.Add(newLand); | ||
1103 | } | ||
1104 | } | ||
1105 | return landDataForRegion; | ||
1106 | } | ||
1107 | |||
1108 | /// <summary> | ||
1109 | /// | ||
1110 | /// </summary> | ||
1111 | public void Commit() | ||
1112 | { | ||
1113 | // m_log.Debug("[SQLITE]: Starting commit"); | ||
1114 | lock (ds) | ||
1115 | { | ||
1116 | primDa.Update(ds, "prims"); | ||
1117 | shapeDa.Update(ds, "primshapes"); | ||
1118 | |||
1119 | itemsDa.Update(ds, "primitems"); | ||
1120 | |||
1121 | terrainDa.Update(ds, "terrain"); | ||
1122 | landDa.Update(ds, "land"); | ||
1123 | landAccessListDa.Update(ds, "landaccesslist"); | ||
1124 | try | ||
1125 | { | ||
1126 | regionSettingsDa.Update(ds, "regionsettings"); | ||
1127 | regionWindlightDa.Update(ds, "regionwindlight"); | ||
1128 | } | ||
1129 | catch (SqliteException SqlEx) | ||
1130 | { | ||
1131 | throw new Exception( | ||
1132 | "There was a SQL error or connection string configuration error when saving the region settings. This could be a bug, it could also happen if ConnectionString is defined in the [DatabaseService] section of StandaloneCommon.ini in the config_include folder. This could also happen if the config_include folder doesn't exist or if the OpenSim.ini [Architecture] section isn't set. If this is your first time running OpenSimulator, please restart the simulator and bug a developer to fix this!", | ||
1133 | SqlEx); | ||
1134 | } | ||
1135 | ds.AcceptChanges(); | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | /// <summary> | ||
1140 | /// See <see cref="Commit"/> | ||
1141 | /// </summary> | ||
1142 | public void Shutdown() | ||
1143 | { | ||
1144 | Commit(); | ||
1145 | } | ||
1146 | |||
1147 | /*********************************************************************** | ||
1148 | * | ||
1149 | * Database Definition Functions | ||
1150 | * | ||
1151 | * This should be db agnostic as we define them in ADO.NET terms | ||
1152 | * | ||
1153 | **********************************************************************/ | ||
1154 | |||
1155 | protected void CreateDataSetMapping(IDataAdapter da, string tableName) | ||
1156 | { | ||
1157 | ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); | ||
1158 | foreach (DataColumn col in ds.Tables[tableName].Columns) | ||
1159 | { | ||
1160 | dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | /// <summary> | ||
1165 | /// | ||
1166 | /// </summary> | ||
1167 | /// <param name="dt"></param> | ||
1168 | /// <param name="name"></param> | ||
1169 | /// <param name="type"></param> | ||
1170 | private static void createCol(DataTable dt, string name, Type type) | ||
1171 | { | ||
1172 | DataColumn col = new DataColumn(name, type); | ||
1173 | dt.Columns.Add(col); | ||
1174 | } | ||
1175 | |||
1176 | /// <summary> | ||
1177 | /// Creates the "terrain" table | ||
1178 | /// </summary> | ||
1179 | /// <returns>terrain table DataTable</returns> | ||
1180 | private static DataTable createTerrainTable() | ||
1181 | { | ||
1182 | DataTable terrain = new DataTable("terrain"); | ||
1183 | |||
1184 | createCol(terrain, "RegionUUID", typeof(String)); | ||
1185 | createCol(terrain, "Revision", typeof(Int32)); | ||
1186 | createCol(terrain, "Heightfield", typeof(Byte[])); | ||
1187 | |||
1188 | return terrain; | ||
1189 | } | ||
1190 | |||
1191 | /// <summary> | ||
1192 | /// Creates the "prims" table | ||
1193 | /// </summary> | ||
1194 | /// <returns>prim table DataTable</returns> | ||
1195 | private static DataTable createPrimTable() | ||
1196 | { | ||
1197 | DataTable prims = new DataTable("prims"); | ||
1198 | |||
1199 | createCol(prims, "UUID", typeof(String)); | ||
1200 | createCol(prims, "RegionUUID", typeof(String)); | ||
1201 | createCol(prims, "CreationDate", typeof(Int32)); | ||
1202 | createCol(prims, "Name", typeof(String)); | ||
1203 | createCol(prims, "SceneGroupID", typeof(String)); | ||
1204 | // various text fields | ||
1205 | createCol(prims, "Text", typeof(String)); | ||
1206 | createCol(prims, "ColorR", typeof(Int32)); | ||
1207 | createCol(prims, "ColorG", typeof(Int32)); | ||
1208 | createCol(prims, "ColorB", typeof(Int32)); | ||
1209 | createCol(prims, "ColorA", typeof(Int32)); | ||
1210 | createCol(prims, "Description", typeof(String)); | ||
1211 | createCol(prims, "SitName", typeof(String)); | ||
1212 | createCol(prims, "TouchName", typeof(String)); | ||
1213 | // permissions | ||
1214 | createCol(prims, "ObjectFlags", typeof(Int32)); | ||
1215 | createCol(prims, "CreatorID", typeof(String)); | ||
1216 | createCol(prims, "OwnerID", typeof(String)); | ||
1217 | createCol(prims, "GroupID", typeof(String)); | ||
1218 | createCol(prims, "LastOwnerID", typeof(String)); | ||
1219 | createCol(prims, "RezzerID", typeof(String)); | ||
1220 | createCol(prims, "OwnerMask", typeof(Int32)); | ||
1221 | createCol(prims, "NextOwnerMask", typeof(Int32)); | ||
1222 | createCol(prims, "GroupMask", typeof(Int32)); | ||
1223 | createCol(prims, "EveryoneMask", typeof(Int32)); | ||
1224 | createCol(prims, "BaseMask", typeof(Int32)); | ||
1225 | // vectors | ||
1226 | createCol(prims, "PositionX", typeof(Double)); | ||
1227 | createCol(prims, "PositionY", typeof(Double)); | ||
1228 | createCol(prims, "PositionZ", typeof(Double)); | ||
1229 | createCol(prims, "GroupPositionX", typeof(Double)); | ||
1230 | createCol(prims, "GroupPositionY", typeof(Double)); | ||
1231 | createCol(prims, "GroupPositionZ", typeof(Double)); | ||
1232 | createCol(prims, "VelocityX", typeof(Double)); | ||
1233 | createCol(prims, "VelocityY", typeof(Double)); | ||
1234 | createCol(prims, "VelocityZ", typeof(Double)); | ||
1235 | createCol(prims, "AngularVelocityX", typeof(Double)); | ||
1236 | createCol(prims, "AngularVelocityY", typeof(Double)); | ||
1237 | createCol(prims, "AngularVelocityZ", typeof(Double)); | ||
1238 | createCol(prims, "AccelerationX", typeof(Double)); | ||
1239 | createCol(prims, "AccelerationY", typeof(Double)); | ||
1240 | createCol(prims, "AccelerationZ", typeof(Double)); | ||
1241 | // quaternions | ||
1242 | createCol(prims, "RotationX", typeof(Double)); | ||
1243 | createCol(prims, "RotationY", typeof(Double)); | ||
1244 | createCol(prims, "RotationZ", typeof(Double)); | ||
1245 | createCol(prims, "RotationW", typeof(Double)); | ||
1246 | |||
1247 | // sit target | ||
1248 | createCol(prims, "SitTargetOffsetX", typeof(Double)); | ||
1249 | createCol(prims, "SitTargetOffsetY", typeof(Double)); | ||
1250 | createCol(prims, "SitTargetOffsetZ", typeof(Double)); | ||
1251 | |||
1252 | createCol(prims, "SitTargetOrientW", typeof(Double)); | ||
1253 | createCol(prims, "SitTargetOrientX", typeof(Double)); | ||
1254 | createCol(prims, "SitTargetOrientY", typeof(Double)); | ||
1255 | createCol(prims, "SitTargetOrientZ", typeof(Double)); | ||
1256 | |||
1257 | createCol(prims, "PayPrice", typeof(Int32)); | ||
1258 | createCol(prims, "PayButton1", typeof(Int32)); | ||
1259 | createCol(prims, "PayButton2", typeof(Int32)); | ||
1260 | createCol(prims, "PayButton3", typeof(Int32)); | ||
1261 | createCol(prims, "PayButton4", typeof(Int32)); | ||
1262 | |||
1263 | createCol(prims, "LoopedSound", typeof(String)); | ||
1264 | createCol(prims, "LoopedSoundGain", typeof(Double)); | ||
1265 | createCol(prims, "TextureAnimation", typeof(String)); | ||
1266 | createCol(prims, "ParticleSystem", typeof(String)); | ||
1267 | |||
1268 | createCol(prims, "OmegaX", typeof(Double)); | ||
1269 | createCol(prims, "OmegaY", typeof(Double)); | ||
1270 | createCol(prims, "OmegaZ", typeof(Double)); | ||
1271 | |||
1272 | createCol(prims, "CameraEyeOffsetX", typeof(Double)); | ||
1273 | createCol(prims, "CameraEyeOffsetY", typeof(Double)); | ||
1274 | createCol(prims, "CameraEyeOffsetZ", typeof(Double)); | ||
1275 | |||
1276 | createCol(prims, "CameraAtOffsetX", typeof(Double)); | ||
1277 | createCol(prims, "CameraAtOffsetY", typeof(Double)); | ||
1278 | createCol(prims, "CameraAtOffsetZ", typeof(Double)); | ||
1279 | |||
1280 | createCol(prims, "ForceMouselook", typeof(Int16)); | ||
1281 | |||
1282 | createCol(prims, "ScriptAccessPin", typeof(Int32)); | ||
1283 | |||
1284 | createCol(prims, "AllowedDrop", typeof(Int16)); | ||
1285 | createCol(prims, "DieAtEdge", typeof(Int16)); | ||
1286 | |||
1287 | createCol(prims, "SalePrice", typeof(Int32)); | ||
1288 | createCol(prims, "SaleType", typeof(Int16)); | ||
1289 | |||
1290 | // click action | ||
1291 | createCol(prims, "ClickAction", typeof(Byte)); | ||
1292 | |||
1293 | createCol(prims, "Material", typeof(Byte)); | ||
1294 | |||
1295 | createCol(prims, "CollisionSound", typeof(String)); | ||
1296 | createCol(prims, "CollisionSoundVolume", typeof(Double)); | ||
1297 | |||
1298 | createCol(prims, "VolumeDetect", typeof(Int16)); | ||
1299 | |||
1300 | createCol(prims, "MediaURL", typeof(String)); | ||
1301 | |||
1302 | createCol(prims, "AttachedPosX", typeof(Double)); | ||
1303 | createCol(prims, "AttachedPosY", typeof(Double)); | ||
1304 | createCol(prims, "AttachedPosZ", typeof(Double)); | ||
1305 | |||
1306 | createCol(prims, "DynAttrs", typeof(String)); | ||
1307 | |||
1308 | createCol(prims, "PhysicsShapeType", typeof(Byte)); | ||
1309 | createCol(prims, "Density", typeof(Double)); | ||
1310 | createCol(prims, "GravityModifier", typeof(Double)); | ||
1311 | createCol(prims, "Friction", typeof(Double)); | ||
1312 | createCol(prims, "Restitution", typeof(Double)); | ||
1313 | |||
1314 | createCol(prims, "KeyframeMotion", typeof(Byte[])); | ||
1315 | |||
1316 | // Add in contraints | ||
1317 | prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; | ||
1318 | |||
1319 | return prims; | ||
1320 | } | ||
1321 | |||
1322 | /// <summary> | ||
1323 | /// Creates "primshapes" table | ||
1324 | /// </summary> | ||
1325 | /// <returns>shape table DataTable</returns> | ||
1326 | private static DataTable createShapeTable() | ||
1327 | { | ||
1328 | DataTable shapes = new DataTable("primshapes"); | ||
1329 | createCol(shapes, "UUID", typeof(String)); | ||
1330 | // shape is an enum | ||
1331 | createCol(shapes, "Shape", typeof(Int32)); | ||
1332 | // vectors | ||
1333 | createCol(shapes, "ScaleX", typeof(Double)); | ||
1334 | createCol(shapes, "ScaleY", typeof(Double)); | ||
1335 | createCol(shapes, "ScaleZ", typeof(Double)); | ||
1336 | // paths | ||
1337 | createCol(shapes, "PCode", typeof(Int32)); | ||
1338 | createCol(shapes, "PathBegin", typeof(Int32)); | ||
1339 | createCol(shapes, "PathEnd", typeof(Int32)); | ||
1340 | createCol(shapes, "PathScaleX", typeof(Int32)); | ||
1341 | createCol(shapes, "PathScaleY", typeof(Int32)); | ||
1342 | createCol(shapes, "PathShearX", typeof(Int32)); | ||
1343 | createCol(shapes, "PathShearY", typeof(Int32)); | ||
1344 | createCol(shapes, "PathSkew", typeof(Int32)); | ||
1345 | createCol(shapes, "PathCurve", typeof(Int32)); | ||
1346 | createCol(shapes, "PathRadiusOffset", typeof(Int32)); | ||
1347 | createCol(shapes, "PathRevolutions", typeof(Int32)); | ||
1348 | createCol(shapes, "PathTaperX", typeof(Int32)); | ||
1349 | createCol(shapes, "PathTaperY", typeof(Int32)); | ||
1350 | createCol(shapes, "PathTwist", typeof(Int32)); | ||
1351 | createCol(shapes, "PathTwistBegin", typeof(Int32)); | ||
1352 | // profile | ||
1353 | createCol(shapes, "ProfileBegin", typeof(Int32)); | ||
1354 | createCol(shapes, "ProfileEnd", typeof(Int32)); | ||
1355 | createCol(shapes, "ProfileCurve", typeof(Int32)); | ||
1356 | createCol(shapes, "ProfileHollow", typeof(Int32)); | ||
1357 | createCol(shapes, "State", typeof(Int32)); | ||
1358 | // text TODO: this isn't right, but I'm not sure the right | ||
1359 | // way to specify this as a blob atm | ||
1360 | createCol(shapes, "Texture", typeof(Byte[])); | ||
1361 | createCol(shapes, "ExtraParams", typeof(Byte[])); | ||
1362 | createCol(shapes, "Media", typeof(String)); | ||
1363 | |||
1364 | shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] }; | ||
1365 | |||
1366 | return shapes; | ||
1367 | } | ||
1368 | |||
1369 | /// <summary> | ||
1370 | /// creates "primitems" table | ||
1371 | /// </summary> | ||
1372 | /// <returns>item table DataTable</returns> | ||
1373 | private static DataTable createItemsTable() | ||
1374 | { | ||
1375 | DataTable items = new DataTable("primitems"); | ||
1376 | |||
1377 | createCol(items, "itemID", typeof(String)); | ||
1378 | createCol(items, "primID", typeof(String)); | ||
1379 | createCol(items, "assetID", typeof(String)); | ||
1380 | createCol(items, "parentFolderID", typeof(String)); | ||
1381 | |||
1382 | createCol(items, "invType", typeof(Int32)); | ||
1383 | createCol(items, "assetType", typeof(Int32)); | ||
1384 | |||
1385 | createCol(items, "name", typeof(String)); | ||
1386 | createCol(items, "description", typeof(String)); | ||
1387 | |||
1388 | createCol(items, "creationDate", typeof(Int64)); | ||
1389 | createCol(items, "creatorID", typeof(String)); | ||
1390 | createCol(items, "ownerID", typeof(String)); | ||
1391 | createCol(items, "lastOwnerID", typeof(String)); | ||
1392 | createCol(items, "groupID", typeof(String)); | ||
1393 | |||
1394 | createCol(items, "nextPermissions", typeof(UInt32)); | ||
1395 | createCol(items, "currentPermissions", typeof(UInt32)); | ||
1396 | createCol(items, "basePermissions", typeof(UInt32)); | ||
1397 | createCol(items, "everyonePermissions", typeof(UInt32)); | ||
1398 | createCol(items, "groupPermissions", typeof(UInt32)); | ||
1399 | createCol(items, "flags", typeof(UInt32)); | ||
1400 | |||
1401 | items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] }; | ||
1402 | |||
1403 | return items; | ||
1404 | } | ||
1405 | |||
1406 | /// <summary> | ||
1407 | /// Creates "land" table | ||
1408 | /// </summary> | ||
1409 | /// <returns>land table DataTable</returns> | ||
1410 | private static DataTable createLandTable() | ||
1411 | { | ||
1412 | DataTable land = new DataTable("land"); | ||
1413 | createCol(land, "UUID", typeof(String)); | ||
1414 | createCol(land, "RegionUUID", typeof(String)); | ||
1415 | createCol(land, "LocalLandID", typeof(UInt32)); | ||
1416 | |||
1417 | // Bitmap is a byte[512] | ||
1418 | createCol(land, "Bitmap", typeof(Byte[])); | ||
1419 | |||
1420 | createCol(land, "Name", typeof(String)); | ||
1421 | createCol(land, "Desc", typeof(String)); | ||
1422 | createCol(land, "OwnerUUID", typeof(String)); | ||
1423 | createCol(land, "IsGroupOwned", typeof(string)); | ||
1424 | createCol(land, "Area", typeof(Int32)); | ||
1425 | createCol(land, "AuctionID", typeof(Int32)); //Unemplemented | ||
1426 | createCol(land, "Category", typeof(Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory | ||
1427 | createCol(land, "ClaimDate", typeof(Int32)); | ||
1428 | createCol(land, "ClaimPrice", typeof(Int32)); | ||
1429 | createCol(land, "GroupUUID", typeof(string)); | ||
1430 | createCol(land, "SalePrice", typeof(Int32)); | ||
1431 | createCol(land, "LandStatus", typeof(Int32)); //Enum. OpenMetaverse.Parcel.ParcelStatus | ||
1432 | createCol(land, "LandFlags", typeof(UInt32)); | ||
1433 | createCol(land, "LandingType", typeof(Byte)); | ||
1434 | createCol(land, "MediaAutoScale", typeof(Byte)); | ||
1435 | createCol(land, "MediaTextureUUID", typeof(String)); | ||
1436 | createCol(land, "MediaURL", typeof(String)); | ||
1437 | createCol(land, "MusicURL", typeof(String)); | ||
1438 | createCol(land, "PassHours", typeof(Double)); | ||
1439 | createCol(land, "PassPrice", typeof(UInt32)); | ||
1440 | createCol(land, "SnapshotUUID", typeof(String)); | ||
1441 | createCol(land, "UserLocationX", typeof(Double)); | ||
1442 | createCol(land, "UserLocationY", typeof(Double)); | ||
1443 | createCol(land, "UserLocationZ", typeof(Double)); | ||
1444 | createCol(land, "UserLookAtX", typeof(Double)); | ||
1445 | createCol(land, "UserLookAtY", typeof(Double)); | ||
1446 | createCol(land, "UserLookAtZ", typeof(Double)); | ||
1447 | createCol(land, "AuthbuyerID", typeof(String)); | ||
1448 | createCol(land, "OtherCleanTime", typeof(Int32)); | ||
1449 | createCol(land, "Dwell", typeof(Int32)); | ||
1450 | createCol(land, "MediaType", typeof(String)); | ||
1451 | createCol(land, "MediaDescription", typeof(String)); | ||
1452 | createCol(land, "MediaSize", typeof(String)); | ||
1453 | createCol(land, "MediaLoop", typeof(Boolean)); | ||
1454 | createCol(land, "ObscureMedia", typeof(Boolean)); | ||
1455 | createCol(land, "ObscureMusic", typeof(Boolean)); | ||
1456 | createCol(land, "SeeAVs", typeof(Boolean)); | ||
1457 | createCol(land, "AnyAVSounds", typeof(Boolean)); | ||
1458 | createCol(land, "GroupAVSounds", typeof(Boolean)); | ||
1459 | |||
1460 | land.PrimaryKey = new DataColumn[] { land.Columns["UUID"] }; | ||
1461 | |||
1462 | return land; | ||
1463 | } | ||
1464 | |||
1465 | /// <summary> | ||
1466 | /// create "landaccesslist" table | ||
1467 | /// </summary> | ||
1468 | /// <returns>Landacceslist DataTable</returns> | ||
1469 | private static DataTable createLandAccessListTable() | ||
1470 | { | ||
1471 | DataTable landaccess = new DataTable("landaccesslist"); | ||
1472 | createCol(landaccess, "LandUUID", typeof(String)); | ||
1473 | createCol(landaccess, "AccessUUID", typeof(String)); | ||
1474 | createCol(landaccess, "Flags", typeof(UInt32)); | ||
1475 | |||
1476 | return landaccess; | ||
1477 | } | ||
1478 | |||
1479 | private static DataTable createRegionSettingsTable() | ||
1480 | { | ||
1481 | DataTable regionsettings = new DataTable("regionsettings"); | ||
1482 | createCol(regionsettings, "regionUUID", typeof(String)); | ||
1483 | createCol(regionsettings, "block_terraform", typeof(Int32)); | ||
1484 | createCol(regionsettings, "block_fly", typeof(Int32)); | ||
1485 | createCol(regionsettings, "allow_damage", typeof(Int32)); | ||
1486 | createCol(regionsettings, "restrict_pushing", typeof(Int32)); | ||
1487 | createCol(regionsettings, "allow_land_resell", typeof(Int32)); | ||
1488 | createCol(regionsettings, "allow_land_join_divide", typeof(Int32)); | ||
1489 | createCol(regionsettings, "block_show_in_search", typeof(Int32)); | ||
1490 | createCol(regionsettings, "agent_limit", typeof(Int32)); | ||
1491 | createCol(regionsettings, "object_bonus", typeof(Double)); | ||
1492 | createCol(regionsettings, "maturity", typeof(Int32)); | ||
1493 | createCol(regionsettings, "disable_scripts", typeof(Int32)); | ||
1494 | createCol(regionsettings, "disable_collisions", typeof(Int32)); | ||
1495 | createCol(regionsettings, "disable_physics", typeof(Int32)); | ||
1496 | createCol(regionsettings, "terrain_texture_1", typeof(String)); | ||
1497 | createCol(regionsettings, "terrain_texture_2", typeof(String)); | ||
1498 | createCol(regionsettings, "terrain_texture_3", typeof(String)); | ||
1499 | createCol(regionsettings, "terrain_texture_4", typeof(String)); | ||
1500 | createCol(regionsettings, "elevation_1_nw", typeof(Double)); | ||
1501 | createCol(regionsettings, "elevation_2_nw", typeof(Double)); | ||
1502 | createCol(regionsettings, "elevation_1_ne", typeof(Double)); | ||
1503 | createCol(regionsettings, "elevation_2_ne", typeof(Double)); | ||
1504 | createCol(regionsettings, "elevation_1_se", typeof(Double)); | ||
1505 | createCol(regionsettings, "elevation_2_se", typeof(Double)); | ||
1506 | createCol(regionsettings, "elevation_1_sw", typeof(Double)); | ||
1507 | createCol(regionsettings, "elevation_2_sw", typeof(Double)); | ||
1508 | createCol(regionsettings, "water_height", typeof(Double)); | ||
1509 | createCol(regionsettings, "terrain_raise_limit", typeof(Double)); | ||
1510 | createCol(regionsettings, "terrain_lower_limit", typeof(Double)); | ||
1511 | createCol(regionsettings, "use_estate_sun", typeof(Int32)); | ||
1512 | createCol(regionsettings, "sandbox", typeof(Int32)); | ||
1513 | createCol(regionsettings, "sunvectorx", typeof(Double)); | ||
1514 | createCol(regionsettings, "sunvectory", typeof(Double)); | ||
1515 | createCol(regionsettings, "sunvectorz", typeof(Double)); | ||
1516 | createCol(regionsettings, "fixed_sun", typeof(Int32)); | ||
1517 | createCol(regionsettings, "sun_position", typeof(Double)); | ||
1518 | createCol(regionsettings, "covenant", typeof(String)); | ||
1519 | createCol(regionsettings, "covenant_datetime", typeof(Int32)); | ||
1520 | createCol(regionsettings, "map_tile_ID", typeof(String)); | ||
1521 | createCol(regionsettings, "TelehubObject", typeof(String)); | ||
1522 | createCol(regionsettings, "parcel_tile_ID", typeof(String)); | ||
1523 | regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] }; | ||
1524 | return regionsettings; | ||
1525 | } | ||
1526 | |||
1527 | /// <summary> | ||
1528 | /// create "regionwindlight" table | ||
1529 | /// </summary> | ||
1530 | /// <returns>RegionWindlight DataTable</returns> | ||
1531 | private static DataTable createRegionWindlightTable() | ||
1532 | { | ||
1533 | DataTable regionwindlight = new DataTable("regionwindlight"); | ||
1534 | createCol(regionwindlight, "region_id", typeof(String)); | ||
1535 | createCol(regionwindlight, "water_color_r", typeof(Double)); | ||
1536 | createCol(regionwindlight, "water_color_g", typeof(Double)); | ||
1537 | createCol(regionwindlight, "water_color_b", typeof(Double)); | ||
1538 | createCol(regionwindlight, "water_color_i", typeof(Double)); | ||
1539 | createCol(regionwindlight, "water_fog_density_exponent", typeof(Double)); | ||
1540 | createCol(regionwindlight, "underwater_fog_modifier", typeof(Double)); | ||
1541 | createCol(regionwindlight, "reflection_wavelet_scale_1", typeof(Double)); | ||
1542 | createCol(regionwindlight, "reflection_wavelet_scale_2", typeof(Double)); | ||
1543 | createCol(regionwindlight, "reflection_wavelet_scale_3", typeof(Double)); | ||
1544 | createCol(regionwindlight, "fresnel_scale", typeof(Double)); | ||
1545 | createCol(regionwindlight, "fresnel_offset", typeof(Double)); | ||
1546 | createCol(regionwindlight, "refract_scale_above", typeof(Double)); | ||
1547 | createCol(regionwindlight, "refract_scale_below", typeof(Double)); | ||
1548 | createCol(regionwindlight, "blur_multiplier", typeof(Double)); | ||
1549 | createCol(regionwindlight, "big_wave_direction_x", typeof(Double)); | ||
1550 | createCol(regionwindlight, "big_wave_direction_y", typeof(Double)); | ||
1551 | createCol(regionwindlight, "little_wave_direction_x", typeof(Double)); | ||
1552 | createCol(regionwindlight, "little_wave_direction_y", typeof(Double)); | ||
1553 | createCol(regionwindlight, "normal_map_texture", typeof(String)); | ||
1554 | createCol(regionwindlight, "horizon_r", typeof(Double)); | ||
1555 | createCol(regionwindlight, "horizon_g", typeof(Double)); | ||
1556 | createCol(regionwindlight, "horizon_b", typeof(Double)); | ||
1557 | createCol(regionwindlight, "horizon_i", typeof(Double)); | ||
1558 | createCol(regionwindlight, "haze_horizon", typeof(Double)); | ||
1559 | createCol(regionwindlight, "blue_density_r", typeof(Double)); | ||
1560 | createCol(regionwindlight, "blue_density_g", typeof(Double)); | ||
1561 | createCol(regionwindlight, "blue_density_b", typeof(Double)); | ||
1562 | createCol(regionwindlight, "blue_density_i", typeof(Double)); | ||
1563 | createCol(regionwindlight, "haze_density", typeof(Double)); | ||
1564 | createCol(regionwindlight, "density_multiplier", typeof(Double)); | ||
1565 | createCol(regionwindlight, "distance_multiplier", typeof(Double)); | ||
1566 | createCol(regionwindlight, "max_altitude", typeof(Int32)); | ||
1567 | createCol(regionwindlight, "sun_moon_color_r", typeof(Double)); | ||
1568 | createCol(regionwindlight, "sun_moon_color_g", typeof(Double)); | ||
1569 | createCol(regionwindlight, "sun_moon_color_b", typeof(Double)); | ||
1570 | createCol(regionwindlight, "sun_moon_color_i", typeof(Double)); | ||
1571 | createCol(regionwindlight, "sun_moon_position", typeof(Double)); | ||
1572 | createCol(regionwindlight, "ambient_r", typeof(Double)); | ||
1573 | createCol(regionwindlight, "ambient_g", typeof(Double)); | ||
1574 | createCol(regionwindlight, "ambient_b", typeof(Double)); | ||
1575 | createCol(regionwindlight, "ambient_i", typeof(Double)); | ||
1576 | createCol(regionwindlight, "east_angle", typeof(Double)); | ||
1577 | createCol(regionwindlight, "sun_glow_focus", typeof(Double)); | ||
1578 | createCol(regionwindlight, "sun_glow_size", typeof(Double)); | ||
1579 | createCol(regionwindlight, "scene_gamma", typeof(Double)); | ||
1580 | createCol(regionwindlight, "star_brightness", typeof(Double)); | ||
1581 | createCol(regionwindlight, "cloud_color_r", typeof(Double)); | ||
1582 | createCol(regionwindlight, "cloud_color_g", typeof(Double)); | ||
1583 | createCol(regionwindlight, "cloud_color_b", typeof(Double)); | ||
1584 | createCol(regionwindlight, "cloud_color_i", typeof(Double)); | ||
1585 | createCol(regionwindlight, "cloud_x", typeof(Double)); | ||
1586 | createCol(regionwindlight, "cloud_y", typeof(Double)); | ||
1587 | createCol(regionwindlight, "cloud_density", typeof(Double)); | ||
1588 | createCol(regionwindlight, "cloud_coverage", typeof(Double)); | ||
1589 | createCol(regionwindlight, "cloud_scale", typeof(Double)); | ||
1590 | createCol(regionwindlight, "cloud_detail_x", typeof(Double)); | ||
1591 | createCol(regionwindlight, "cloud_detail_y", typeof(Double)); | ||
1592 | createCol(regionwindlight, "cloud_detail_density", typeof(Double)); | ||
1593 | createCol(regionwindlight, "cloud_scroll_x", typeof(Double)); | ||
1594 | createCol(regionwindlight, "cloud_scroll_x_lock", typeof(Int32)); | ||
1595 | createCol(regionwindlight, "cloud_scroll_y", typeof(Double)); | ||
1596 | createCol(regionwindlight, "cloud_scroll_y_lock", typeof(Int32)); | ||
1597 | createCol(regionwindlight, "draw_classic_clouds", typeof(Int32)); | ||
1598 | |||
1599 | regionwindlight.PrimaryKey = new DataColumn[] { regionwindlight.Columns["region_id"] }; | ||
1600 | return regionwindlight; | ||
1601 | } | ||
1602 | |||
1603 | private static DataTable createRegionEnvironmentTable() | ||
1604 | { | ||
1605 | DataTable regionEnvironment = new DataTable("regionenvironment"); | ||
1606 | createCol(regionEnvironment, "region_id", typeof(String)); | ||
1607 | createCol(regionEnvironment, "llsd_settings", typeof(String)); | ||
1608 | |||
1609 | regionEnvironment.PrimaryKey = new DataColumn[] { regionEnvironment.Columns["region_id"] }; | ||
1610 | |||
1611 | return regionEnvironment; | ||
1612 | } | ||
1613 | |||
1614 | private static DataTable createRegionSpawnPointsTable() | ||
1615 | { | ||
1616 | DataTable spawn_points = new DataTable("spawn_points"); | ||
1617 | createCol(spawn_points, "regionID", typeof(String)); | ||
1618 | createCol(spawn_points, "Yaw", typeof(float)); | ||
1619 | createCol(spawn_points, "Pitch", typeof(float)); | ||
1620 | createCol(spawn_points, "Distance", typeof(float)); | ||
1621 | |||
1622 | return spawn_points; | ||
1623 | } | ||
1624 | |||
1625 | /*********************************************************************** | ||
1626 | * | ||
1627 | * Convert between ADO.NET <=> OpenSim Objects | ||
1628 | * | ||
1629 | * These should be database independant | ||
1630 | * | ||
1631 | **********************************************************************/ | ||
1632 | |||
1633 | /// <summary> | ||
1634 | /// | ||
1635 | /// </summary> | ||
1636 | /// <param name="row"></param> | ||
1637 | /// <returns></returns> | ||
1638 | private SceneObjectPart buildPrim(DataRow row) | ||
1639 | { | ||
1640 | // Code commented. Uncomment to test the unit test inline. | ||
1641 | |||
1642 | // The unit test mentions this commented code for the purposes | ||
1643 | // of debugging a unit test failure | ||
1644 | |||
1645 | // SceneObjectGroup sog = new SceneObjectGroup(); | ||
1646 | // SceneObjectPart sop = new SceneObjectPart(); | ||
1647 | // sop.LocalId = 1; | ||
1648 | // sop.Name = "object1"; | ||
1649 | // sop.Description = "object1"; | ||
1650 | // sop.Text = ""; | ||
1651 | // sop.SitName = ""; | ||
1652 | // sop.TouchName = ""; | ||
1653 | // sop.UUID = UUID.Random(); | ||
1654 | // sop.Shape = PrimitiveBaseShape.Default; | ||
1655 | // sog.SetRootPart(sop); | ||
1656 | // Add breakpoint in above line. Check sop fields. | ||
1657 | |||
1658 | // TODO: this doesn't work yet because something more | ||
1659 | // interesting has to be done to actually get these values | ||
1660 | // back out. Not enough time to figure it out yet. | ||
1661 | |||
1662 | SceneObjectPart prim = new SceneObjectPart(); | ||
1663 | prim.UUID = new UUID((String)row["UUID"]); | ||
1664 | // explicit conversion of integers is required, which sort | ||
1665 | // of sucks. No idea if there is a shortcut here or not. | ||
1666 | prim.CreationDate = Convert.ToInt32(row["CreationDate"]); | ||
1667 | prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"]; | ||
1668 | // various text fields | ||
1669 | prim.Text = (String)row["Text"]; | ||
1670 | prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]), | ||
1671 | Convert.ToInt32(row["ColorR"]), | ||
1672 | Convert.ToInt32(row["ColorG"]), | ||
1673 | Convert.ToInt32(row["ColorB"])); | ||
1674 | prim.Description = (String)row["Description"]; | ||
1675 | prim.SitName = (String)row["SitName"]; | ||
1676 | prim.TouchName = (String)row["TouchName"]; | ||
1677 | // permissions | ||
1678 | prim.Flags = (PrimFlags)Convert.ToUInt32(row["ObjectFlags"]); | ||
1679 | prim.CreatorIdentification = (String)row["CreatorID"]; | ||
1680 | prim.OwnerID = new UUID((String)row["OwnerID"]); | ||
1681 | prim.GroupID = new UUID((String)row["GroupID"]); | ||
1682 | prim.LastOwnerID = new UUID((String)row["LastOwnerID"]); | ||
1683 | prim.RezzerID = row["RezzerID"] == DBNull.Value ? UUID.Zero : new UUID((String)row["RezzerID"]); | ||
1684 | prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); | ||
1685 | prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); | ||
1686 | prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); | ||
1687 | prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); | ||
1688 | prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); | ||
1689 | // vectors | ||
1690 | prim.OffsetPosition = new Vector3( | ||
1691 | Convert.ToSingle(row["PositionX"]), | ||
1692 | Convert.ToSingle(row["PositionY"]), | ||
1693 | Convert.ToSingle(row["PositionZ"]) | ||
1694 | ); | ||
1695 | prim.GroupPosition = new Vector3( | ||
1696 | Convert.ToSingle(row["GroupPositionX"]), | ||
1697 | Convert.ToSingle(row["GroupPositionY"]), | ||
1698 | Convert.ToSingle(row["GroupPositionZ"]) | ||
1699 | ); | ||
1700 | prim.Velocity = new Vector3( | ||
1701 | Convert.ToSingle(row["VelocityX"]), | ||
1702 | Convert.ToSingle(row["VelocityY"]), | ||
1703 | Convert.ToSingle(row["VelocityZ"]) | ||
1704 | ); | ||
1705 | prim.AngularVelocity = new Vector3( | ||
1706 | Convert.ToSingle(row["AngularVelocityX"]), | ||
1707 | Convert.ToSingle(row["AngularVelocityY"]), | ||
1708 | Convert.ToSingle(row["AngularVelocityZ"]) | ||
1709 | ); | ||
1710 | prim.Acceleration = new Vector3( | ||
1711 | Convert.ToSingle(row["AccelerationX"]), | ||
1712 | Convert.ToSingle(row["AccelerationY"]), | ||
1713 | Convert.ToSingle(row["AccelerationZ"]) | ||
1714 | ); | ||
1715 | // quaternions | ||
1716 | prim.RotationOffset = new Quaternion( | ||
1717 | Convert.ToSingle(row["RotationX"]), | ||
1718 | Convert.ToSingle(row["RotationY"]), | ||
1719 | Convert.ToSingle(row["RotationZ"]), | ||
1720 | Convert.ToSingle(row["RotationW"]) | ||
1721 | ); | ||
1722 | |||
1723 | prim.SitTargetPositionLL = new Vector3( | ||
1724 | Convert.ToSingle(row["SitTargetOffsetX"]), | ||
1725 | Convert.ToSingle(row["SitTargetOffsetY"]), | ||
1726 | Convert.ToSingle(row["SitTargetOffsetZ"])); | ||
1727 | prim.SitTargetOrientationLL = new Quaternion( | ||
1728 | Convert.ToSingle( | ||
1729 | row["SitTargetOrientX"]), | ||
1730 | Convert.ToSingle( | ||
1731 | row["SitTargetOrientY"]), | ||
1732 | Convert.ToSingle( | ||
1733 | row["SitTargetOrientZ"]), | ||
1734 | Convert.ToSingle( | ||
1735 | row["SitTargetOrientW"])); | ||
1736 | |||
1737 | prim.ClickAction = Convert.ToByte(row["ClickAction"]); | ||
1738 | prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]); | ||
1739 | prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]); | ||
1740 | prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]); | ||
1741 | prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]); | ||
1742 | prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]); | ||
1743 | |||
1744 | prim.Sound = new UUID(row["LoopedSound"].ToString()); | ||
1745 | prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]); | ||
1746 | prim.SoundFlags = 1; // If it's persisted at all, it's looped | ||
1747 | |||
1748 | if (!row.IsNull("TextureAnimation")) | ||
1749 | prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString()); | ||
1750 | if (!row.IsNull("ParticleSystem")) | ||
1751 | prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString()); | ||
1752 | |||
1753 | prim.AngularVelocity = new Vector3( | ||
1754 | Convert.ToSingle(row["OmegaX"]), | ||
1755 | Convert.ToSingle(row["OmegaY"]), | ||
1756 | Convert.ToSingle(row["OmegaZ"]) | ||
1757 | ); | ||
1758 | |||
1759 | prim.SetCameraEyeOffset(new Vector3( | ||
1760 | Convert.ToSingle(row["CameraEyeOffsetX"]), | ||
1761 | Convert.ToSingle(row["CameraEyeOffsetY"]), | ||
1762 | Convert.ToSingle(row["CameraEyeOffsetZ"]) | ||
1763 | )); | ||
1764 | |||
1765 | prim.SetCameraAtOffset(new Vector3( | ||
1766 | Convert.ToSingle(row["CameraAtOffsetX"]), | ||
1767 | Convert.ToSingle(row["CameraAtOffsetY"]), | ||
1768 | Convert.ToSingle(row["CameraAtOffsetZ"]) | ||
1769 | )); | ||
1770 | |||
1771 | if (Convert.ToInt16(row["ForceMouselook"]) != 0) | ||
1772 | prim.SetForceMouselook(true); | ||
1773 | |||
1774 | prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]); | ||
1775 | |||
1776 | if (Convert.ToInt16(row["AllowedDrop"]) != 0) | ||
1777 | prim.AllowedDrop = true; | ||
1778 | |||
1779 | if (Convert.ToInt16(row["DieAtEdge"]) != 0) | ||
1780 | prim.DIE_AT_EDGE = true; | ||
1781 | |||
1782 | prim.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1783 | prim.ObjectSaleType = Convert.ToByte(row["SaleType"]); | ||
1784 | |||
1785 | prim.Material = Convert.ToByte(row["Material"]); | ||
1786 | |||
1787 | prim.CollisionSound = new UUID(row["CollisionSound"].ToString()); | ||
1788 | prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]); | ||
1789 | |||
1790 | if (Convert.ToInt16(row["VolumeDetect"]) != 0) | ||
1791 | prim.VolumeDetectActive = true; | ||
1792 | |||
1793 | if (!(row["MediaURL"] is System.DBNull)) | ||
1794 | { | ||
1795 | // m_log.DebugFormat("[SQLITE]: MediaUrl type [{0}]", row["MediaURL"].GetType()); | ||
1796 | prim.MediaUrl = (string)row["MediaURL"]; | ||
1797 | } | ||
1798 | |||
1799 | prim.AttachedPos = new Vector3( | ||
1800 | Convert.ToSingle(row["AttachedPosX"]), | ||
1801 | Convert.ToSingle(row["AttachedPosY"]), | ||
1802 | Convert.ToSingle(row["AttachedPosZ"]) | ||
1803 | ); | ||
1804 | |||
1805 | if (!(row["DynAttrs"] is System.DBNull)) | ||
1806 | { | ||
1807 | //m_log.DebugFormat("[SQLITE]: DynAttrs type [{0}]", row["DynAttrs"].GetType()); | ||
1808 | prim.DynAttrs = DAMap.FromXml((string)row["DynAttrs"]); | ||
1809 | } | ||
1810 | else | ||
1811 | { | ||
1812 | prim.DynAttrs = new DAMap(); | ||
1813 | } | ||
1814 | |||
1815 | prim.PhysicsShapeType = Convert.ToByte(row["PhysicsShapeType"]); | ||
1816 | prim.Density = Convert.ToSingle(row["Density"]); | ||
1817 | prim.GravityModifier = Convert.ToSingle(row["GravityModifier"]); | ||
1818 | prim.Friction = Convert.ToSingle(row["Friction"]); | ||
1819 | prim.Restitution = Convert.ToSingle(row["Restitution"]); | ||
1820 | |||
1821 | |||
1822 | if (!(row["KeyframeMotion"] is DBNull)) | ||
1823 | { | ||
1824 | Byte[] data = (byte[])row["KeyframeMotion"]; | ||
1825 | if (data.Length > 0) | ||
1826 | prim.KeyframeMotion = KeyframeMotion.FromData(null, data); | ||
1827 | else | ||
1828 | prim.KeyframeMotion = null; | ||
1829 | } | ||
1830 | else | ||
1831 | { | ||
1832 | prim.KeyframeMotion = null; | ||
1833 | } | ||
1834 | |||
1835 | prim.PassCollisions = Convert.ToBoolean(row["PassCollisions"]); | ||
1836 | prim.PassTouches = Convert.ToBoolean(row["PassTouches"]); | ||
1837 | prim.RotationAxisLocks = Convert.ToByte(row["RotationAxisLocks"]); | ||
1838 | |||
1839 | SOPVehicle vehicle = null; | ||
1840 | if (!(row["Vehicle"] is DBNull) && row["Vehicle"].ToString() != String.Empty) | ||
1841 | { | ||
1842 | vehicle = SOPVehicle.FromXml2(row["Vehicle"].ToString()); | ||
1843 | if (vehicle != null) | ||
1844 | prim.VehicleParams = vehicle; | ||
1845 | } | ||
1846 | |||
1847 | PhysicsInertiaData pdata = null; | ||
1848 | if (!(row["PhysInertia"] is DBNull) && row["PhysInertia"].ToString() != String.Empty) | ||
1849 | pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); | ||
1850 | prim.PhysicsInertia = pdata; | ||
1851 | |||
1852 | return prim; | ||
1853 | } | ||
1854 | |||
1855 | /// <summary> | ||
1856 | /// Build a prim inventory item from the persisted data. | ||
1857 | /// </summary> | ||
1858 | /// <param name="row"></param> | ||
1859 | /// <returns></returns> | ||
1860 | private static TaskInventoryItem buildItem(DataRow row) | ||
1861 | { | ||
1862 | TaskInventoryItem taskItem = new TaskInventoryItem(); | ||
1863 | |||
1864 | taskItem.ItemID = new UUID((String)row["itemID"]); | ||
1865 | taskItem.ParentPartID = new UUID((String)row["primID"]); | ||
1866 | taskItem.AssetID = new UUID((String)row["assetID"]); | ||
1867 | taskItem.ParentID = new UUID((String)row["parentFolderID"]); | ||
1868 | |||
1869 | taskItem.InvType = Convert.ToInt32(row["invType"]); | ||
1870 | taskItem.Type = Convert.ToInt32(row["assetType"]); | ||
1871 | |||
1872 | taskItem.Name = (String)row["name"]; | ||
1873 | taskItem.Description = (String)row["description"]; | ||
1874 | taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]); | ||
1875 | taskItem.CreatorIdentification = (String)row["creatorID"]; | ||
1876 | taskItem.OwnerID = new UUID((String)row["ownerID"]); | ||
1877 | taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]); | ||
1878 | taskItem.GroupID = new UUID((String)row["groupID"]); | ||
1879 | |||
1880 | taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]); | ||
1881 | taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]); | ||
1882 | taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]); | ||
1883 | taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]); | ||
1884 | taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]); | ||
1885 | taskItem.Flags = Convert.ToUInt32(row["flags"]); | ||
1886 | |||
1887 | return taskItem; | ||
1888 | } | ||
1889 | |||
1890 | /// <summary> | ||
1891 | /// Build a Land Data from the persisted data. | ||
1892 | /// </summary> | ||
1893 | /// <param name="row"></param> | ||
1894 | /// <returns></returns> | ||
1895 | private LandData buildLandData(DataRow row) | ||
1896 | { | ||
1897 | LandData newData = new LandData(); | ||
1898 | |||
1899 | newData.GlobalID = new UUID((String)row["UUID"]); | ||
1900 | newData.LocalID = Convert.ToInt32(row["LocalLandID"]); | ||
1901 | |||
1902 | // Bitmap is a byte[512] | ||
1903 | newData.Bitmap = (Byte[])row["Bitmap"]; | ||
1904 | |||
1905 | newData.Name = (String)row["Name"]; | ||
1906 | newData.Description = (String)row["Desc"]; | ||
1907 | newData.OwnerID = (UUID)(String)row["OwnerUUID"]; | ||
1908 | newData.IsGroupOwned = Convert.ToBoolean(row["IsGroupOwned"]); | ||
1909 | newData.Area = Convert.ToInt32(row["Area"]); | ||
1910 | newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented | ||
1911 | newData.Category = (ParcelCategory)Convert.ToInt32(row["Category"]); | ||
1912 | //Enum OpenMetaverse.Parcel.ParcelCategory | ||
1913 | newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]); | ||
1914 | newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]); | ||
1915 | newData.GroupID = new UUID((String)row["GroupUUID"]); | ||
1916 | newData.SalePrice = Convert.ToInt32(row["SalePrice"]); | ||
1917 | newData.Status = (ParcelStatus)Convert.ToInt32(row["LandStatus"]); | ||
1918 | //Enum. OpenMetaverse.Parcel.ParcelStatus | ||
1919 | newData.Flags = Convert.ToUInt32(row["LandFlags"]); | ||
1920 | newData.LandingType = (Byte)row["LandingType"]; | ||
1921 | newData.MediaAutoScale = (Byte)row["MediaAutoScale"]; | ||
1922 | newData.MediaID = new UUID((String)row["MediaTextureUUID"]); | ||
1923 | newData.MediaURL = (String)row["MediaURL"]; | ||
1924 | newData.MusicURL = (String)row["MusicURL"]; | ||
1925 | newData.PassHours = Convert.ToSingle(row["PassHours"]); | ||
1926 | newData.PassPrice = Convert.ToInt32(row["PassPrice"]); | ||
1927 | newData.SnapshotID = (UUID)(String)row["SnapshotUUID"]; | ||
1928 | newData.Dwell = Convert.ToInt32(row["Dwell"]); | ||
1929 | newData.MediaType = (String)row["MediaType"]; | ||
1930 | newData.MediaDescription = (String)row["MediaDescription"]; | ||
1931 | newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]); | ||
1932 | newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]); | ||
1933 | newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); | ||
1934 | newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); | ||
1935 | newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); | ||
1936 | newData.SeeAVs = Convert.ToBoolean(row["SeeAVs"]); | ||
1937 | newData.AnyAVSounds = Convert.ToBoolean(row["AnyAVSounds"]); | ||
1938 | newData.GroupAVSounds = Convert.ToBoolean(row["GroupAVSounds"]); | ||
1939 | |||
1940 | try | ||
1941 | { | ||
1942 | newData.UserLocation = | ||
1943 | new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]), | ||
1944 | Convert.ToSingle(row["UserLocationZ"])); | ||
1945 | newData.UserLookAt = | ||
1946 | new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]), | ||
1947 | Convert.ToSingle(row["UserLookAtZ"])); | ||
1948 | |||
1949 | } | ||
1950 | catch (InvalidCastException) | ||
1951 | { | ||
1952 | m_log.ErrorFormat("[SQLITE REGION DB]: unable to get parcel telehub settings for {1}", newData.Name); | ||
1953 | newData.UserLocation = Vector3.Zero; | ||
1954 | newData.UserLookAt = Vector3.Zero; | ||
1955 | } | ||
1956 | newData.ParcelAccessList = new List<LandAccessEntry>(); | ||
1957 | UUID authBuyerID = UUID.Zero; | ||
1958 | |||
1959 | UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID); | ||
1960 | |||
1961 | newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); | ||
1962 | |||
1963 | return newData; | ||
1964 | } | ||
1965 | |||
1966 | private RegionSettings buildRegionSettings(DataRow row) | ||
1967 | { | ||
1968 | RegionSettings newSettings = new RegionSettings(); | ||
1969 | |||
1970 | newSettings.RegionUUID = new UUID((string)row["regionUUID"]); | ||
1971 | newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]); | ||
1972 | newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]); | ||
1973 | newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]); | ||
1974 | newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]); | ||
1975 | newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]); | ||
1976 | newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]); | ||
1977 | newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]); | ||
1978 | newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]); | ||
1979 | newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]); | ||
1980 | newSettings.Maturity = Convert.ToInt32(row["maturity"]); | ||
1981 | newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]); | ||
1982 | newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]); | ||
1983 | newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]); | ||
1984 | newSettings.TerrainTexture1 = new UUID((String)row["terrain_texture_1"]); | ||
1985 | newSettings.TerrainTexture2 = new UUID((String)row["terrain_texture_2"]); | ||
1986 | newSettings.TerrainTexture3 = new UUID((String)row["terrain_texture_3"]); | ||
1987 | newSettings.TerrainTexture4 = new UUID((String)row["terrain_texture_4"]); | ||
1988 | newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]); | ||
1989 | newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]); | ||
1990 | newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]); | ||
1991 | newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]); | ||
1992 | newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]); | ||
1993 | newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]); | ||
1994 | newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]); | ||
1995 | newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]); | ||
1996 | newSettings.WaterHeight = Convert.ToDouble(row["water_height"]); | ||
1997 | newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]); | ||
1998 | newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]); | ||
1999 | newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]); | ||
2000 | newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]); | ||
2001 | newSettings.SunVector = new Vector3( | ||
2002 | Convert.ToSingle(row["sunvectorx"]), | ||
2003 | Convert.ToSingle(row["sunvectory"]), | ||
2004 | Convert.ToSingle(row["sunvectorz"]) | ||
2005 | ); | ||
2006 | newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]); | ||
2007 | newSettings.SunPosition = Convert.ToDouble(row["sun_position"]); | ||
2008 | newSettings.Covenant = new UUID((String)row["covenant"]); | ||
2009 | newSettings.CovenantChangedDateTime = Convert.ToInt32(row["covenant_datetime"]); | ||
2010 | newSettings.TerrainImageID = new UUID((String)row["map_tile_ID"]); | ||
2011 | newSettings.TelehubObject = new UUID((String)row["TelehubObject"]); | ||
2012 | newSettings.ParcelImageID = new UUID((String)row["parcel_tile_ID"]); | ||
2013 | newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]); | ||
2014 | newSettings.Casino = Convert.ToBoolean(row["casino"]); | ||
2015 | return newSettings; | ||
2016 | } | ||
2017 | |||
2018 | /// <summary> | ||
2019 | /// Build a windlight entry from the persisted data. | ||
2020 | /// </summary> | ||
2021 | /// <param name="row"></param> | ||
2022 | /// <returns>RegionLightShareData</returns> | ||
2023 | private RegionLightShareData buildRegionWindlight(DataRow row) | ||
2024 | { | ||
2025 | RegionLightShareData windlight = new RegionLightShareData(); | ||
2026 | |||
2027 | windlight.regionID = new UUID((string)row["region_id"]); | ||
2028 | windlight.waterColor.X = Convert.ToSingle(row["water_color_r"]); | ||
2029 | windlight.waterColor.Y = Convert.ToSingle(row["water_color_g"]); | ||
2030 | windlight.waterColor.Z = Convert.ToSingle(row["water_color_b"]); | ||
2031 | //windlight.waterColor.W = Convert.ToSingle(row["water_color_i"]); //not implemented | ||
2032 | windlight.waterFogDensityExponent = Convert.ToSingle(row["water_fog_density_exponent"]); | ||
2033 | windlight.underwaterFogModifier = Convert.ToSingle(row["underwater_fog_modifier"]); | ||
2034 | windlight.reflectionWaveletScale.X = Convert.ToSingle(row["reflection_wavelet_scale_1"]); | ||
2035 | windlight.reflectionWaveletScale.Y = Convert.ToSingle(row["reflection_wavelet_scale_2"]); | ||
2036 | windlight.reflectionWaveletScale.Z = Convert.ToSingle(row["reflection_wavelet_scale_3"]); | ||
2037 | windlight.fresnelScale = Convert.ToSingle(row["fresnel_scale"]); | ||
2038 | windlight.fresnelOffset = Convert.ToSingle(row["fresnel_offset"]); | ||
2039 | windlight.refractScaleAbove = Convert.ToSingle(row["refract_scale_above"]); | ||
2040 | windlight.refractScaleBelow = Convert.ToSingle(row["refract_scale_below"]); | ||
2041 | windlight.blurMultiplier = Convert.ToSingle(row["blur_multiplier"]); | ||
2042 | windlight.bigWaveDirection.X = Convert.ToSingle(row["big_wave_direction_x"]); | ||
2043 | windlight.bigWaveDirection.Y = Convert.ToSingle(row["big_wave_direction_y"]); | ||
2044 | windlight.littleWaveDirection.X = Convert.ToSingle(row["little_wave_direction_x"]); | ||
2045 | windlight.littleWaveDirection.Y = Convert.ToSingle(row["little_wave_direction_y"]); | ||
2046 | windlight.normalMapTexture = new UUID((string)row["normal_map_texture"]); | ||
2047 | windlight.horizon.X = Convert.ToSingle(row["horizon_r"]); | ||
2048 | windlight.horizon.Y = Convert.ToSingle(row["horizon_g"]); | ||
2049 | windlight.horizon.Z = Convert.ToSingle(row["horizon_b"]); | ||
2050 | windlight.horizon.W = Convert.ToSingle(row["horizon_i"]); | ||
2051 | windlight.hazeHorizon = Convert.ToSingle(row["haze_horizon"]); | ||
2052 | windlight.blueDensity.X = Convert.ToSingle(row["blue_density_r"]); | ||
2053 | windlight.blueDensity.Y = Convert.ToSingle(row["blue_density_g"]); | ||
2054 | windlight.blueDensity.Z = Convert.ToSingle(row["blue_density_b"]); | ||
2055 | windlight.blueDensity.W = Convert.ToSingle(row["blue_density_i"]); | ||
2056 | windlight.hazeDensity = Convert.ToSingle(row["haze_density"]); | ||
2057 | windlight.densityMultiplier = Convert.ToSingle(row["density_multiplier"]); | ||
2058 | windlight.distanceMultiplier = Convert.ToSingle(row["distance_multiplier"]); | ||
2059 | windlight.maxAltitude = Convert.ToUInt16(row["max_altitude"]); | ||
2060 | windlight.sunMoonColor.X = Convert.ToSingle(row["sun_moon_color_r"]); | ||
2061 | windlight.sunMoonColor.Y = Convert.ToSingle(row["sun_moon_color_g"]); | ||
2062 | windlight.sunMoonColor.Z = Convert.ToSingle(row["sun_moon_color_b"]); | ||
2063 | windlight.sunMoonColor.W = Convert.ToSingle(row["sun_moon_color_i"]); | ||
2064 | windlight.sunMoonPosition = Convert.ToSingle(row["sun_moon_position"]); | ||
2065 | windlight.ambient.X = Convert.ToSingle(row["ambient_r"]); | ||
2066 | windlight.ambient.Y = Convert.ToSingle(row["ambient_g"]); | ||
2067 | windlight.ambient.Z = Convert.ToSingle(row["ambient_b"]); | ||
2068 | windlight.ambient.W = Convert.ToSingle(row["ambient_i"]); | ||
2069 | windlight.eastAngle = Convert.ToSingle(row["east_angle"]); | ||
2070 | windlight.sunGlowFocus = Convert.ToSingle(row["sun_glow_focus"]); | ||
2071 | windlight.sunGlowSize = Convert.ToSingle(row["sun_glow_size"]); | ||
2072 | windlight.sceneGamma = Convert.ToSingle(row["scene_gamma"]); | ||
2073 | windlight.starBrightness = Convert.ToSingle(row["star_brightness"]); | ||
2074 | windlight.cloudColor.X = Convert.ToSingle(row["cloud_color_r"]); | ||
2075 | windlight.cloudColor.Y = Convert.ToSingle(row["cloud_color_g"]); | ||
2076 | windlight.cloudColor.Z = Convert.ToSingle(row["cloud_color_b"]); | ||
2077 | windlight.cloudColor.W = Convert.ToSingle(row["cloud_color_i"]); | ||
2078 | windlight.cloudXYDensity.X = Convert.ToSingle(row["cloud_x"]); | ||
2079 | windlight.cloudXYDensity.Y = Convert.ToSingle(row["cloud_y"]); | ||
2080 | windlight.cloudXYDensity.Z = Convert.ToSingle(row["cloud_density"]); | ||
2081 | windlight.cloudCoverage = Convert.ToSingle(row["cloud_coverage"]); | ||
2082 | windlight.cloudScale = Convert.ToSingle(row["cloud_scale"]); | ||
2083 | windlight.cloudDetailXYDensity.X = Convert.ToSingle(row["cloud_detail_x"]); | ||
2084 | windlight.cloudDetailXYDensity.Y = Convert.ToSingle(row["cloud_detail_y"]); | ||
2085 | windlight.cloudDetailXYDensity.Z = Convert.ToSingle(row["cloud_detail_density"]); | ||
2086 | windlight.cloudScrollX = Convert.ToSingle(row["cloud_scroll_x"]); | ||
2087 | windlight.cloudScrollXLock = Convert.ToBoolean(row["cloud_scroll_x_lock"]); | ||
2088 | windlight.cloudScrollY = Convert.ToSingle(row["cloud_scroll_y"]); | ||
2089 | windlight.cloudScrollYLock = Convert.ToBoolean(row["cloud_scroll_y_lock"]); | ||
2090 | windlight.drawClassicClouds = Convert.ToBoolean(row["draw_classic_clouds"]); | ||
2091 | |||
2092 | return windlight; | ||
2093 | } | ||
2094 | |||
2095 | /// <summary> | ||
2096 | /// Build a land access entry from the persisted data. | ||
2097 | /// </summary> | ||
2098 | /// <param name="row"></param> | ||
2099 | /// <returns></returns> | ||
2100 | private static LandAccessEntry buildLandAccessData(DataRow row) | ||
2101 | { | ||
2102 | LandAccessEntry entry = new LandAccessEntry(); | ||
2103 | entry.AgentID = new UUID((string)row["AccessUUID"]); | ||
2104 | entry.Flags = (AccessList)row["Flags"]; | ||
2105 | entry.Expires = 0; | ||
2106 | return entry; | ||
2107 | } | ||
2108 | |||
2109 | |||
2110 | /// <summary> | ||
2111 | /// | ||
2112 | /// </summary> | ||
2113 | /// <param name="row"></param> | ||
2114 | /// <param name="prim"></param> | ||
2115 | /// <param name="sceneGroupID"></param> | ||
2116 | /// <param name="regionUUID"></param> | ||
2117 | private static void fillPrimRow(DataRow row, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | ||
2118 | { | ||
2119 | row["UUID"] = prim.UUID.ToString(); | ||
2120 | row["RegionUUID"] = regionUUID.ToString(); | ||
2121 | row["CreationDate"] = prim.CreationDate; | ||
2122 | row["Name"] = prim.Name; | ||
2123 | row["SceneGroupID"] = sceneGroupID.ToString(); | ||
2124 | // the UUID of the root part for this SceneObjectGroup | ||
2125 | // various text fields | ||
2126 | row["Text"] = prim.Text; | ||
2127 | row["Description"] = prim.Description; | ||
2128 | row["SitName"] = prim.SitName; | ||
2129 | row["TouchName"] = prim.TouchName; | ||
2130 | // permissions | ||
2131 | row["ObjectFlags"] = (uint)prim.Flags; | ||
2132 | row["CreatorID"] = prim.CreatorIdentification.ToString(); | ||
2133 | row["OwnerID"] = prim.OwnerID.ToString(); | ||
2134 | row["GroupID"] = prim.GroupID.ToString(); | ||
2135 | row["LastOwnerID"] = prim.LastOwnerID.ToString(); | ||
2136 | row["RezzerID"] = prim.RezzerID.ToString(); | ||
2137 | row["OwnerMask"] = prim.OwnerMask; | ||
2138 | row["NextOwnerMask"] = prim.NextOwnerMask; | ||
2139 | row["GroupMask"] = prim.GroupMask; | ||
2140 | row["EveryoneMask"] = prim.EveryoneMask; | ||
2141 | row["BaseMask"] = prim.BaseMask; | ||
2142 | // vectors | ||
2143 | row["PositionX"] = prim.OffsetPosition.X; | ||
2144 | row["PositionY"] = prim.OffsetPosition.Y; | ||
2145 | row["PositionZ"] = prim.OffsetPosition.Z; | ||
2146 | row["GroupPositionX"] = prim.GroupPosition.X; | ||
2147 | row["GroupPositionY"] = prim.GroupPosition.Y; | ||
2148 | row["GroupPositionZ"] = prim.GroupPosition.Z; | ||
2149 | row["VelocityX"] = prim.Velocity.X; | ||
2150 | row["VelocityY"] = prim.Velocity.Y; | ||
2151 | row["VelocityZ"] = prim.Velocity.Z; | ||
2152 | row["AngularVelocityX"] = prim.AngularVelocity.X; | ||
2153 | row["AngularVelocityY"] = prim.AngularVelocity.Y; | ||
2154 | row["AngularVelocityZ"] = prim.AngularVelocity.Z; | ||
2155 | row["AccelerationX"] = prim.Acceleration.X; | ||
2156 | row["AccelerationY"] = prim.Acceleration.Y; | ||
2157 | row["AccelerationZ"] = prim.Acceleration.Z; | ||
2158 | // quaternions | ||
2159 | row["RotationX"] = prim.RotationOffset.X; | ||
2160 | row["RotationY"] = prim.RotationOffset.Y; | ||
2161 | row["RotationZ"] = prim.RotationOffset.Z; | ||
2162 | row["RotationW"] = prim.RotationOffset.W; | ||
2163 | |||
2164 | // Sit target | ||
2165 | Vector3 sitTargetPos = prim.SitTargetPositionLL; | ||
2166 | row["SitTargetOffsetX"] = sitTargetPos.X; | ||
2167 | row["SitTargetOffsetY"] = sitTargetPos.Y; | ||
2168 | row["SitTargetOffsetZ"] = sitTargetPos.Z; | ||
2169 | |||
2170 | Quaternion sitTargetOrient = prim.SitTargetOrientationLL; | ||
2171 | row["SitTargetOrientW"] = sitTargetOrient.W; | ||
2172 | row["SitTargetOrientX"] = sitTargetOrient.X; | ||
2173 | row["SitTargetOrientY"] = sitTargetOrient.Y; | ||
2174 | row["SitTargetOrientZ"] = sitTargetOrient.Z; | ||
2175 | row["ColorR"] = Convert.ToInt32(prim.Color.R); | ||
2176 | row["ColorG"] = Convert.ToInt32(prim.Color.G); | ||
2177 | row["ColorB"] = Convert.ToInt32(prim.Color.B); | ||
2178 | row["ColorA"] = Convert.ToInt32(prim.Color.A); | ||
2179 | row["PayPrice"] = prim.PayPrice[0]; | ||
2180 | row["PayButton1"] = prim.PayPrice[1]; | ||
2181 | row["PayButton2"] = prim.PayPrice[2]; | ||
2182 | row["PayButton3"] = prim.PayPrice[3]; | ||
2183 | row["PayButton4"] = prim.PayPrice[4]; | ||
2184 | |||
2185 | row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation); | ||
2186 | row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem); | ||
2187 | |||
2188 | row["OmegaX"] = prim.AngularVelocity.X; | ||
2189 | row["OmegaY"] = prim.AngularVelocity.Y; | ||
2190 | row["OmegaZ"] = prim.AngularVelocity.Z; | ||
2191 | |||
2192 | row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X; | ||
2193 | row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y; | ||
2194 | row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z; | ||
2195 | |||
2196 | row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X; | ||
2197 | row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y; | ||
2198 | row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z; | ||
2199 | |||
2200 | |||
2201 | if ((prim.SoundFlags & 1) != 0) // Looped | ||
2202 | { | ||
2203 | row["LoopedSound"] = prim.Sound.ToString(); | ||
2204 | row["LoopedSoundGain"] = prim.SoundGain; | ||
2205 | } | ||
2206 | else | ||
2207 | { | ||
2208 | row["LoopedSound"] = UUID.Zero.ToString(); | ||
2209 | row["LoopedSoundGain"] = 0.0f; | ||
2210 | } | ||
2211 | |||
2212 | if (prim.GetForceMouselook()) | ||
2213 | row["ForceMouselook"] = 1; | ||
2214 | else | ||
2215 | row["ForceMouselook"] = 0; | ||
2216 | |||
2217 | row["ScriptAccessPin"] = prim.ScriptAccessPin; | ||
2218 | |||
2219 | if (prim.AllowedDrop) | ||
2220 | row["AllowedDrop"] = 1; | ||
2221 | else | ||
2222 | row["AllowedDrop"] = 0; | ||
2223 | |||
2224 | if (prim.DIE_AT_EDGE) | ||
2225 | row["DieAtEdge"] = 1; | ||
2226 | else | ||
2227 | row["DieAtEdge"] = 0; | ||
2228 | |||
2229 | row["SalePrice"] = prim.SalePrice; | ||
2230 | row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType); | ||
2231 | |||
2232 | // click action | ||
2233 | row["ClickAction"] = prim.ClickAction; | ||
2234 | |||
2235 | row["Material"] = prim.Material; | ||
2236 | |||
2237 | row["CollisionSound"] = prim.CollisionSound.ToString(); | ||
2238 | row["CollisionSoundVolume"] = prim.CollisionSoundVolume; | ||
2239 | if (prim.VolumeDetectActive) | ||
2240 | row["VolumeDetect"] = 1; | ||
2241 | else | ||
2242 | row["VolumeDetect"] = 0; | ||
2243 | |||
2244 | row["MediaURL"] = prim.MediaUrl; | ||
2245 | |||
2246 | row["AttachedPosX"] = prim.AttachedPos.X; | ||
2247 | row["AttachedPosY"] = prim.AttachedPos.Y; | ||
2248 | row["AttachedPosZ"] = prim.AttachedPos.Z; | ||
2249 | |||
2250 | if (prim.DynAttrs.CountNamespaces > 0) | ||
2251 | row["DynAttrs"] = prim.DynAttrs.ToXml(); | ||
2252 | else | ||
2253 | row["DynAttrs"] = null; | ||
2254 | |||
2255 | row["PhysicsShapeType"] = prim.PhysicsShapeType; | ||
2256 | row["Density"] = (double)prim.Density; | ||
2257 | row["GravityModifier"] = (double)prim.GravityModifier; | ||
2258 | row["Friction"] = (double)prim.Friction; | ||
2259 | row["Restitution"] = (double)prim.Restitution; | ||
2260 | |||
2261 | if (prim.KeyframeMotion != null) | ||
2262 | row["KeyframeMotion"] = prim.KeyframeMotion.Serialize(); | ||
2263 | else | ||
2264 | row["KeyframeMotion"] = new Byte[0]; | ||
2265 | |||
2266 | row["PassTouches"] = prim.PassTouches; | ||
2267 | row["PassCollisions"] = prim.PassCollisions; | ||
2268 | row["RotationAxisLocks"] = prim.RotationAxisLocks; | ||
2269 | |||
2270 | if (prim.VehicleParams != null) | ||
2271 | row["Vehicle"] = prim.VehicleParams.ToXml2(); | ||
2272 | else | ||
2273 | row["Vehicle"] = String.Empty; | ||
2274 | |||
2275 | if (prim.PhysicsInertia != null) | ||
2276 | row["PhysInertia"] = prim.PhysicsInertia.ToXml2(); | ||
2277 | else | ||
2278 | row["PhysInertia"] = String.Empty; | ||
2279 | |||
2280 | } | ||
2281 | |||
2282 | /// <summary> | ||
2283 | /// | ||
2284 | /// </summary> | ||
2285 | /// <param name="row"></param> | ||
2286 | /// <param name="taskItem"></param> | ||
2287 | private static void fillItemRow(DataRow row, TaskInventoryItem taskItem) | ||
2288 | { | ||
2289 | row["itemID"] = taskItem.ItemID.ToString(); | ||
2290 | row["primID"] = taskItem.ParentPartID.ToString(); | ||
2291 | row["assetID"] = taskItem.AssetID.ToString(); | ||
2292 | row["parentFolderID"] = taskItem.ParentID.ToString(); | ||
2293 | |||
2294 | row["invType"] = taskItem.InvType; | ||
2295 | row["assetType"] = taskItem.Type; | ||
2296 | |||
2297 | row["name"] = taskItem.Name; | ||
2298 | row["description"] = taskItem.Description; | ||
2299 | row["creationDate"] = taskItem.CreationDate; | ||
2300 | row["creatorID"] = taskItem.CreatorIdentification.ToString(); | ||
2301 | row["ownerID"] = taskItem.OwnerID.ToString(); | ||
2302 | row["lastOwnerID"] = taskItem.LastOwnerID.ToString(); | ||
2303 | row["groupID"] = taskItem.GroupID.ToString(); | ||
2304 | row["nextPermissions"] = taskItem.NextPermissions; | ||
2305 | row["currentPermissions"] = taskItem.CurrentPermissions; | ||
2306 | row["basePermissions"] = taskItem.BasePermissions; | ||
2307 | row["everyonePermissions"] = taskItem.EveryonePermissions; | ||
2308 | row["groupPermissions"] = taskItem.GroupPermissions; | ||
2309 | row["flags"] = taskItem.Flags; | ||
2310 | } | ||
2311 | |||
2312 | /// <summary> | ||
2313 | /// | ||
2314 | /// </summary> | ||
2315 | /// <param name="row"></param> | ||
2316 | /// <param name="land"></param> | ||
2317 | /// <param name="regionUUID"></param> | ||
2318 | private static void fillLandRow(DataRow row, LandData land, UUID regionUUID) | ||
2319 | { | ||
2320 | row["UUID"] = land.GlobalID.ToString(); | ||
2321 | row["RegionUUID"] = regionUUID.ToString(); | ||
2322 | row["LocalLandID"] = land.LocalID; | ||
2323 | |||
2324 | // Bitmap is a byte[512] | ||
2325 | row["Bitmap"] = land.Bitmap; | ||
2326 | |||
2327 | row["Name"] = land.Name; | ||
2328 | row["Desc"] = land.Description; | ||
2329 | row["OwnerUUID"] = land.OwnerID.ToString(); | ||
2330 | row["IsGroupOwned"] = land.IsGroupOwned.ToString(); | ||
2331 | row["Area"] = land.Area; | ||
2332 | row["AuctionID"] = land.AuctionID; //Unemplemented | ||
2333 | row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory | ||
2334 | row["ClaimDate"] = land.ClaimDate; | ||
2335 | row["ClaimPrice"] = land.ClaimPrice; | ||
2336 | row["GroupUUID"] = land.GroupID.ToString(); | ||
2337 | row["SalePrice"] = land.SalePrice; | ||
2338 | row["LandStatus"] = land.Status; //Enum. OpenMetaverse.Parcel.ParcelStatus | ||
2339 | row["LandFlags"] = land.Flags; | ||
2340 | row["LandingType"] = land.LandingType; | ||
2341 | row["MediaAutoScale"] = land.MediaAutoScale; | ||
2342 | row["MediaTextureUUID"] = land.MediaID.ToString(); | ||
2343 | row["MediaURL"] = land.MediaURL; | ||
2344 | row["MusicURL"] = land.MusicURL; | ||
2345 | row["PassHours"] = land.PassHours; | ||
2346 | row["PassPrice"] = land.PassPrice; | ||
2347 | row["SnapshotUUID"] = land.SnapshotID.ToString(); | ||
2348 | row["UserLocationX"] = land.UserLocation.X; | ||
2349 | row["UserLocationY"] = land.UserLocation.Y; | ||
2350 | row["UserLocationZ"] = land.UserLocation.Z; | ||
2351 | row["UserLookAtX"] = land.UserLookAt.X; | ||
2352 | row["UserLookAtY"] = land.UserLookAt.Y; | ||
2353 | row["UserLookAtZ"] = land.UserLookAt.Z; | ||
2354 | row["AuthbuyerID"] = land.AuthBuyerID.ToString(); | ||
2355 | row["OtherCleanTime"] = land.OtherCleanTime; | ||
2356 | row["Dwell"] = land.Dwell; | ||
2357 | row["MediaType"] = land.MediaType; | ||
2358 | row["MediaDescription"] = land.MediaDescription; | ||
2359 | row["MediaSize"] = String.Format("{0},{1}", land.MediaWidth, land.MediaHeight); | ||
2360 | row["MediaLoop"] = land.MediaLoop; | ||
2361 | row["ObscureMusic"] = land.ObscureMusic; | ||
2362 | row["ObscureMedia"] = land.ObscureMedia; | ||
2363 | row["SeeAVs"] = land.SeeAVs; | ||
2364 | row["AnyAVSounds"] = land.AnyAVSounds; | ||
2365 | row["GroupAVSounds"] = land.GroupAVSounds; | ||
2366 | |||
2367 | } | ||
2368 | |||
2369 | /// <summary> | ||
2370 | /// | ||
2371 | /// </summary> | ||
2372 | /// <param name="row"></param> | ||
2373 | /// <param name="entry"></param> | ||
2374 | /// <param name="parcelID"></param> | ||
2375 | private static void fillLandAccessRow(DataRow row, LandAccessEntry entry, UUID parcelID) | ||
2376 | { | ||
2377 | row["LandUUID"] = parcelID.ToString(); | ||
2378 | row["AccessUUID"] = entry.AgentID.ToString(); | ||
2379 | row["Flags"] = entry.Flags; | ||
2380 | } | ||
2381 | |||
2382 | private static void fillRegionSettingsRow(DataRow row, RegionSettings settings) | ||
2383 | { | ||
2384 | row["regionUUID"] = settings.RegionUUID.ToString(); | ||
2385 | row["block_terraform"] = settings.BlockTerraform; | ||
2386 | row["block_fly"] = settings.BlockFly; | ||
2387 | row["allow_damage"] = settings.AllowDamage; | ||
2388 | row["restrict_pushing"] = settings.RestrictPushing; | ||
2389 | row["allow_land_resell"] = settings.AllowLandResell; | ||
2390 | row["allow_land_join_divide"] = settings.AllowLandJoinDivide; | ||
2391 | row["block_show_in_search"] = settings.BlockShowInSearch; | ||
2392 | row["agent_limit"] = settings.AgentLimit; | ||
2393 | row["object_bonus"] = settings.ObjectBonus; | ||
2394 | row["maturity"] = settings.Maturity; | ||
2395 | row["disable_scripts"] = settings.DisableScripts; | ||
2396 | row["disable_collisions"] = settings.DisableCollisions; | ||
2397 | row["disable_physics"] = settings.DisablePhysics; | ||
2398 | row["terrain_texture_1"] = settings.TerrainTexture1.ToString(); | ||
2399 | row["terrain_texture_2"] = settings.TerrainTexture2.ToString(); | ||
2400 | row["terrain_texture_3"] = settings.TerrainTexture3.ToString(); | ||
2401 | row["terrain_texture_4"] = settings.TerrainTexture4.ToString(); | ||
2402 | row["elevation_1_nw"] = settings.Elevation1NW; | ||
2403 | row["elevation_2_nw"] = settings.Elevation2NW; | ||
2404 | row["elevation_1_ne"] = settings.Elevation1NE; | ||
2405 | row["elevation_2_ne"] = settings.Elevation2NE; | ||
2406 | row["elevation_1_se"] = settings.Elevation1SE; | ||
2407 | row["elevation_2_se"] = settings.Elevation2SE; | ||
2408 | row["elevation_1_sw"] = settings.Elevation1SW; | ||
2409 | row["elevation_2_sw"] = settings.Elevation2SW; | ||
2410 | row["water_height"] = settings.WaterHeight; | ||
2411 | row["terrain_raise_limit"] = settings.TerrainRaiseLimit; | ||
2412 | row["terrain_lower_limit"] = settings.TerrainLowerLimit; | ||
2413 | row["use_estate_sun"] = settings.UseEstateSun; | ||
2414 | row["sandbox"] = settings.Sandbox; // unlike other database modules, sqlite uses a lower case s for sandbox! | ||
2415 | row["sunvectorx"] = settings.SunVector.X; | ||
2416 | row["sunvectory"] = settings.SunVector.Y; | ||
2417 | row["sunvectorz"] = settings.SunVector.Z; | ||
2418 | row["fixed_sun"] = settings.FixedSun; | ||
2419 | row["sun_position"] = settings.SunPosition; | ||
2420 | row["covenant"] = settings.Covenant.ToString(); | ||
2421 | row["covenant_datetime"] = settings.CovenantChangedDateTime; | ||
2422 | row["map_tile_ID"] = settings.TerrainImageID.ToString(); | ||
2423 | row["TelehubObject"] = settings.TelehubObject.ToString(); | ||
2424 | row["parcel_tile_ID"] = settings.ParcelImageID.ToString(); | ||
2425 | row["block_search"] = settings.GodBlockSearch; | ||
2426 | row["casino"] = settings.Casino; | ||
2427 | } | ||
2428 | |||
2429 | /// <summary> | ||
2430 | /// | ||
2431 | /// </summary> | ||
2432 | /// <param name="row"></param> | ||
2433 | /// <param name="windlight"></param> | ||
2434 | private static void fillRegionWindlightRow(DataRow row, RegionLightShareData windlight) | ||
2435 | { | ||
2436 | row["region_id"] = windlight.regionID.ToString(); | ||
2437 | row["water_color_r"] = windlight.waterColor.X; | ||
2438 | row["water_color_g"] = windlight.waterColor.Y; | ||
2439 | row["water_color_b"] = windlight.waterColor.Z; | ||
2440 | row["water_color_i"] = 1; //windlight.waterColor.W; //not implemented | ||
2441 | row["water_fog_density_exponent"] = windlight.waterFogDensityExponent; | ||
2442 | row["underwater_fog_modifier"] = windlight.underwaterFogModifier; | ||
2443 | row["reflection_wavelet_scale_1"] = windlight.reflectionWaveletScale.X; | ||
2444 | row["reflection_wavelet_scale_2"] = windlight.reflectionWaveletScale.Y; | ||
2445 | row["reflection_wavelet_scale_3"] = windlight.reflectionWaveletScale.Z; | ||
2446 | row["fresnel_scale"] = windlight.fresnelScale; | ||
2447 | row["fresnel_offset"] = windlight.fresnelOffset; | ||
2448 | row["refract_scale_above"] = windlight.refractScaleAbove; | ||
2449 | row["refract_scale_below"] = windlight.refractScaleBelow; | ||
2450 | row["blur_multiplier"] = windlight.blurMultiplier; | ||
2451 | row["big_wave_direction_x"] = windlight.bigWaveDirection.X; | ||
2452 | row["big_wave_direction_y"] = windlight.bigWaveDirection.Y; | ||
2453 | row["little_wave_direction_x"] = windlight.littleWaveDirection.X; | ||
2454 | row["little_wave_direction_y"] = windlight.littleWaveDirection.Y; | ||
2455 | row["normal_map_texture"] = windlight.normalMapTexture.ToString(); | ||
2456 | row["horizon_r"] = windlight.horizon.X; | ||
2457 | row["horizon_g"] = windlight.horizon.Y; | ||
2458 | row["horizon_b"] = windlight.horizon.Z; | ||
2459 | row["horizon_i"] = windlight.horizon.W; | ||
2460 | row["haze_horizon"] = windlight.hazeHorizon; | ||
2461 | row["blue_density_r"] = windlight.blueDensity.X; | ||
2462 | row["blue_density_g"] = windlight.blueDensity.Y; | ||
2463 | row["blue_density_b"] = windlight.blueDensity.Z; | ||
2464 | row["blue_density_i"] = windlight.blueDensity.W; | ||
2465 | row["haze_density"] = windlight.hazeDensity; | ||
2466 | row["density_multiplier"] = windlight.densityMultiplier; | ||
2467 | row["distance_multiplier"] = windlight.distanceMultiplier; | ||
2468 | row["max_altitude"] = windlight.maxAltitude; | ||
2469 | row["sun_moon_color_r"] = windlight.sunMoonColor.X; | ||
2470 | row["sun_moon_color_g"] = windlight.sunMoonColor.Y; | ||
2471 | row["sun_moon_color_b"] = windlight.sunMoonColor.Z; | ||
2472 | row["sun_moon_color_i"] = windlight.sunMoonColor.W; | ||
2473 | row["sun_moon_position"] = windlight.sunMoonPosition; | ||
2474 | row["ambient_r"] = windlight.ambient.X; | ||
2475 | row["ambient_g"] = windlight.ambient.Y; | ||
2476 | row["ambient_b"] = windlight.ambient.Z; | ||
2477 | row["ambient_i"] = windlight.ambient.W; | ||
2478 | row["east_angle"] = windlight.eastAngle; | ||
2479 | row["sun_glow_focus"] = windlight.sunGlowFocus; | ||
2480 | row["sun_glow_size"] = windlight.sunGlowSize; | ||
2481 | row["scene_gamma"] = windlight.sceneGamma; | ||
2482 | row["star_brightness"] = windlight.starBrightness; | ||
2483 | row["cloud_color_r"] = windlight.cloudColor.X; | ||
2484 | row["cloud_color_g"] = windlight.cloudColor.Y; | ||
2485 | row["cloud_color_b"] = windlight.cloudColor.Z; | ||
2486 | row["cloud_color_i"] = windlight.cloudColor.W; | ||
2487 | row["cloud_x"] = windlight.cloudXYDensity.X; | ||
2488 | row["cloud_y"] = windlight.cloudXYDensity.Y; | ||
2489 | row["cloud_density"] = windlight.cloudXYDensity.Z; | ||
2490 | row["cloud_coverage"] = windlight.cloudCoverage; | ||
2491 | row["cloud_scale"] = windlight.cloudScale; | ||
2492 | row["cloud_detail_x"] = windlight.cloudDetailXYDensity.X; | ||
2493 | row["cloud_detail_y"] = windlight.cloudDetailXYDensity.Y; | ||
2494 | row["cloud_detail_density"] = windlight.cloudDetailXYDensity.Z; | ||
2495 | row["cloud_scroll_x"] = windlight.cloudScrollX; | ||
2496 | row["cloud_scroll_x_lock"] = windlight.cloudScrollXLock; | ||
2497 | row["cloud_scroll_y"] = windlight.cloudScrollY; | ||
2498 | row["cloud_scroll_y_lock"] = windlight.cloudScrollYLock; | ||
2499 | row["draw_classic_clouds"] = windlight.drawClassicClouds; | ||
2500 | } | ||
2501 | |||
2502 | /// <summary> | ||
2503 | /// | ||
2504 | /// </summary> | ||
2505 | /// <param name="row"></param> | ||
2506 | /// <returns></returns> | ||
2507 | private PrimitiveBaseShape buildShape(DataRow row) | ||
2508 | { | ||
2509 | PrimitiveBaseShape s = new PrimitiveBaseShape(); | ||
2510 | s.Scale = new Vector3( | ||
2511 | Convert.ToSingle(row["ScaleX"]), | ||
2512 | Convert.ToSingle(row["ScaleY"]), | ||
2513 | Convert.ToSingle(row["ScaleZ"]) | ||
2514 | ); | ||
2515 | // paths | ||
2516 | s.PCode = Convert.ToByte(row["PCode"]); | ||
2517 | s.PathBegin = Convert.ToUInt16(row["PathBegin"]); | ||
2518 | s.PathEnd = Convert.ToUInt16(row["PathEnd"]); | ||
2519 | s.PathScaleX = Convert.ToByte(row["PathScaleX"]); | ||
2520 | s.PathScaleY = Convert.ToByte(row["PathScaleY"]); | ||
2521 | s.PathShearX = Convert.ToByte(row["PathShearX"]); | ||
2522 | s.PathShearY = Convert.ToByte(row["PathShearY"]); | ||
2523 | s.PathSkew = Convert.ToSByte(row["PathSkew"]); | ||
2524 | s.PathCurve = Convert.ToByte(row["PathCurve"]); | ||
2525 | s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); | ||
2526 | s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); | ||
2527 | s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); | ||
2528 | s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); | ||
2529 | s.PathTwist = Convert.ToSByte(row["PathTwist"]); | ||
2530 | s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); | ||
2531 | // profile | ||
2532 | s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); | ||
2533 | s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); | ||
2534 | s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); | ||
2535 | s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]); | ||
2536 | s.State = Convert.ToByte(row["State"]); | ||
2537 | s.LastAttachPoint = Convert.ToByte(row["LastAttachPoint"]); | ||
2538 | |||
2539 | byte[] textureEntry = (byte[])row["Texture"]; | ||
2540 | s.TextureEntry = textureEntry; | ||
2541 | |||
2542 | s.ExtraParams = (byte[])row["ExtraParams"]; | ||
2543 | |||
2544 | if (!(row["Media"] is System.DBNull)) | ||
2545 | s.Media = PrimitiveBaseShape.MediaList.FromXml((string)row["Media"]); | ||
2546 | |||
2547 | return s; | ||
2548 | } | ||
2549 | |||
2550 | /// <summary> | ||
2551 | /// | ||
2552 | /// </summary> | ||
2553 | /// <param name="row"></param> | ||
2554 | /// <param name="prim"></param> | ||
2555 | private static void fillShapeRow(DataRow row, SceneObjectPart prim) | ||
2556 | { | ||
2557 | PrimitiveBaseShape s = prim.Shape; | ||
2558 | row["UUID"] = prim.UUID.ToString(); | ||
2559 | // shape is an enum | ||
2560 | row["Shape"] = 0; | ||
2561 | // vectors | ||
2562 | row["ScaleX"] = s.Scale.X; | ||
2563 | row["ScaleY"] = s.Scale.Y; | ||
2564 | row["ScaleZ"] = s.Scale.Z; | ||
2565 | // paths | ||
2566 | row["PCode"] = s.PCode; | ||
2567 | row["PathBegin"] = s.PathBegin; | ||
2568 | row["PathEnd"] = s.PathEnd; | ||
2569 | row["PathScaleX"] = s.PathScaleX; | ||
2570 | row["PathScaleY"] = s.PathScaleY; | ||
2571 | row["PathShearX"] = s.PathShearX; | ||
2572 | row["PathShearY"] = s.PathShearY; | ||
2573 | row["PathSkew"] = s.PathSkew; | ||
2574 | row["PathCurve"] = s.PathCurve; | ||
2575 | row["PathRadiusOffset"] = s.PathRadiusOffset; | ||
2576 | row["PathRevolutions"] = s.PathRevolutions; | ||
2577 | row["PathTaperX"] = s.PathTaperX; | ||
2578 | row["PathTaperY"] = s.PathTaperY; | ||
2579 | row["PathTwist"] = s.PathTwist; | ||
2580 | row["PathTwistBegin"] = s.PathTwistBegin; | ||
2581 | // profile | ||
2582 | row["ProfileBegin"] = s.ProfileBegin; | ||
2583 | row["ProfileEnd"] = s.ProfileEnd; | ||
2584 | row["ProfileCurve"] = s.ProfileCurve; | ||
2585 | row["ProfileHollow"] = s.ProfileHollow; | ||
2586 | row["State"] = s.State; | ||
2587 | row["LastAttachPoint"] = s.LastAttachPoint; | ||
2588 | |||
2589 | row["Texture"] = s.TextureEntry; | ||
2590 | row["ExtraParams"] = s.ExtraParams; | ||
2591 | |||
2592 | if (s.Media != null) | ||
2593 | row["Media"] = s.Media.ToXml(); | ||
2594 | } | ||
2595 | |||
2596 | /// <summary> | ||
2597 | /// Persistently store a prim. | ||
2598 | /// </summary> | ||
2599 | /// <param name="prim"></param> | ||
2600 | /// <param name="sceneGroupID"></param> | ||
2601 | /// <param name="regionUUID"></param> | ||
2602 | private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID) | ||
2603 | { | ||
2604 | DataTable prims = ds.Tables["prims"]; | ||
2605 | DataTable shapes = ds.Tables["primshapes"]; | ||
2606 | |||
2607 | DataRow primRow = prims.Rows.Find(prim.UUID.ToString()); | ||
2608 | if (primRow == null) | ||
2609 | { | ||
2610 | primRow = prims.NewRow(); | ||
2611 | fillPrimRow(primRow, prim, sceneGroupID, regionUUID); | ||
2612 | prims.Rows.Add(primRow); | ||
2613 | } | ||
2614 | else | ||
2615 | { | ||
2616 | fillPrimRow(primRow, prim, sceneGroupID, regionUUID); | ||
2617 | } | ||
2618 | |||
2619 | DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString()); | ||
2620 | if (shapeRow == null) | ||
2621 | { | ||
2622 | shapeRow = shapes.NewRow(); | ||
2623 | fillShapeRow(shapeRow, prim); | ||
2624 | shapes.Rows.Add(shapeRow); | ||
2625 | } | ||
2626 | else | ||
2627 | { | ||
2628 | fillShapeRow(shapeRow, prim); | ||
2629 | } | ||
2630 | } | ||
2631 | |||
2632 | /// <summary> | ||
2633 | /// </summary> | ||
2634 | /// <param name="primID"></param> | ||
2635 | /// <param name="items"></param> | ||
2636 | public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items) | ||
2637 | { | ||
2638 | // m_log.DebugFormat("[SQLITE REGION DB]: Entered StorePrimInventory with prim ID {0}", primID); | ||
2639 | |||
2640 | DataTable dbItems = ds.Tables["primitems"]; | ||
2641 | |||
2642 | // For now, we're just going to crudely remove all the previous inventory items | ||
2643 | // no matter whether they have changed or not, and replace them with the current set. | ||
2644 | lock (ds) | ||
2645 | { | ||
2646 | RemoveItems(primID); | ||
2647 | |||
2648 | // repalce with current inventory details | ||
2649 | foreach (TaskInventoryItem newItem in items) | ||
2650 | { | ||
2651 | // m_log.InfoFormat( | ||
2652 | // "[DATASTORE]: ", | ||
2653 | // "Adding item {0}, {1} to prim ID {2}", | ||
2654 | // newItem.Name, newItem.ItemID, newItem.ParentPartID); | ||
2655 | |||
2656 | DataRow newItemRow = dbItems.NewRow(); | ||
2657 | fillItemRow(newItemRow, newItem); | ||
2658 | dbItems.Rows.Add(newItemRow); | ||
2659 | } | ||
2660 | } | ||
2661 | |||
2662 | Commit(); | ||
2663 | } | ||
2664 | |||
2665 | /*********************************************************************** | ||
2666 | * | ||
2667 | * SQL Statement Creation Functions | ||
2668 | * | ||
2669 | * These functions create SQL statements for update, insert, and create. | ||
2670 | * They can probably be factored later to have a db independant | ||
2671 | * portion and a db specific portion | ||
2672 | * | ||
2673 | **********************************************************************/ | ||
2674 | |||
2675 | /// <summary> | ||
2676 | /// Create an insert command | ||
2677 | /// </summary> | ||
2678 | /// <param name="table">table name</param> | ||
2679 | /// <param name="dt">data table</param> | ||
2680 | /// <returns>the created command</returns> | ||
2681 | /// <remarks> | ||
2682 | /// This is subtle enough to deserve some commentary. | ||
2683 | /// Instead of doing *lots* and *lots of hardcoded strings | ||
2684 | /// for database definitions we'll use the fact that | ||
2685 | /// realistically all insert statements look like "insert | ||
2686 | /// into A(b, c) values(:b, :c) on the parameterized query | ||
2687 | /// front. If we just have a list of b, c, etc... we can | ||
2688 | /// generate these strings instead of typing them out. | ||
2689 | /// </remarks> | ||
2690 | private static SqliteCommand createInsertCommand(string table, DataTable dt) | ||
2691 | { | ||
2692 | string[] cols = new string[dt.Columns.Count]; | ||
2693 | for (int i = 0; i < dt.Columns.Count; i++) | ||
2694 | { | ||
2695 | DataColumn col = dt.Columns[i]; | ||
2696 | cols[i] = col.ColumnName; | ||
2697 | } | ||
2698 | |||
2699 | string sql = "insert into " + table + "("; | ||
2700 | sql += String.Join(", ", cols); | ||
2701 | // important, the first ':' needs to be here, the rest get added in the join | ||
2702 | sql += ") values (:"; | ||
2703 | sql += String.Join(", :", cols); | ||
2704 | sql += ")"; | ||
2705 | // m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); | ||
2706 | SqliteCommand cmd = new SqliteCommand(sql); | ||
2707 | |||
2708 | // this provides the binding for all our parameters, so | ||
2709 | // much less code than it used to be | ||
2710 | foreach (DataColumn col in dt.Columns) | ||
2711 | { | ||
2712 | cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); | ||
2713 | } | ||
2714 | return cmd; | ||
2715 | } | ||
2716 | |||
2717 | |||
2718 | /// <summary> | ||
2719 | /// create an update command | ||
2720 | /// </summary> | ||
2721 | /// <param name="table">table name</param> | ||
2722 | /// <param name="pk"></param> | ||
2723 | /// <param name="dt"></param> | ||
2724 | /// <returns>the created command</returns> | ||
2725 | private static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) | ||
2726 | { | ||
2727 | string sql = "update " + table + " set "; | ||
2728 | string subsql = String.Empty; | ||
2729 | foreach (DataColumn col in dt.Columns) | ||
2730 | { | ||
2731 | if (subsql.Length > 0) | ||
2732 | { | ||
2733 | // a map function would rock so much here | ||
2734 | subsql += ", "; | ||
2735 | } | ||
2736 | subsql += col.ColumnName + "= :" + col.ColumnName; | ||
2737 | } | ||
2738 | sql += subsql; | ||
2739 | sql += " where " + pk; | ||
2740 | SqliteCommand cmd = new SqliteCommand(sql); | ||
2741 | |||
2742 | // this provides the binding for all our parameters, so | ||
2743 | // much less code than it used to be | ||
2744 | |||
2745 | foreach (DataColumn col in dt.Columns) | ||
2746 | { | ||
2747 | cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); | ||
2748 | } | ||
2749 | return cmd; | ||
2750 | } | ||
2751 | |||
2752 | /// <summary> | ||
2753 | /// create an update command | ||
2754 | /// </summary> | ||
2755 | /// <param name="table">table name</param> | ||
2756 | /// <param name="pk"></param> | ||
2757 | /// <param name="dt"></param> | ||
2758 | /// <returns>the created command</returns> | ||
2759 | private static SqliteCommand createUpdateCommand(string table, string pk1, string pk2, DataTable dt) | ||
2760 | { | ||
2761 | string sql = "update " + table + " set "; | ||
2762 | string subsql = String.Empty; | ||
2763 | foreach (DataColumn col in dt.Columns) | ||
2764 | { | ||
2765 | if (subsql.Length > 0) | ||
2766 | { | ||
2767 | // a map function would rock so much here | ||
2768 | subsql += ", "; | ||
2769 | } | ||
2770 | subsql += col.ColumnName + "= :" + col.ColumnName; | ||
2771 | } | ||
2772 | sql += subsql; | ||
2773 | sql += " where " + pk1 + " and " + pk2; | ||
2774 | SqliteCommand cmd = new SqliteCommand(sql); | ||
2775 | |||
2776 | // this provides the binding for all our parameters, so | ||
2777 | // much less code than it used to be | ||
2778 | |||
2779 | foreach (DataColumn col in dt.Columns) | ||
2780 | { | ||
2781 | cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); | ||
2782 | } | ||
2783 | return cmd; | ||
2784 | } | ||
2785 | |||
2786 | /// <summary> | ||
2787 | /// | ||
2788 | /// </summary> | ||
2789 | /// <param name="dt">Data Table</param> | ||
2790 | /// <returns></returns> | ||
2791 | // private static string defineTable(DataTable dt) | ||
2792 | // { | ||
2793 | // string sql = "create table " + dt.TableName + "("; | ||
2794 | // string subsql = String.Empty; | ||
2795 | // foreach (DataColumn col in dt.Columns) | ||
2796 | // { | ||
2797 | // if (subsql.Length > 0) | ||
2798 | // { | ||
2799 | // // a map function would rock so much here | ||
2800 | // subsql += ",\n"; | ||
2801 | // } | ||
2802 | // subsql += col.ColumnName + " " + sqliteType(col.DataType); | ||
2803 | // if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0]) | ||
2804 | // { | ||
2805 | // subsql += " primary key"; | ||
2806 | // } | ||
2807 | // } | ||
2808 | // sql += subsql; | ||
2809 | // sql += ")"; | ||
2810 | // return sql; | ||
2811 | // } | ||
2812 | |||
2813 | /*********************************************************************** | ||
2814 | * | ||
2815 | * Database Binding functions | ||
2816 | * | ||
2817 | * These will be db specific due to typing, and minor differences | ||
2818 | * in databases. | ||
2819 | * | ||
2820 | **********************************************************************/ | ||
2821 | |||
2822 | ///<summary> | ||
2823 | /// This is a convenience function that collapses 5 repetitive | ||
2824 | /// lines for defining SqliteParameters to 2 parameters: | ||
2825 | /// column name and database type. | ||
2826 | /// | ||
2827 | /// It assumes certain conventions like :param as the param | ||
2828 | /// name to replace in parametrized queries, and that source | ||
2829 | /// version is always current version, both of which are fine | ||
2830 | /// for us. | ||
2831 | ///</summary> | ||
2832 | ///<returns>a built sqlite parameter</returns> | ||
2833 | private static SqliteParameter createSqliteParameter(string name, Type type) | ||
2834 | { | ||
2835 | SqliteParameter param = new SqliteParameter(); | ||
2836 | param.ParameterName = ":" + name; | ||
2837 | param.DbType = dbtypeFromType(type); | ||
2838 | param.SourceColumn = name; | ||
2839 | param.SourceVersion = DataRowVersion.Current; | ||
2840 | return param; | ||
2841 | } | ||
2842 | |||
2843 | /// <summary> | ||
2844 | /// | ||
2845 | /// </summary> | ||
2846 | /// <param name="da"></param> | ||
2847 | /// <param name="conn"></param> | ||
2848 | private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2849 | { | ||
2850 | da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]); | ||
2851 | da.InsertCommand.Connection = conn; | ||
2852 | |||
2853 | da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]); | ||
2854 | da.UpdateCommand.Connection = conn; | ||
2855 | |||
2856 | SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID"); | ||
2857 | delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); | ||
2858 | delete.Connection = conn; | ||
2859 | da.DeleteCommand = delete; | ||
2860 | } | ||
2861 | |||
2862 | /// <summary> | ||
2863 | /// | ||
2864 | /// </summary> | ||
2865 | /// <param name="da"></param> | ||
2866 | /// <param name="conn"></param> | ||
2867 | private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2868 | { | ||
2869 | da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]); | ||
2870 | da.InsertCommand.Connection = conn; | ||
2871 | |||
2872 | da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]); | ||
2873 | da.UpdateCommand.Connection = conn; | ||
2874 | |||
2875 | SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID"); | ||
2876 | delete.Parameters.Add(createSqliteParameter("itemID", typeof(String))); | ||
2877 | delete.Connection = conn; | ||
2878 | da.DeleteCommand = delete; | ||
2879 | } | ||
2880 | |||
2881 | /// <summary> | ||
2882 | /// | ||
2883 | /// </summary> | ||
2884 | /// <param name="da"></param> | ||
2885 | /// <param name="conn"></param> | ||
2886 | private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2887 | { | ||
2888 | da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]); | ||
2889 | da.InsertCommand.Connection = conn; | ||
2890 | } | ||
2891 | |||
2892 | /// <summary> | ||
2893 | /// | ||
2894 | /// </summary> | ||
2895 | /// <param name="da"></param> | ||
2896 | /// <param name="conn"></param> | ||
2897 | private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2898 | { | ||
2899 | da.InsertCommand = createInsertCommand("land", ds.Tables["land"]); | ||
2900 | da.InsertCommand.Connection = conn; | ||
2901 | |||
2902 | da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]); | ||
2903 | da.UpdateCommand.Connection = conn; | ||
2904 | |||
2905 | SqliteCommand delete = new SqliteCommand("delete from land where UUID=:UUID"); | ||
2906 | delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); | ||
2907 | da.DeleteCommand = delete; | ||
2908 | da.DeleteCommand.Connection = conn; | ||
2909 | } | ||
2910 | |||
2911 | /// <summary> | ||
2912 | /// | ||
2913 | /// </summary> | ||
2914 | /// <param name="da"></param> | ||
2915 | /// <param name="conn"></param> | ||
2916 | private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2917 | { | ||
2918 | da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]); | ||
2919 | da.InsertCommand.Connection = conn; | ||
2920 | |||
2921 | da.UpdateCommand = createUpdateCommand("landaccesslist", "LandUUID=:landUUID", "AccessUUID=:AccessUUID", ds.Tables["landaccesslist"]); | ||
2922 | da.UpdateCommand.Connection = conn; | ||
2923 | |||
2924 | SqliteCommand delete = new SqliteCommand("delete from landaccesslist where LandUUID= :LandUUID and AccessUUID= :AccessUUID"); | ||
2925 | delete.Parameters.Add(createSqliteParameter("LandUUID", typeof(String))); | ||
2926 | delete.Parameters.Add(createSqliteParameter("AccessUUID", typeof(String))); | ||
2927 | da.DeleteCommand = delete; | ||
2928 | da.DeleteCommand.Connection = conn; | ||
2929 | } | ||
2930 | |||
2931 | private void setupRegionSettingsCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2932 | { | ||
2933 | da.InsertCommand = createInsertCommand("regionsettings", ds.Tables["regionsettings"]); | ||
2934 | da.InsertCommand.Connection = conn; | ||
2935 | da.UpdateCommand = createUpdateCommand("regionsettings", "regionUUID=:regionUUID", ds.Tables["regionsettings"]); | ||
2936 | da.UpdateCommand.Connection = conn; | ||
2937 | } | ||
2938 | |||
2939 | /// <summary> | ||
2940 | /// | ||
2941 | /// </summary> | ||
2942 | /// <param name="da"></param> | ||
2943 | /// <param name="conn"></param> | ||
2944 | private void setupRegionWindlightCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2945 | { | ||
2946 | da.InsertCommand = createInsertCommand("regionwindlight", ds.Tables["regionwindlight"]); | ||
2947 | da.InsertCommand.Connection = conn; | ||
2948 | da.UpdateCommand = createUpdateCommand("regionwindlight", "region_id=:region_id", ds.Tables["regionwindlight"]); | ||
2949 | da.UpdateCommand.Connection = conn; | ||
2950 | } | ||
2951 | |||
2952 | private void setupRegionEnvironmentCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2953 | { | ||
2954 | da.InsertCommand = createInsertCommand("regionenvironment", ds.Tables["regionenvironment"]); | ||
2955 | da.InsertCommand.Connection = conn; | ||
2956 | da.UpdateCommand = createUpdateCommand("regionenvironment", "region_id=:region_id", ds.Tables["regionenvironment"]); | ||
2957 | da.UpdateCommand.Connection = conn; | ||
2958 | } | ||
2959 | |||
2960 | private void setupRegionSpawnPointsCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2961 | { | ||
2962 | da.InsertCommand = createInsertCommand("spawn_points", ds.Tables["spawn_points"]); | ||
2963 | da.InsertCommand.Connection = conn; | ||
2964 | da.UpdateCommand = createUpdateCommand("spawn_points", "RegionID=:RegionID", ds.Tables["spawn_points"]); | ||
2965 | da.UpdateCommand.Connection = conn; | ||
2966 | } | ||
2967 | |||
2968 | /// <summary> | ||
2969 | /// | ||
2970 | /// </summary> | ||
2971 | /// <param name="da"></param> | ||
2972 | /// <param name="conn"></param> | ||
2973 | private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) | ||
2974 | { | ||
2975 | da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]); | ||
2976 | da.InsertCommand.Connection = conn; | ||
2977 | |||
2978 | da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]); | ||
2979 | da.UpdateCommand.Connection = conn; | ||
2980 | |||
2981 | SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID"); | ||
2982 | delete.Parameters.Add(createSqliteParameter("UUID", typeof(String))); | ||
2983 | delete.Connection = conn; | ||
2984 | da.DeleteCommand = delete; | ||
2985 | } | ||
2986 | |||
2987 | /*********************************************************************** | ||
2988 | * | ||
2989 | * Type conversion functions | ||
2990 | * | ||
2991 | **********************************************************************/ | ||
2992 | |||
2993 | /// <summary> | ||
2994 | /// Type conversion function | ||
2995 | /// </summary> | ||
2996 | /// <param name="type"></param> | ||
2997 | /// <returns></returns> | ||
2998 | private static DbType dbtypeFromType(Type type) | ||
2999 | { | ||
3000 | if (type == typeof(String)) | ||
3001 | { | ||
3002 | return DbType.String; | ||
3003 | } | ||
3004 | else if (type == typeof(Int32)) | ||
3005 | { | ||
3006 | return DbType.Int32; | ||
3007 | } | ||
3008 | else if (type == typeof(Double)) | ||
3009 | { | ||
3010 | return DbType.Double; | ||
3011 | } | ||
3012 | else if (type == typeof(Byte)) | ||
3013 | { | ||
3014 | return DbType.Byte; | ||
3015 | } | ||
3016 | else if (type == typeof(Double)) | ||
3017 | { | ||
3018 | return DbType.Double; | ||
3019 | } | ||
3020 | else if (type == typeof(Byte[])) | ||
3021 | { | ||
3022 | return DbType.Binary; | ||
3023 | } | ||
3024 | else if (type == typeof(Boolean)) | ||
3025 | { | ||
3026 | return DbType.Boolean; | ||
3027 | } | ||
3028 | else | ||
3029 | { | ||
3030 | return DbType.String; | ||
3031 | } | ||
3032 | } | ||
3033 | |||
3034 | static void PrintDataSet(DataSet ds) | ||
3035 | { | ||
3036 | // Print out any name and extended properties. | ||
3037 | Console.WriteLine("DataSet is named: {0}", ds.DataSetName); | ||
3038 | foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties) | ||
3039 | { | ||
3040 | Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); | ||
3041 | } | ||
3042 | Console.WriteLine(); | ||
3043 | foreach (DataTable dt in ds.Tables) | ||
3044 | { | ||
3045 | Console.WriteLine("=> {0} Table:", dt.TableName); | ||
3046 | // Print out the column names. | ||
3047 | for (int curCol = 0; curCol < dt.Columns.Count; curCol++) | ||
3048 | { | ||
3049 | Console.Write(dt.Columns[curCol].ColumnName + "\t"); | ||
3050 | } | ||
3051 | Console.WriteLine("\n----------------------------------"); | ||
3052 | // Print the DataTable. | ||
3053 | for (int curRow = 0; curRow < dt.Rows.Count; curRow++) | ||
3054 | { | ||
3055 | for (int curCol = 0; curCol < dt.Columns.Count; curCol++) | ||
3056 | { | ||
3057 | Console.Write(dt.Rows[curRow][curCol].ToString() + "\t"); | ||
3058 | } | ||
3059 | Console.WriteLine(); | ||
3060 | } | ||
3061 | } | ||
3062 | } | ||
3063 | |||
3064 | public UUID[] GetObjectIDs(UUID regionID) | ||
3065 | { | ||
3066 | return new UUID[0]; | ||
3067 | } | ||
3068 | |||
3069 | public void SaveExtra(UUID regionID, string name, string value) | ||
3070 | { | ||
3071 | } | ||
3072 | |||
3073 | public void RemoveExtra(UUID regionID, string name) | ||
3074 | { | ||
3075 | } | ||
3076 | |||
3077 | public Dictionary<string, string> GetExtra(UUID regionID) | ||
3078 | { | ||
3079 | return null; | ||
3080 | } | ||
3081 | } | ||
3082 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs new file mode 100644 index 0000000..1b79185 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs | |||
@@ -0,0 +1,91 @@ | |||
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 | #if CSharpSqlite | ||
35 | using Community.CsharpSqlite.Sqlite; | ||
36 | #else | ||
37 | using Mono.Data.Sqlite; | ||
38 | #endif | ||
39 | |||
40 | namespace OpenSim.Data.SQLite | ||
41 | { | ||
42 | public class SQLiteUserAccountData : SQLiteGenericTableHandler<UserAccountData>, IUserAccountData | ||
43 | { | ||
44 | public SQLiteUserAccountData(string connectionString, string realm) | ||
45 | : base(connectionString, realm, "UserAccount") | ||
46 | { | ||
47 | } | ||
48 | |||
49 | public UserAccountData[] GetUsers(UUID scopeID, string query) | ||
50 | { | ||
51 | string[] words = query.Split(new char[] {' '}); | ||
52 | |||
53 | for (int i = 0 ; i < words.Length ; i++) | ||
54 | { | ||
55 | if (words[i].Length < 3) | ||
56 | { | ||
57 | if (i != words.Length - 1) | ||
58 | Array.Copy(words, i + 1, words, i, words.Length - i - 1); | ||
59 | Array.Resize(ref words, words.Length - 1); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | if (words.Length == 0) | ||
64 | return new UserAccountData[0]; | ||
65 | |||
66 | if (words.Length > 2) | ||
67 | return new UserAccountData[0]; | ||
68 | |||
69 | using (SqliteCommand cmd = new SqliteCommand()) | ||
70 | { | ||
71 | if (words.Length == 1) | ||
72 | { | ||
73 | 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}%')", | ||
74 | m_Realm, scopeID.ToString(), words[0]); | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | 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}%')", | ||
79 | m_Realm, scopeID.ToString(), words[0], words[1]); | ||
80 | } | ||
81 | |||
82 | return DoQuery(cmd); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | public UserAccountData[] GetUsersWhere(UUID scopeID, string where) | ||
87 | { | ||
88 | return null; | ||
89 | } | ||
90 | } | ||
91 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs new file mode 100644 index 0000000..13aac79 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs | |||
@@ -0,0 +1,982 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Data; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | #if CSharpSqlite | ||
34 | using Community.CsharpSqlite.Sqlite; | ||
35 | #else | ||
36 | using Mono.Data.Sqlite; | ||
37 | #endif | ||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.StructuredData; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | |||
43 | namespace OpenSim.Data.SQLite | ||
44 | { | ||
45 | public class SQLiteUserProfilesData: IProfilesData | ||
46 | { | ||
47 | private static readonly ILog m_log = | ||
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private SqliteConnection m_connection; | ||
51 | private string m_connectionString; | ||
52 | |||
53 | private Dictionary<string, FieldInfo> m_FieldMap = | ||
54 | new Dictionary<string, FieldInfo>(); | ||
55 | |||
56 | protected virtual Assembly Assembly | ||
57 | { | ||
58 | get { return GetType().Assembly; } | ||
59 | } | ||
60 | |||
61 | public SQLiteUserProfilesData() | ||
62 | { | ||
63 | } | ||
64 | |||
65 | public SQLiteUserProfilesData(string connectionString) | ||
66 | { | ||
67 | Initialise(connectionString); | ||
68 | } | ||
69 | |||
70 | public void Initialise(string connectionString) | ||
71 | { | ||
72 | if (Util.IsWindows()) | ||
73 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
74 | |||
75 | m_connectionString = connectionString; | ||
76 | |||
77 | m_log.Info("[PROFILES_DATA]: Sqlite - connecting: "+m_connectionString); | ||
78 | |||
79 | m_connection = new SqliteConnection(m_connectionString); | ||
80 | m_connection.Open(); | ||
81 | |||
82 | Migration m = new Migration(m_connection, Assembly, "UserProfiles"); | ||
83 | m.Update(); | ||
84 | } | ||
85 | |||
86 | private string[] FieldList | ||
87 | { | ||
88 | get { return new List<string>(m_FieldMap.Keys).ToArray(); } | ||
89 | } | ||
90 | |||
91 | #region IProfilesData implementation | ||
92 | public OSDArray GetClassifiedRecords(UUID creatorId) | ||
93 | { | ||
94 | OSDArray data = new OSDArray(); | ||
95 | string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = :Id"; | ||
96 | IDataReader reader = null; | ||
97 | |||
98 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
99 | { | ||
100 | cmd.CommandText = query; | ||
101 | cmd.Parameters.AddWithValue(":Id", creatorId); | ||
102 | reader = cmd.ExecuteReader(); | ||
103 | } | ||
104 | |||
105 | while (reader.Read()) | ||
106 | { | ||
107 | OSDMap n = new OSDMap(); | ||
108 | UUID Id = UUID.Zero; | ||
109 | string Name = null; | ||
110 | try | ||
111 | { | ||
112 | UUID.TryParse(Convert.ToString( reader["classifieduuid"]), out Id); | ||
113 | Name = Convert.ToString(reader["name"]); | ||
114 | } | ||
115 | catch (Exception e) | ||
116 | { | ||
117 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
118 | ": UserAccount exception {0}", e.Message); | ||
119 | } | ||
120 | n.Add("classifieduuid", OSD.FromUUID(Id)); | ||
121 | n.Add("name", OSD.FromString(Name)); | ||
122 | data.Add(n); | ||
123 | } | ||
124 | |||
125 | reader.Close(); | ||
126 | |||
127 | return data; | ||
128 | } | ||
129 | public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) | ||
130 | { | ||
131 | string query = string.Empty; | ||
132 | |||
133 | query += "INSERT OR REPLACE INTO classifieds ("; | ||
134 | query += "`classifieduuid`,"; | ||
135 | query += "`creatoruuid`,"; | ||
136 | query += "`creationdate`,"; | ||
137 | query += "`expirationdate`,"; | ||
138 | query += "`category`,"; | ||
139 | query += "`name`,"; | ||
140 | query += "`description`,"; | ||
141 | query += "`parceluuid`,"; | ||
142 | query += "`parentestate`,"; | ||
143 | query += "`snapshotuuid`,"; | ||
144 | query += "`simname`,"; | ||
145 | query += "`posglobal`,"; | ||
146 | query += "`parcelname`,"; | ||
147 | query += "`classifiedflags`,"; | ||
148 | query += "`priceforlisting`) "; | ||
149 | query += "VALUES ("; | ||
150 | query += ":ClassifiedId,"; | ||
151 | query += ":CreatorId,"; | ||
152 | query += ":CreatedDate,"; | ||
153 | query += ":ExpirationDate,"; | ||
154 | query += ":Category,"; | ||
155 | query += ":Name,"; | ||
156 | query += ":Description,"; | ||
157 | query += ":ParcelId,"; | ||
158 | query += ":ParentEstate,"; | ||
159 | query += ":SnapshotId,"; | ||
160 | query += ":SimName,"; | ||
161 | query += ":GlobalPos,"; | ||
162 | query += ":ParcelName,"; | ||
163 | query += ":Flags,"; | ||
164 | query += ":ListingPrice ) "; | ||
165 | |||
166 | if(string.IsNullOrEmpty(ad.ParcelName)) | ||
167 | ad.ParcelName = "Unknown"; | ||
168 | if(ad.ParcelId == null) | ||
169 | ad.ParcelId = UUID.Zero; | ||
170 | if(string.IsNullOrEmpty(ad.Description)) | ||
171 | ad.Description = "No Description"; | ||
172 | |||
173 | DateTime epoch = new DateTime(1970, 1, 1); | ||
174 | DateTime now = DateTime.Now; | ||
175 | TimeSpan epochnow = now - epoch; | ||
176 | TimeSpan duration; | ||
177 | DateTime expiration; | ||
178 | TimeSpan epochexp; | ||
179 | |||
180 | if(ad.Flags == 2) | ||
181 | { | ||
182 | duration = new TimeSpan(7,0,0,0); | ||
183 | expiration = now.Add(duration); | ||
184 | epochexp = expiration - epoch; | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | duration = new TimeSpan(365,0,0,0); | ||
189 | expiration = now.Add(duration); | ||
190 | epochexp = expiration - epoch; | ||
191 | } | ||
192 | ad.CreationDate = (int)epochnow.TotalSeconds; | ||
193 | ad.ExpirationDate = (int)epochexp.TotalSeconds; | ||
194 | |||
195 | try { | ||
196 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
197 | { | ||
198 | cmd.CommandText = query; | ||
199 | cmd.Parameters.AddWithValue(":ClassifiedId", ad.ClassifiedId.ToString()); | ||
200 | cmd.Parameters.AddWithValue(":CreatorId", ad.CreatorId.ToString()); | ||
201 | cmd.Parameters.AddWithValue(":CreatedDate", ad.CreationDate.ToString()); | ||
202 | cmd.Parameters.AddWithValue(":ExpirationDate", ad.ExpirationDate.ToString()); | ||
203 | cmd.Parameters.AddWithValue(":Category", ad.Category.ToString()); | ||
204 | cmd.Parameters.AddWithValue(":Name", ad.Name.ToString()); | ||
205 | cmd.Parameters.AddWithValue(":Description", ad.Description.ToString()); | ||
206 | cmd.Parameters.AddWithValue(":ParcelId", ad.ParcelId.ToString()); | ||
207 | cmd.Parameters.AddWithValue(":ParentEstate", ad.ParentEstate.ToString()); | ||
208 | cmd.Parameters.AddWithValue(":SnapshotId", ad.SnapshotId.ToString ()); | ||
209 | cmd.Parameters.AddWithValue(":SimName", ad.SimName.ToString()); | ||
210 | cmd.Parameters.AddWithValue(":GlobalPos", ad.GlobalPos.ToString()); | ||
211 | cmd.Parameters.AddWithValue(":ParcelName", ad.ParcelName.ToString()); | ||
212 | cmd.Parameters.AddWithValue(":Flags", ad.Flags.ToString()); | ||
213 | cmd.Parameters.AddWithValue(":ListingPrice", ad.Price.ToString ()); | ||
214 | |||
215 | cmd.ExecuteNonQuery(); | ||
216 | } | ||
217 | } | ||
218 | catch (Exception e) | ||
219 | { | ||
220 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
221 | ": ClassifiedesUpdate exception {0}", e.Message); | ||
222 | result = e.Message; | ||
223 | return false; | ||
224 | } | ||
225 | return true; | ||
226 | } | ||
227 | public bool DeleteClassifiedRecord(UUID recordId) | ||
228 | { | ||
229 | string query = string.Empty; | ||
230 | |||
231 | query += "DELETE FROM classifieds WHERE "; | ||
232 | query += "classifieduuid = :ClasifiedId"; | ||
233 | |||
234 | try | ||
235 | { | ||
236 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
237 | { | ||
238 | cmd.CommandText = query; | ||
239 | cmd.Parameters.AddWithValue(":ClassifiedId", recordId.ToString()); | ||
240 | |||
241 | cmd.ExecuteNonQuery(); | ||
242 | } | ||
243 | } | ||
244 | catch (Exception e) | ||
245 | { | ||
246 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
247 | ": DeleteClassifiedRecord exception {0}", e.Message); | ||
248 | return false; | ||
249 | } | ||
250 | return true; | ||
251 | } | ||
252 | |||
253 | public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) | ||
254 | { | ||
255 | IDataReader reader = null; | ||
256 | string query = string.Empty; | ||
257 | |||
258 | query += "SELECT * FROM classifieds WHERE "; | ||
259 | query += "classifieduuid = :AdId"; | ||
260 | |||
261 | try | ||
262 | { | ||
263 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
264 | { | ||
265 | cmd.CommandText = query; | ||
266 | cmd.Parameters.AddWithValue(":AdId", ad.ClassifiedId.ToString()); | ||
267 | |||
268 | using (reader = cmd.ExecuteReader()) | ||
269 | { | ||
270 | if(reader.Read ()) | ||
271 | { | ||
272 | ad.CreatorId = new UUID(reader["creatoruuid"].ToString()); | ||
273 | ad.ParcelId = new UUID(reader["parceluuid"].ToString ()); | ||
274 | ad.SnapshotId = new UUID(reader["snapshotuuid"].ToString ()); | ||
275 | ad.CreationDate = Convert.ToInt32(reader["creationdate"]); | ||
276 | ad.ExpirationDate = Convert.ToInt32(reader["expirationdate"]); | ||
277 | ad.ParentEstate = Convert.ToInt32(reader["parentestate"]); | ||
278 | ad.Flags = (byte) Convert.ToUInt32(reader["classifiedflags"]); | ||
279 | ad.Category = Convert.ToInt32(reader["category"]); | ||
280 | ad.Price = Convert.ToInt16(reader["priceforlisting"]); | ||
281 | ad.Name = reader["name"].ToString(); | ||
282 | ad.Description = reader["description"].ToString(); | ||
283 | ad.SimName = reader["simname"].ToString(); | ||
284 | ad.GlobalPos = reader["posglobal"].ToString(); | ||
285 | ad.ParcelName = reader["parcelname"].ToString(); | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | catch (Exception e) | ||
291 | { | ||
292 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
293 | ": GetPickInfo exception {0}", e.Message); | ||
294 | } | ||
295 | return true; | ||
296 | } | ||
297 | |||
298 | public OSDArray GetAvatarPicks(UUID avatarId) | ||
299 | { | ||
300 | IDataReader reader = null; | ||
301 | string query = string.Empty; | ||
302 | |||
303 | query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; | ||
304 | query += "creatoruuid = :Id"; | ||
305 | OSDArray data = new OSDArray(); | ||
306 | |||
307 | try | ||
308 | { | ||
309 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
310 | { | ||
311 | cmd.CommandText = query; | ||
312 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
313 | |||
314 | using (reader = cmd.ExecuteReader()) | ||
315 | { | ||
316 | while (reader.Read()) | ||
317 | { | ||
318 | OSDMap record = new OSDMap(); | ||
319 | |||
320 | record.Add("pickuuid",OSD.FromString((string)reader["pickuuid"])); | ||
321 | record.Add("name",OSD.FromString((string)reader["name"])); | ||
322 | data.Add(record); | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | catch (Exception e) | ||
328 | { | ||
329 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
330 | ": GetAvatarPicks exception {0}", e.Message); | ||
331 | } | ||
332 | return data; | ||
333 | } | ||
334 | public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) | ||
335 | { | ||
336 | IDataReader reader = null; | ||
337 | string query = string.Empty; | ||
338 | UserProfilePick pick = new UserProfilePick(); | ||
339 | |||
340 | query += "SELECT * FROM userpicks WHERE "; | ||
341 | query += "creatoruuid = :CreatorId AND "; | ||
342 | query += "pickuuid = :PickId"; | ||
343 | |||
344 | try | ||
345 | { | ||
346 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
347 | { | ||
348 | cmd.CommandText = query; | ||
349 | cmd.Parameters.AddWithValue(":CreatorId", avatarId.ToString()); | ||
350 | cmd.Parameters.AddWithValue(":PickId", pickId.ToString()); | ||
351 | |||
352 | using (reader = cmd.ExecuteReader()) | ||
353 | { | ||
354 | |||
355 | while (reader.Read()) | ||
356 | { | ||
357 | string description = (string)reader["description"]; | ||
358 | |||
359 | if (string.IsNullOrEmpty(description)) | ||
360 | description = "No description given."; | ||
361 | |||
362 | UUID.TryParse((string)reader["pickuuid"], out pick.PickId); | ||
363 | UUID.TryParse((string)reader["creatoruuid"], out pick.CreatorId); | ||
364 | UUID.TryParse((string)reader["parceluuid"], out pick.ParcelId); | ||
365 | UUID.TryParse((string)reader["snapshotuuid"], out pick.SnapshotId); | ||
366 | pick.GlobalPos = (string)reader["posglobal"]; | ||
367 | bool.TryParse((string)reader["toppick"].ToString(), out pick.TopPick); | ||
368 | bool.TryParse((string)reader["enabled"].ToString(), out pick.Enabled); | ||
369 | pick.Name = (string)reader["name"]; | ||
370 | pick.Desc = description; | ||
371 | pick.ParcelName = (string)reader["user"]; | ||
372 | pick.OriginalName = (string)reader["originalname"]; | ||
373 | pick.SimName = (string)reader["simname"]; | ||
374 | pick.SortOrder = (int)reader["sortorder"]; | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | catch (Exception e) | ||
380 | { | ||
381 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
382 | ": GetPickInfo exception {0}", e.Message); | ||
383 | } | ||
384 | return pick; | ||
385 | } | ||
386 | |||
387 | public bool UpdatePicksRecord(UserProfilePick pick) | ||
388 | { | ||
389 | string query = string.Empty; | ||
390 | |||
391 | query += "INSERT OR REPLACE INTO userpicks ("; | ||
392 | query += "pickuuid, "; | ||
393 | query += "creatoruuid, "; | ||
394 | query += "toppick, "; | ||
395 | query += "parceluuid, "; | ||
396 | query += "name, "; | ||
397 | query += "description, "; | ||
398 | query += "snapshotuuid, "; | ||
399 | query += "user, "; | ||
400 | query += "originalname, "; | ||
401 | query += "simname, "; | ||
402 | query += "posglobal, "; | ||
403 | query += "sortorder, "; | ||
404 | query += "enabled ) "; | ||
405 | query += "VALUES ("; | ||
406 | query += ":PickId,"; | ||
407 | query += ":CreatorId,"; | ||
408 | query += ":TopPick,"; | ||
409 | query += ":ParcelId,"; | ||
410 | query += ":Name,"; | ||
411 | query += ":Desc,"; | ||
412 | query += ":SnapshotId,"; | ||
413 | query += ":User,"; | ||
414 | query += ":Original,"; | ||
415 | query += ":SimName,"; | ||
416 | query += ":GlobalPos,"; | ||
417 | query += ":SortOrder,"; | ||
418 | query += ":Enabled) "; | ||
419 | |||
420 | try | ||
421 | { | ||
422 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
423 | { | ||
424 | int top_pick; | ||
425 | int.TryParse(pick.TopPick.ToString(), out top_pick); | ||
426 | int enabled; | ||
427 | int.TryParse(pick.Enabled.ToString(), out enabled); | ||
428 | |||
429 | cmd.CommandText = query; | ||
430 | cmd.Parameters.AddWithValue(":PickId", pick.PickId.ToString()); | ||
431 | cmd.Parameters.AddWithValue(":CreatorId", pick.CreatorId.ToString()); | ||
432 | cmd.Parameters.AddWithValue(":TopPick", top_pick); | ||
433 | cmd.Parameters.AddWithValue(":ParcelId", pick.ParcelId.ToString()); | ||
434 | cmd.Parameters.AddWithValue(":Name", pick.Name.ToString()); | ||
435 | cmd.Parameters.AddWithValue(":Desc", pick.Desc.ToString()); | ||
436 | cmd.Parameters.AddWithValue(":SnapshotId", pick.SnapshotId.ToString()); | ||
437 | cmd.Parameters.AddWithValue(":User", pick.ParcelName.ToString()); | ||
438 | cmd.Parameters.AddWithValue(":Original", pick.OriginalName.ToString()); | ||
439 | cmd.Parameters.AddWithValue(":SimName",pick.SimName.ToString()); | ||
440 | cmd.Parameters.AddWithValue(":GlobalPos", pick.GlobalPos); | ||
441 | cmd.Parameters.AddWithValue(":SortOrder", pick.SortOrder.ToString ()); | ||
442 | cmd.Parameters.AddWithValue(":Enabled", enabled); | ||
443 | |||
444 | cmd.ExecuteNonQuery(); | ||
445 | } | ||
446 | } | ||
447 | catch (Exception e) | ||
448 | { | ||
449 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
450 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
451 | return false; | ||
452 | } | ||
453 | return true; | ||
454 | } | ||
455 | |||
456 | public bool DeletePicksRecord(UUID pickId) | ||
457 | { | ||
458 | string query = string.Empty; | ||
459 | |||
460 | query += "DELETE FROM userpicks WHERE "; | ||
461 | query += "pickuuid = :PickId"; | ||
462 | |||
463 | try | ||
464 | { | ||
465 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
466 | { | ||
467 | cmd.CommandText = query; | ||
468 | cmd.Parameters.AddWithValue(":PickId", pickId.ToString()); | ||
469 | cmd.ExecuteNonQuery(); | ||
470 | } | ||
471 | } | ||
472 | catch (Exception e) | ||
473 | { | ||
474 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
475 | ": DeleteUserPickRecord exception {0}", e.Message); | ||
476 | return false; | ||
477 | } | ||
478 | return true; | ||
479 | } | ||
480 | |||
481 | public bool GetAvatarNotes(ref UserProfileNotes notes) | ||
482 | { | ||
483 | IDataReader reader = null; | ||
484 | string query = string.Empty; | ||
485 | |||
486 | query += "SELECT `notes` FROM usernotes WHERE "; | ||
487 | query += "useruuid = :Id AND "; | ||
488 | query += "targetuuid = :TargetId"; | ||
489 | OSDArray data = new OSDArray(); | ||
490 | |||
491 | try | ||
492 | { | ||
493 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
494 | { | ||
495 | cmd.CommandText = query; | ||
496 | cmd.Parameters.AddWithValue(":Id", notes.UserId.ToString()); | ||
497 | cmd.Parameters.AddWithValue(":TargetId", notes.TargetId.ToString()); | ||
498 | |||
499 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
500 | { | ||
501 | while (reader.Read()) | ||
502 | { | ||
503 | notes.Notes = OSD.FromString((string)reader["notes"]); | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | } | ||
508 | catch (Exception e) | ||
509 | { | ||
510 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
511 | ": GetAvatarNotes exception {0}", e.Message); | ||
512 | } | ||
513 | return true; | ||
514 | } | ||
515 | |||
516 | public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) | ||
517 | { | ||
518 | string query = string.Empty; | ||
519 | bool remove; | ||
520 | |||
521 | if(string.IsNullOrEmpty(note.Notes)) | ||
522 | { | ||
523 | remove = true; | ||
524 | query += "DELETE FROM usernotes WHERE "; | ||
525 | query += "useruuid=:UserId AND "; | ||
526 | query += "targetuuid=:TargetId"; | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | remove = false; | ||
531 | query += "INSERT OR REPLACE INTO usernotes VALUES ( "; | ||
532 | query += ":UserId,"; | ||
533 | query += ":TargetId,"; | ||
534 | query += ":Notes )"; | ||
535 | } | ||
536 | |||
537 | try | ||
538 | { | ||
539 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
540 | { | ||
541 | cmd.CommandText = query; | ||
542 | |||
543 | if(!remove) | ||
544 | cmd.Parameters.AddWithValue(":Notes", note.Notes); | ||
545 | cmd.Parameters.AddWithValue(":TargetId", note.TargetId.ToString ()); | ||
546 | cmd.Parameters.AddWithValue(":UserId", note.UserId.ToString()); | ||
547 | |||
548 | cmd.ExecuteNonQuery(); | ||
549 | } | ||
550 | } | ||
551 | catch (Exception e) | ||
552 | { | ||
553 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
554 | ": UpdateAvatarNotes exception {0}", e.Message); | ||
555 | return false; | ||
556 | } | ||
557 | return true; | ||
558 | } | ||
559 | |||
560 | public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) | ||
561 | { | ||
562 | IDataReader reader = null; | ||
563 | string query = string.Empty; | ||
564 | |||
565 | query += "SELECT * FROM userprofile WHERE "; | ||
566 | query += "useruuid = :Id"; | ||
567 | |||
568 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
569 | { | ||
570 | cmd.CommandText = query; | ||
571 | cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
572 | |||
573 | |||
574 | try | ||
575 | { | ||
576 | reader = cmd.ExecuteReader(); | ||
577 | } | ||
578 | catch(Exception e) | ||
579 | { | ||
580 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
581 | ": GetAvatarProperties exception {0}", e.Message); | ||
582 | result = e.Message; | ||
583 | return false; | ||
584 | } | ||
585 | if(reader != null && reader.Read()) | ||
586 | { | ||
587 | props.WebUrl = (string)reader["profileURL"]; | ||
588 | UUID.TryParse((string)reader["profileImage"], out props.ImageId); | ||
589 | props.AboutText = (string)reader["profileAboutText"]; | ||
590 | UUID.TryParse((string)reader["profileFirstImage"], out props.FirstLifeImageId); | ||
591 | props.FirstLifeText = (string)reader["profileFirstText"]; | ||
592 | UUID.TryParse((string)reader["profilePartner"], out props.PartnerId); | ||
593 | props.WantToMask = (int)reader["profileWantToMask"]; | ||
594 | props.WantToText = (string)reader["profileWantToText"]; | ||
595 | props.SkillsMask = (int)reader["profileSkillsMask"]; | ||
596 | props.SkillsText = (string)reader["profileSkillsText"]; | ||
597 | props.Language = (string)reader["profileLanguages"]; | ||
598 | } | ||
599 | else | ||
600 | { | ||
601 | props.WebUrl = string.Empty; | ||
602 | props.ImageId = UUID.Zero; | ||
603 | props.AboutText = string.Empty; | ||
604 | props.FirstLifeImageId = UUID.Zero; | ||
605 | props.FirstLifeText = string.Empty; | ||
606 | props.PartnerId = UUID.Zero; | ||
607 | props.WantToMask = 0; | ||
608 | props.WantToText = string.Empty; | ||
609 | props.SkillsMask = 0; | ||
610 | props.SkillsText = string.Empty; | ||
611 | props.Language = string.Empty; | ||
612 | props.PublishProfile = false; | ||
613 | props.PublishMature = false; | ||
614 | |||
615 | query = "INSERT INTO userprofile ("; | ||
616 | query += "useruuid, "; | ||
617 | query += "profilePartner, "; | ||
618 | query += "profileAllowPublish, "; | ||
619 | query += "profileMaturePublish, "; | ||
620 | query += "profileURL, "; | ||
621 | query += "profileWantToMask, "; | ||
622 | query += "profileWantToText, "; | ||
623 | query += "profileSkillsMask, "; | ||
624 | query += "profileSkillsText, "; | ||
625 | query += "profileLanguages, "; | ||
626 | query += "profileImage, "; | ||
627 | query += "profileAboutText, "; | ||
628 | query += "profileFirstImage, "; | ||
629 | query += "profileFirstText) VALUES ("; | ||
630 | query += ":userId, "; | ||
631 | query += ":profilePartner, "; | ||
632 | query += ":profileAllowPublish, "; | ||
633 | query += ":profileMaturePublish, "; | ||
634 | query += ":profileURL, "; | ||
635 | query += ":profileWantToMask, "; | ||
636 | query += ":profileWantToText, "; | ||
637 | query += ":profileSkillsMask, "; | ||
638 | query += ":profileSkillsText, "; | ||
639 | query += ":profileLanguages, "; | ||
640 | query += ":profileImage, "; | ||
641 | query += ":profileAboutText, "; | ||
642 | query += ":profileFirstImage, "; | ||
643 | query += ":profileFirstText)"; | ||
644 | |||
645 | using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) | ||
646 | { | ||
647 | put.CommandText = query; | ||
648 | put.Parameters.AddWithValue(":userId", props.UserId.ToString()); | ||
649 | put.Parameters.AddWithValue(":profilePartner", props.PartnerId.ToString()); | ||
650 | put.Parameters.AddWithValue(":profileAllowPublish", props.PublishProfile); | ||
651 | put.Parameters.AddWithValue(":profileMaturePublish", props.PublishMature); | ||
652 | put.Parameters.AddWithValue(":profileURL", props.WebUrl); | ||
653 | put.Parameters.AddWithValue(":profileWantToMask", props.WantToMask); | ||
654 | put.Parameters.AddWithValue(":profileWantToText", props.WantToText); | ||
655 | put.Parameters.AddWithValue(":profileSkillsMask", props.SkillsMask); | ||
656 | put.Parameters.AddWithValue(":profileSkillsText", props.SkillsText); | ||
657 | put.Parameters.AddWithValue(":profileLanguages", props.Language); | ||
658 | put.Parameters.AddWithValue(":profileImage", props.ImageId.ToString()); | ||
659 | put.Parameters.AddWithValue(":profileAboutText", props.AboutText); | ||
660 | put.Parameters.AddWithValue(":profileFirstImage", props.FirstLifeImageId.ToString()); | ||
661 | put.Parameters.AddWithValue(":profileFirstText", props.FirstLifeText); | ||
662 | |||
663 | put.ExecuteNonQuery(); | ||
664 | } | ||
665 | } | ||
666 | } | ||
667 | return true; | ||
668 | } | ||
669 | |||
670 | public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) | ||
671 | { | ||
672 | string query = string.Empty; | ||
673 | |||
674 | query += "UPDATE userprofile SET "; | ||
675 | query += "profileURL=:profileURL, "; | ||
676 | query += "profileImage=:image, "; | ||
677 | query += "profileAboutText=:abouttext,"; | ||
678 | query += "profileFirstImage=:firstlifeimage,"; | ||
679 | query += "profileFirstText=:firstlifetext "; | ||
680 | query += "WHERE useruuid=:uuid"; | ||
681 | |||
682 | try | ||
683 | { | ||
684 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
685 | { | ||
686 | cmd.CommandText = query; | ||
687 | cmd.Parameters.AddWithValue(":profileURL", props.WebUrl); | ||
688 | cmd.Parameters.AddWithValue(":image", props.ImageId.ToString()); | ||
689 | cmd.Parameters.AddWithValue(":abouttext", props.AboutText); | ||
690 | cmd.Parameters.AddWithValue(":firstlifeimage", props.FirstLifeImageId.ToString()); | ||
691 | cmd.Parameters.AddWithValue(":firstlifetext", props.FirstLifeText); | ||
692 | cmd.Parameters.AddWithValue(":uuid", props.UserId.ToString()); | ||
693 | |||
694 | cmd.ExecuteNonQuery(); | ||
695 | } | ||
696 | } | ||
697 | catch (Exception e) | ||
698 | { | ||
699 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
700 | ": AgentPropertiesUpdate exception {0}", e.Message); | ||
701 | |||
702 | return false; | ||
703 | } | ||
704 | return true; | ||
705 | } | ||
706 | |||
707 | public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) | ||
708 | { | ||
709 | string query = string.Empty; | ||
710 | |||
711 | query += "UPDATE userprofile SET "; | ||
712 | query += "profileWantToMask=:WantMask, "; | ||
713 | query += "profileWantToText=:WantText,"; | ||
714 | query += "profileSkillsMask=:SkillsMask,"; | ||
715 | query += "profileSkillsText=:SkillsText, "; | ||
716 | query += "profileLanguages=:Languages "; | ||
717 | query += "WHERE useruuid=:uuid"; | ||
718 | |||
719 | try | ||
720 | { | ||
721 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
722 | { | ||
723 | cmd.CommandText = query; | ||
724 | cmd.Parameters.AddWithValue(":WantMask", up.WantToMask); | ||
725 | cmd.Parameters.AddWithValue(":WantText", up.WantToText); | ||
726 | cmd.Parameters.AddWithValue(":SkillsMask", up.SkillsMask); | ||
727 | cmd.Parameters.AddWithValue(":SkillsText", up.SkillsText); | ||
728 | cmd.Parameters.AddWithValue(":Languages", up.Language); | ||
729 | cmd.Parameters.AddWithValue(":uuid", up.UserId.ToString()); | ||
730 | |||
731 | cmd.ExecuteNonQuery(); | ||
732 | } | ||
733 | } | ||
734 | catch (Exception e) | ||
735 | { | ||
736 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
737 | ": AgentInterestsUpdate exception {0}", e.Message); | ||
738 | result = e.Message; | ||
739 | return false; | ||
740 | } | ||
741 | return true; | ||
742 | } | ||
743 | |||
744 | |||
745 | public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) | ||
746 | { | ||
747 | string query = string.Empty; | ||
748 | |||
749 | query += "UPDATE usersettings SET "; | ||
750 | query += "imviaemail=:ImViaEmail, "; | ||
751 | query += "visible=:Visible, "; | ||
752 | query += "email=:EMail "; | ||
753 | query += "WHERE useruuid=:uuid"; | ||
754 | |||
755 | try | ||
756 | { | ||
757 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
758 | { | ||
759 | cmd.CommandText = query; | ||
760 | cmd.Parameters.AddWithValue(":ImViaEmail", pref.IMViaEmail); | ||
761 | cmd.Parameters.AddWithValue(":Visible", pref.Visible); | ||
762 | cmd.Parameters.AddWithValue(":EMail", pref.EMail); | ||
763 | cmd.Parameters.AddWithValue(":uuid", pref.UserId.ToString()); | ||
764 | |||
765 | cmd.ExecuteNonQuery(); | ||
766 | } | ||
767 | } | ||
768 | catch (Exception e) | ||
769 | { | ||
770 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
771 | ": AgentInterestsUpdate exception {0}", e.Message); | ||
772 | result = e.Message; | ||
773 | return false; | ||
774 | } | ||
775 | return true; | ||
776 | } | ||
777 | |||
778 | public bool GetUserPreferences(ref UserPreferences pref, ref string result) | ||
779 | { | ||
780 | IDataReader reader = null; | ||
781 | string query = string.Empty; | ||
782 | |||
783 | query += "SELECT imviaemail,visible,email FROM "; | ||
784 | query += "usersettings WHERE "; | ||
785 | query += "useruuid = :Id"; | ||
786 | |||
787 | OSDArray data = new OSDArray(); | ||
788 | |||
789 | try | ||
790 | { | ||
791 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
792 | { | ||
793 | cmd.CommandText = query; | ||
794 | cmd.Parameters.AddWithValue("?Id", pref.UserId.ToString()); | ||
795 | |||
796 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
797 | { | ||
798 | if(reader.Read()) | ||
799 | { | ||
800 | bool.TryParse((string)reader["imviaemail"], out pref.IMViaEmail); | ||
801 | bool.TryParse((string)reader["visible"], out pref.Visible); | ||
802 | pref.EMail = (string)reader["email"]; | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | query = "INSERT INTO usersettings VALUES "; | ||
807 | query += "(:Id,'false','false', :Email)"; | ||
808 | |||
809 | using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) | ||
810 | { | ||
811 | put.Parameters.AddWithValue(":Id", pref.UserId.ToString()); | ||
812 | put.Parameters.AddWithValue(":Email", pref.EMail); | ||
813 | put.ExecuteNonQuery(); | ||
814 | |||
815 | } | ||
816 | } | ||
817 | } | ||
818 | } | ||
819 | } | ||
820 | catch (Exception e) | ||
821 | { | ||
822 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
823 | ": Get preferences exception {0}", e.Message); | ||
824 | result = e.Message; | ||
825 | return false; | ||
826 | } | ||
827 | return true; | ||
828 | } | ||
829 | |||
830 | public bool GetUserAppData(ref UserAppData props, ref string result) | ||
831 | { | ||
832 | IDataReader reader = null; | ||
833 | string query = string.Empty; | ||
834 | |||
835 | query += "SELECT * FROM `userdata` WHERE "; | ||
836 | query += "UserId = :Id AND "; | ||
837 | query += "TagId = :TagId"; | ||
838 | |||
839 | try | ||
840 | { | ||
841 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
842 | { | ||
843 | cmd.CommandText = query; | ||
844 | cmd.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
845 | cmd.Parameters.AddWithValue (":TagId", props.TagId.ToString()); | ||
846 | |||
847 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
848 | { | ||
849 | if(reader.Read()) | ||
850 | { | ||
851 | props.DataKey = (string)reader["DataKey"]; | ||
852 | props.DataVal = (string)reader["DataVal"]; | ||
853 | } | ||
854 | else | ||
855 | { | ||
856 | query += "INSERT INTO userdata VALUES ( "; | ||
857 | query += ":UserId,"; | ||
858 | query += ":TagId,"; | ||
859 | query += ":DataKey,"; | ||
860 | query += ":DataVal) "; | ||
861 | |||
862 | using (SqliteCommand put = (SqliteCommand)m_connection.CreateCommand()) | ||
863 | { | ||
864 | put.Parameters.AddWithValue(":Id", props.UserId.ToString()); | ||
865 | put.Parameters.AddWithValue(":TagId", props.TagId.ToString()); | ||
866 | put.Parameters.AddWithValue(":DataKey", props.DataKey.ToString()); | ||
867 | put.Parameters.AddWithValue(":DataVal", props.DataVal.ToString()); | ||
868 | |||
869 | put.ExecuteNonQuery(); | ||
870 | } | ||
871 | } | ||
872 | } | ||
873 | } | ||
874 | } | ||
875 | catch (Exception e) | ||
876 | { | ||
877 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
878 | ": Requst application data exception {0}", e.Message); | ||
879 | result = e.Message; | ||
880 | return false; | ||
881 | } | ||
882 | return true; | ||
883 | } | ||
884 | public bool SetUserAppData(UserAppData props, ref string result) | ||
885 | { | ||
886 | string query = string.Empty; | ||
887 | |||
888 | query += "UPDATE userdata SET "; | ||
889 | query += "TagId = :TagId, "; | ||
890 | query += "DataKey = :DataKey, "; | ||
891 | query += "DataVal = :DataVal WHERE "; | ||
892 | query += "UserId = :UserId AND "; | ||
893 | query += "TagId = :TagId"; | ||
894 | |||
895 | try | ||
896 | { | ||
897 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
898 | { | ||
899 | cmd.CommandText = query; | ||
900 | cmd.Parameters.AddWithValue(":UserId", props.UserId.ToString()); | ||
901 | cmd.Parameters.AddWithValue(":TagId", props.TagId.ToString ()); | ||
902 | cmd.Parameters.AddWithValue(":DataKey", props.DataKey.ToString ()); | ||
903 | cmd.Parameters.AddWithValue(":DataVal", props.DataKey.ToString ()); | ||
904 | |||
905 | cmd.ExecuteNonQuery(); | ||
906 | } | ||
907 | } | ||
908 | catch (Exception e) | ||
909 | { | ||
910 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
911 | ": SetUserData exception {0}", e.Message); | ||
912 | return false; | ||
913 | } | ||
914 | return true; | ||
915 | } | ||
916 | public OSDArray GetUserImageAssets(UUID avatarId) | ||
917 | { | ||
918 | IDataReader reader = null; | ||
919 | OSDArray data = new OSDArray(); | ||
920 | string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = :Id"; | ||
921 | |||
922 | // Get classified image assets | ||
923 | |||
924 | |||
925 | try | ||
926 | { | ||
927 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
928 | { | ||
929 | cmd.CommandText = query; | ||
930 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
931 | |||
932 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
933 | { | ||
934 | while(reader.Read()) | ||
935 | { | ||
936 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString())); | ||
937 | } | ||
938 | } | ||
939 | } | ||
940 | |||
941 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
942 | { | ||
943 | cmd.CommandText = query; | ||
944 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
945 | |||
946 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
947 | { | ||
948 | if(reader.Read()) | ||
949 | { | ||
950 | data.Add(new OSDString((string)reader["snapshotuuid"].ToString ())); | ||
951 | } | ||
952 | } | ||
953 | } | ||
954 | |||
955 | query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = :Id"; | ||
956 | |||
957 | using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) | ||
958 | { | ||
959 | cmd.CommandText = query; | ||
960 | cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); | ||
961 | |||
962 | using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) | ||
963 | { | ||
964 | if(reader.Read()) | ||
965 | { | ||
966 | data.Add(new OSDString((string)reader["profileImage"].ToString ())); | ||
967 | data.Add(new OSDString((string)reader["profileFirstImage"].ToString ())); | ||
968 | } | ||
969 | } | ||
970 | } | ||
971 | } | ||
972 | catch (Exception e) | ||
973 | { | ||
974 | m_log.ErrorFormat("[PROFILES_DATA]" + | ||
975 | ": GetAvatarNotes exception {0}", e.Message); | ||
976 | } | ||
977 | return data; | ||
978 | } | ||
979 | #endregion | ||
980 | } | ||
981 | } | ||
982 | |||
diff --git a/OpenSim/Data/SQLite/SQLiteUtils.cs b/OpenSim/Data/SQLite/SQLiteUtils.cs new file mode 100644 index 0000000..1218ebb --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteUtils.cs | |||
@@ -0,0 +1,311 @@ | |||
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.Data; | ||
30 | #if CSharpSqlite | ||
31 | using Community.CsharpSqlite.Sqlite; | ||
32 | #else | ||
33 | using Mono.Data.Sqlite; | ||
34 | #endif | ||
35 | |||
36 | namespace OpenSim.Data.SQLite | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// A base class for methods needed by all SQLite database classes | ||
40 | /// </summary> | ||
41 | public class SQLiteUtil | ||
42 | { | ||
43 | /*********************************************************************** | ||
44 | * | ||
45 | * Database Definition Helper Functions | ||
46 | * | ||
47 | * This should be db agnostic as we define them in ADO.NET terms | ||
48 | * | ||
49 | **********************************************************************/ | ||
50 | |||
51 | /// <summary> | ||
52 | /// | ||
53 | /// </summary> | ||
54 | /// <param name="dt"></param> | ||
55 | /// <param name="name"></param> | ||
56 | /// <param name="type"></param> | ||
57 | public static void createCol(DataTable dt, string name, Type type) | ||
58 | { | ||
59 | DataColumn col = new DataColumn(name, type); | ||
60 | dt.Columns.Add(col); | ||
61 | } | ||
62 | |||
63 | /*********************************************************************** | ||
64 | * | ||
65 | * SQL Statement Creation Functions | ||
66 | * | ||
67 | * These functions create SQL statements for update, insert, and create. | ||
68 | * They can probably be factored later to have a db independant | ||
69 | * portion and a db specific portion | ||
70 | * | ||
71 | **********************************************************************/ | ||
72 | |||
73 | /// <summary> | ||
74 | /// Create an insert command | ||
75 | /// </summary> | ||
76 | /// <param name="table">table name</param> | ||
77 | /// <param name="dt">data table</param> | ||
78 | /// <returns>the created command</returns> | ||
79 | /// <remarks> | ||
80 | /// This is subtle enough to deserve some commentary. | ||
81 | /// Instead of doing *lots* and *lots of hardcoded strings | ||
82 | /// for database definitions we'll use the fact that | ||
83 | /// realistically all insert statements look like "insert | ||
84 | /// into A(b, c) values(:b, :c) on the parameterized query | ||
85 | /// front. If we just have a list of b, c, etc... we can | ||
86 | /// generate these strings instead of typing them out. | ||
87 | /// </remarks> | ||
88 | public static SqliteCommand createInsertCommand(string table, DataTable dt) | ||
89 | { | ||
90 | |||
91 | string[] cols = new string[dt.Columns.Count]; | ||
92 | for (int i = 0; i < dt.Columns.Count; i++) | ||
93 | { | ||
94 | DataColumn col = dt.Columns[i]; | ||
95 | cols[i] = col.ColumnName; | ||
96 | } | ||
97 | |||
98 | string sql = "insert into " + table + "("; | ||
99 | sql += String.Join(", ", cols); | ||
100 | // important, the first ':' needs to be here, the rest get added in the join | ||
101 | sql += ") values (:"; | ||
102 | sql += String.Join(", :", cols); | ||
103 | sql += ")"; | ||
104 | SqliteCommand cmd = new SqliteCommand(sql); | ||
105 | |||
106 | // this provides the binding for all our parameters, so | ||
107 | // much less code than it used to be | ||
108 | foreach (DataColumn col in dt.Columns) | ||
109 | { | ||
110 | cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); | ||
111 | } | ||
112 | return cmd; | ||
113 | } | ||
114 | |||
115 | /// <summary> | ||
116 | /// create an update command | ||
117 | /// </summary> | ||
118 | /// <param name="table">table name</param> | ||
119 | /// <param name="pk"></param> | ||
120 | /// <param name="dt"></param> | ||
121 | /// <returns>the created command</returns> | ||
122 | public static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt) | ||
123 | { | ||
124 | string sql = "update " + table + " set "; | ||
125 | string subsql = String.Empty; | ||
126 | foreach (DataColumn col in dt.Columns) | ||
127 | { | ||
128 | if (subsql.Length > 0) | ||
129 | { | ||
130 | // a map function would rock so much here | ||
131 | subsql += ", "; | ||
132 | } | ||
133 | subsql += col.ColumnName + "= :" + col.ColumnName; | ||
134 | } | ||
135 | sql += subsql; | ||
136 | sql += " where " + pk; | ||
137 | SqliteCommand cmd = new SqliteCommand(sql); | ||
138 | |||
139 | // this provides the binding for all our parameters, so | ||
140 | // much less code than it used to be | ||
141 | |||
142 | foreach (DataColumn col in dt.Columns) | ||
143 | { | ||
144 | cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType)); | ||
145 | } | ||
146 | return cmd; | ||
147 | } | ||
148 | |||
149 | /// <summary> | ||
150 | /// | ||
151 | /// </summary> | ||
152 | /// <param name="dt">Data Table</param> | ||
153 | /// <returns></returns> | ||
154 | public static string defineTable(DataTable dt) | ||
155 | { | ||
156 | string sql = "create table " + dt.TableName + "("; | ||
157 | string subsql = String.Empty; | ||
158 | foreach (DataColumn col in dt.Columns) | ||
159 | { | ||
160 | if (subsql.Length > 0) | ||
161 | { | ||
162 | // a map function would rock so much here | ||
163 | subsql += ",\n"; | ||
164 | } | ||
165 | subsql += col.ColumnName + " " + sqliteType(col.DataType); | ||
166 | if (dt.PrimaryKey.Length > 0) | ||
167 | { | ||
168 | if (col == dt.PrimaryKey[0]) | ||
169 | { | ||
170 | subsql += " primary key"; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | sql += subsql; | ||
175 | sql += ")"; | ||
176 | return sql; | ||
177 | } | ||
178 | |||
179 | /*********************************************************************** | ||
180 | * | ||
181 | * Database Binding functions | ||
182 | * | ||
183 | * These will be db specific due to typing, and minor differences | ||
184 | * in databases. | ||
185 | * | ||
186 | **********************************************************************/ | ||
187 | |||
188 | ///<summary> | ||
189 | /// <para> | ||
190 | /// This is a convenience function that collapses 5 repetitive | ||
191 | /// lines for defining SqliteParameters to 2 parameters: | ||
192 | /// column name and database type. | ||
193 | /// </para> | ||
194 | /// | ||
195 | /// <para> | ||
196 | /// It assumes certain conventions like :param as the param | ||
197 | /// name to replace in parametrized queries, and that source | ||
198 | /// version is always current version, both of which are fine | ||
199 | /// for us. | ||
200 | /// </para> | ||
201 | ///</summary> | ||
202 | /// <param name="name"></param> | ||
203 | /// <param name="type"></param> | ||
204 | ///<returns>a built sqlite parameter</returns> | ||
205 | public static SqliteParameter createSqliteParameter(string name, Type type) | ||
206 | { | ||
207 | SqliteParameter param = new SqliteParameter(); | ||
208 | param.ParameterName = ":" + name; | ||
209 | param.DbType = dbtypeFromType(type); | ||
210 | param.SourceColumn = name; | ||
211 | param.SourceVersion = DataRowVersion.Current; | ||
212 | return param; | ||
213 | } | ||
214 | |||
215 | /*********************************************************************** | ||
216 | * | ||
217 | * Type conversion functions | ||
218 | * | ||
219 | **********************************************************************/ | ||
220 | |||
221 | /// <summary> | ||
222 | /// Type conversion function | ||
223 | /// </summary> | ||
224 | /// <param name="type">a type</param> | ||
225 | /// <returns>a DbType</returns> | ||
226 | public static DbType dbtypeFromType(Type type) | ||
227 | { | ||
228 | if (type == typeof (String)) | ||
229 | { | ||
230 | return DbType.String; | ||
231 | } | ||
232 | else if (type == typeof (Int32)) | ||
233 | { | ||
234 | return DbType.Int32; | ||
235 | } | ||
236 | else if (type == typeof (UInt32)) | ||
237 | { | ||
238 | return DbType.UInt32; | ||
239 | } | ||
240 | else if (type == typeof (Int64)) | ||
241 | { | ||
242 | return DbType.Int64; | ||
243 | } | ||
244 | else if (type == typeof (UInt64)) | ||
245 | { | ||
246 | return DbType.UInt64; | ||
247 | } | ||
248 | else if (type == typeof (Double)) | ||
249 | { | ||
250 | return DbType.Double; | ||
251 | } | ||
252 | else if (type == typeof (Boolean)) | ||
253 | { | ||
254 | return DbType.Boolean; | ||
255 | } | ||
256 | else if (type == typeof (Byte[])) | ||
257 | { | ||
258 | return DbType.Binary; | ||
259 | } | ||
260 | else | ||
261 | { | ||
262 | return DbType.String; | ||
263 | } | ||
264 | } | ||
265 | |||
266 | /// <summary> | ||
267 | /// </summary> | ||
268 | /// <param name="type">a Type</param> | ||
269 | /// <returns>a string</returns> | ||
270 | /// <remarks>this is something we'll need to implement for each db slightly differently.</remarks> | ||
271 | public static string sqliteType(Type type) | ||
272 | { | ||
273 | if (type == typeof (String)) | ||
274 | { | ||
275 | return "varchar(255)"; | ||
276 | } | ||
277 | else if (type == typeof (Int32)) | ||
278 | { | ||
279 | return "integer"; | ||
280 | } | ||
281 | else if (type == typeof (UInt32)) | ||
282 | { | ||
283 | return "integer"; | ||
284 | } | ||
285 | else if (type == typeof (Int64)) | ||
286 | { | ||
287 | return "varchar(255)"; | ||
288 | } | ||
289 | else if (type == typeof (UInt64)) | ||
290 | { | ||
291 | return "varchar(255)"; | ||
292 | } | ||
293 | else if (type == typeof (Double)) | ||
294 | { | ||
295 | return "float"; | ||
296 | } | ||
297 | else if (type == typeof (Boolean)) | ||
298 | { | ||
299 | return "integer"; | ||
300 | } | ||
301 | else if (type == typeof (Byte[])) | ||
302 | { | ||
303 | return "blob"; | ||
304 | } | ||
305 | else | ||
306 | { | ||
307 | return "string"; | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | } | ||
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs new file mode 100644 index 0000000..4ef1f30 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs | |||
@@ -0,0 +1,318 @@ | |||
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.Data; | ||
30 | using System.Reflection; | ||
31 | using System.Collections.Generic; | ||
32 | #if CSharpSqlite | ||
33 | using Community.CsharpSqlite.Sqlite; | ||
34 | #else | ||
35 | using Mono.Data.Sqlite; | ||
36 | #endif | ||
37 | using log4net; | ||
38 | using OpenMetaverse; | ||
39 | using OpenSim.Framework; | ||
40 | |||
41 | namespace OpenSim.Data.SQLite | ||
42 | { | ||
43 | /// <summary> | ||
44 | /// A SQLite Interface for the Asset Server | ||
45 | /// </summary> | ||
46 | public class SQLiteXInventoryData : IXInventoryData | ||
47 | { | ||
48 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private SqliteFolderHandler m_Folders; | ||
51 | private SqliteItemHandler m_Items; | ||
52 | |||
53 | public SQLiteXInventoryData(string conn, string realm) | ||
54 | { | ||
55 | if (Util.IsWindows()) | ||
56 | Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||
57 | |||
58 | m_Folders = new SqliteFolderHandler( | ||
59 | conn, "inventoryfolders", "XInventoryStore"); | ||
60 | m_Items = new SqliteItemHandler( | ||
61 | conn, "inventoryitems", String.Empty); | ||
62 | } | ||
63 | |||
64 | public XInventoryFolder[] GetFolders(string[] fields, string[] vals) | ||
65 | { | ||
66 | return m_Folders.Get(fields, vals); | ||
67 | } | ||
68 | |||
69 | public XInventoryItem[] GetItems(string[] fields, string[] vals) | ||
70 | { | ||
71 | return m_Items.Get(fields, vals); | ||
72 | } | ||
73 | |||
74 | public bool StoreFolder(XInventoryFolder folder) | ||
75 | { | ||
76 | if (folder.folderName.Length > 64) | ||
77 | folder.folderName = folder.folderName.Substring(0, 64); | ||
78 | |||
79 | return m_Folders.Store(folder); | ||
80 | } | ||
81 | |||
82 | public bool StoreItem(XInventoryItem item) | ||
83 | { | ||
84 | if (item.inventoryName.Length > 64) | ||
85 | item.inventoryName = item.inventoryName.Substring(0, 64); | ||
86 | if (item.inventoryDescription.Length > 128) | ||
87 | item.inventoryDescription = item.inventoryDescription.Substring(0, 128); | ||
88 | |||
89 | return m_Items.Store(item); | ||
90 | } | ||
91 | |||
92 | public bool DeleteFolders(string field, string val) | ||
93 | { | ||
94 | return m_Folders.Delete(field, val); | ||
95 | } | ||
96 | |||
97 | public bool DeleteFolders(string[] fields, string[] vals) | ||
98 | { | ||
99 | return m_Folders.Delete(fields, vals); | ||
100 | } | ||
101 | |||
102 | public bool DeleteItems(string field, string val) | ||
103 | { | ||
104 | return m_Items.Delete(field, val); | ||
105 | } | ||
106 | |||
107 | public bool DeleteItems(string[] fields, string[] vals) | ||
108 | { | ||
109 | return m_Items.Delete(fields, vals); | ||
110 | } | ||
111 | |||
112 | public bool MoveItem(string id, string newParent) | ||
113 | { | ||
114 | return m_Items.MoveItem(id, newParent); | ||
115 | } | ||
116 | |||
117 | public bool MoveFolder(string id, string newParent) | ||
118 | { | ||
119 | return m_Folders.MoveFolder(id, newParent); | ||
120 | } | ||
121 | |||
122 | public XInventoryItem[] GetActiveGestures(UUID principalID) | ||
123 | { | ||
124 | return m_Items.GetActiveGestures(principalID); | ||
125 | } | ||
126 | |||
127 | public int GetAssetPermissions(UUID principalID, UUID assetID) | ||
128 | { | ||
129 | return m_Items.GetAssetPermissions(principalID, assetID); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | public class SqliteItemHandler : SqliteInventoryHandler<XInventoryItem> | ||
134 | { | ||
135 | public SqliteItemHandler(string c, string t, string m) : | ||
136 | base(c, t, m) | ||
137 | { | ||
138 | } | ||
139 | |||
140 | public override bool Store(XInventoryItem item) | ||
141 | { | ||
142 | if (!base.Store(item)) | ||
143 | return false; | ||
144 | |||
145 | IncrementFolderVersion(item.parentFolderID); | ||
146 | |||
147 | return true; | ||
148 | } | ||
149 | |||
150 | public override bool Delete(string field, string val) | ||
151 | { | ||
152 | XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val }); | ||
153 | if (retrievedItems.Length == 0) | ||
154 | return false; | ||
155 | |||
156 | if (!base.Delete(field, val)) | ||
157 | return false; | ||
158 | |||
159 | // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[]) | ||
160 | // IncrementFolderVersion(retrievedItems[0].parentFolderID); | ||
161 | |||
162 | return true; | ||
163 | } | ||
164 | |||
165 | public override bool Delete(string[] fields, string[] vals) | ||
166 | { | ||
167 | XInventoryItem[] retrievedItems = Get(fields, vals); | ||
168 | if (retrievedItems.Length == 0) | ||
169 | return false; | ||
170 | |||
171 | if (!base.Delete(fields, vals)) | ||
172 | return false; | ||
173 | |||
174 | HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>(); | ||
175 | |||
176 | Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID)); | ||
177 | |||
178 | foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs) | ||
179 | IncrementFolderVersion(deletedItemFolderUUID); | ||
180 | |||
181 | return true; | ||
182 | } | ||
183 | |||
184 | public bool MoveItem(string id, string newParent) | ||
185 | { | ||
186 | XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id }); | ||
187 | if (retrievedItems.Length == 0) | ||
188 | return false; | ||
189 | |||
190 | UUID oldParent = retrievedItems[0].parentFolderID; | ||
191 | |||
192 | using (SqliteCommand cmd = new SqliteCommand()) | ||
193 | { | ||
194 | cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm); | ||
195 | cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent)); | ||
196 | cmd.Parameters.Add(new SqliteParameter(":InventoryID", id)); | ||
197 | |||
198 | if (ExecuteNonQuery(cmd, m_Connection) == 0) | ||
199 | return false; | ||
200 | } | ||
201 | |||
202 | IncrementFolderVersion(oldParent); | ||
203 | IncrementFolderVersion(newParent); | ||
204 | |||
205 | return true; | ||
206 | } | ||
207 | |||
208 | public XInventoryItem[] GetActiveGestures(UUID principalID) | ||
209 | { | ||
210 | using (SqliteCommand cmd = new SqliteCommand()) | ||
211 | { | ||
212 | cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm); | ||
213 | |||
214 | cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString())); | ||
215 | cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture)); | ||
216 | |||
217 | return DoQuery(cmd); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | public int GetAssetPermissions(UUID principalID, UUID assetID) | ||
222 | { | ||
223 | IDataReader reader; | ||
224 | |||
225 | using (SqliteCommand cmd = new SqliteCommand()) | ||
226 | { | ||
227 | cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm); | ||
228 | cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString())); | ||
229 | cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString())); | ||
230 | |||
231 | reader = ExecuteReader(cmd, m_Connection); | ||
232 | } | ||
233 | |||
234 | int perms = 0; | ||
235 | |||
236 | while (reader.Read()) | ||
237 | { | ||
238 | perms |= Convert.ToInt32(reader["inventoryCurrentPermissions"]); | ||
239 | } | ||
240 | |||
241 | reader.Close(); | ||
242 | //CloseCommand(cmd); | ||
243 | |||
244 | return perms; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | public class SqliteFolderHandler : SqliteInventoryHandler<XInventoryFolder> | ||
249 | { | ||
250 | public SqliteFolderHandler(string c, string t, string m) : | ||
251 | base(c, t, m) | ||
252 | { | ||
253 | } | ||
254 | |||
255 | public override bool Store(XInventoryFolder folder) | ||
256 | { | ||
257 | if (!base.Store(folder)) | ||
258 | return false; | ||
259 | |||
260 | IncrementFolderVersion(folder.parentFolderID); | ||
261 | |||
262 | return true; | ||
263 | } | ||
264 | |||
265 | public bool MoveFolder(string id, string newParentFolderID) | ||
266 | { | ||
267 | XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id }); | ||
268 | |||
269 | if (folders.Length == 0) | ||
270 | return false; | ||
271 | |||
272 | UUID oldParentFolderUUID = folders[0].parentFolderID; | ||
273 | |||
274 | using (SqliteCommand cmd = new SqliteCommand()) | ||
275 | { | ||
276 | cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm); | ||
277 | cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID)); | ||
278 | cmd.Parameters.Add(new SqliteParameter(":FolderID", id)); | ||
279 | |||
280 | if (ExecuteNonQuery(cmd, m_Connection) == 0) | ||
281 | return false; | ||
282 | } | ||
283 | |||
284 | IncrementFolderVersion(oldParentFolderUUID); | ||
285 | IncrementFolderVersion(newParentFolderID); | ||
286 | |||
287 | return true; | ||
288 | } | ||
289 | |||
290 | } | ||
291 | |||
292 | public class SqliteInventoryHandler<T> : SQLiteGenericTableHandler<T> where T: class, new() | ||
293 | { | ||
294 | public SqliteInventoryHandler(string c, string t, string m) : base(c, t, m) {} | ||
295 | |||
296 | protected bool IncrementFolderVersion(UUID folderID) | ||
297 | { | ||
298 | return IncrementFolderVersion(folderID.ToString()); | ||
299 | } | ||
300 | |||
301 | protected bool IncrementFolderVersion(string folderID) | ||
302 | { | ||
303 | // m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID); | ||
304 | // Util.PrintCallStack(); | ||
305 | |||
306 | using (SqliteCommand cmd = new SqliteCommand()) | ||
307 | { | ||
308 | cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID"; | ||
309 | cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); | ||
310 | |||
311 | if(ExecuteNonQuery(cmd, m_Connection) == 0) | ||
312 | return false; | ||
313 | } | ||
314 | |||
315 | return true; | ||
316 | } | ||
317 | } | ||
318 | } \ No newline at end of file | ||