diff --git a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..d45ab5092a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly : AssemblyTitle("OpenSim.Data.SQLite")]
+[assembly : AssemblyDescription("")]
+[assembly : AssemblyConfiguration("")]
+[assembly : AssemblyCompany("http://opensimulator.org")]
+[assembly : AssemblyProduct("OpenSim.Data.SQLite")]
+[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
+[assembly : AssemblyTrademark("")]
+[assembly : AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly : ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly : Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly : AssemblyVersion("0.6.5.*")]
+[assembly : AssemblyFileVersion("0.6.5.0")]
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
new file mode 100644
index 0000000000..2e026cad19
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql
@@ -0,0 +1,12 @@
+BEGIN TRANSACTION;
+CREATE TABLE assets(
+ UUID varchar(255) primary key,
+ Name varchar(255),
+ Description varchar(255),
+ Type integer,
+ InvType integer,
+ Local integer,
+ Temporary integer,
+ Data blob);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
new file mode 100644
index 0000000000..468567dcc2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql
@@ -0,0 +1,18 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE auth (
+ UUID char(36) NOT NULL,
+ passwordHash char(32) NOT NULL default '',
+ passwordSalt char(32) NOT NULL default '',
+ webLoginKey varchar(255) NOT NULL default '',
+ accountType VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
+ PRIMARY KEY (`UUID`)
+);
+
+CREATE TABLE tokens (
+ UUID char(36) NOT NULL,
+ token varchar(255) NOT NULL,
+ validity datetime NOT NULL
+);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
new file mode 100644
index 0000000000..7ec906b48a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql
@@ -0,0 +1,9 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE Avatars (
+ PrincipalID CHAR(36) NOT NULL,
+ Name VARCHAR(32) NOT NULL,
+ Value VARCHAR(255) NOT NULL DEFAULT '',
+ PRIMARY KEY(PrincipalID, Name));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
new file mode 100644
index 0000000000..f1b9ab9902
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE `Friends` (
+ `PrincipalID` CHAR(36) NOT NULL,
+ `Friend` VARCHAR(255) NOT NULL,
+ `Flags` VARCHAR(16) NOT NULL DEFAULT 0,
+ `Offered` VARCHAR(32) NOT NULL DEFAULT 0,
+ PRIMARY KEY(`PrincipalID`, `Friend`));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
new file mode 100644
index 0000000000..554d5c2ec8
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql
@@ -0,0 +1,32 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE inventoryfolders(
+ UUID varchar(255) primary key,
+ name varchar(255),
+ agentID varchar(255),
+ parentID varchar(255),
+ type integer,
+ version integer);
+
+CREATE TABLE inventoryitems(
+ UUID varchar(255) primary key,
+ assetID varchar(255),
+ assetType integer,
+ invType integer,
+ parentFolderID varchar(255),
+ avatarID varchar(255),
+ creatorsID varchar(255),
+ inventoryName varchar(255),
+ inventoryDescription varchar(255),
+ inventoryNextPermissions integer,
+ inventoryCurrentPermissions integer,
+ inventoryBasePermissions integer,
+ inventoryEveryOnePermissions integer,
+ salePrice integer default 99,
+ saleType integer default 0,
+ creationDate integer default 2000,
+ groupID varchar(255) default '00000000-0000-0000-0000-000000000000',
+ groupOwned integer default 0,
+ flags integer default 0);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
new file mode 100644
index 0000000000..39e8180cdc
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql
@@ -0,0 +1,144 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE prims(
+ UUID varchar(255) primary key,
+ RegionUUID varchar(255),
+ ParentID integer,
+ CreationDate integer,
+ Name varchar(255),
+ SceneGroupID varchar(255),
+ Text varchar(255),
+ Description varchar(255),
+ SitName varchar(255),
+ TouchName varchar(255),
+ CreatorID varchar(255),
+ OwnerID varchar(255),
+ GroupID varchar(255),
+ LastOwnerID varchar(255),
+ OwnerMask integer,
+ NextOwnerMask integer,
+ GroupMask integer,
+ EveryoneMask integer,
+ BaseMask integer,
+ PositionX float,
+ PositionY float,
+ PositionZ float,
+ GroupPositionX float,
+ GroupPositionY float,
+ GroupPositionZ float,
+ VelocityX float,
+ VelocityY float,
+ VelocityZ float,
+ AngularVelocityX float,
+ AngularVelocityY float,
+ AngularVelocityZ float,
+ AccelerationX float,
+ AccelerationY float,
+ AccelerationZ float,
+ RotationX float,
+ RotationY float,
+ RotationZ float,
+ RotationW float,
+ ObjectFlags integer,
+ SitTargetOffsetX float NOT NULL default 0,
+ SitTargetOffsetY float NOT NULL default 0,
+ SitTargetOffsetZ float NOT NULL default 0,
+ SitTargetOrientW float NOT NULL default 0,
+ SitTargetOrientX float NOT NULL default 0,
+ SitTargetOrientY float NOT NULL default 0,
+ SitTargetOrientZ float NOT NULL default 0);
+
+CREATE TABLE primshapes(
+ UUID varchar(255) primary key,
+ Shape integer,
+ ScaleX float,
+ ScaleY float,
+ ScaleZ float,
+ PCode integer,
+ PathBegin integer,
+ PathEnd integer,
+ PathScaleX integer,
+ PathScaleY integer,
+ PathShearX integer,
+ PathShearY integer,
+ PathSkew integer,
+ PathCurve integer,
+ PathRadiusOffset integer,
+ PathRevolutions integer,
+ PathTaperX integer,
+ PathTaperY integer,
+ PathTwist integer,
+ PathTwistBegin integer,
+ ProfileBegin integer,
+ ProfileEnd integer,
+ ProfileCurve integer,
+ ProfileHollow integer,
+ Texture blob,
+ ExtraParams blob,
+ State Integer NOT NULL default 0);
+
+CREATE TABLE primitems(
+ itemID varchar(255) primary key,
+ primID varchar(255),
+ assetID varchar(255),
+ parentFolderID varchar(255),
+ invType integer,
+ assetType integer,
+ name varchar(255),
+ description varchar(255),
+ creationDate integer,
+ creatorID varchar(255),
+ ownerID varchar(255),
+ lastOwnerID varchar(255),
+ groupID varchar(255),
+ nextPermissions string,
+ currentPermissions string,
+ basePermissions string,
+ everyonePermissions string,
+ groupPermissions string);
+
+CREATE TABLE terrain(
+ RegionUUID varchar(255),
+ Revision integer,
+ Heightfield blob);
+
+CREATE TABLE land(
+ UUID varchar(255) primary key,
+ RegionUUID varchar(255),
+ LocalLandID string,
+ Bitmap blob,
+ Name varchar(255),
+ Desc varchar(255),
+ OwnerUUID varchar(255),
+ IsGroupOwned string,
+ Area integer,
+ AuctionID integer,
+ Category integer,
+ ClaimDate integer,
+ ClaimPrice integer,
+ GroupUUID varchar(255),
+ SalePrice integer,
+ LandStatus integer,
+ LandFlags string,
+ LandingType string,
+ MediaAutoScale string,
+ MediaTextureUUID varchar(255),
+ MediaURL varchar(255),
+ MusicURL varchar(255),
+ PassHours float,
+ PassPrice string,
+ SnapshotUUID varchar(255),
+ UserLocationX float,
+ UserLocationY float,
+ UserLocationZ float,
+ UserLookAtX float,
+ UserLookAtY float,
+ UserLookAtZ float,
+ AuthbuyerID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000');
+
+CREATE TABLE landaccesslist(
+ LandUUID varchar(255),
+ AccessUUID varchar(255),
+ Flags string);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
new file mode 100644
index 0000000000..c38d9a762f
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql
@@ -0,0 +1,17 @@
+BEGIN TRANSACTION;
+
+-- useraccounts table
+CREATE TABLE UserAccounts (
+ PrincipalID CHAR(36) primary key,
+ ScopeID CHAR(36) NOT NULL,
+ FirstName VARCHAR(64) NOT NULL,
+ LastName VARCHAR(64) NOT NULL,
+ Email VARCHAR(64),
+ ServiceURLs TEXT,
+ Created INT(11),
+ UserLevel integer NOT NULL DEFAULT 0,
+ UserFlags integer NOT NULL DEFAULT 0,
+ UserTitle varchar(64) NOT NULL DEFAULT ''
+);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
new file mode 100644
index 0000000000..b584594ced
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql
@@ -0,0 +1,39 @@
+BEGIN TRANSACTION;
+
+-- users table
+CREATE TABLE users(
+ UUID varchar(255) primary key,
+ username varchar(255),
+ surname varchar(255),
+ passwordHash varchar(255),
+ passwordSalt varchar(255),
+ homeRegionX integer,
+ homeRegionY integer,
+ homeLocationX float,
+ homeLocationY float,
+ homeLocationZ float,
+ homeLookAtX float,
+ homeLookAtY float,
+ homeLookAtZ float,
+ created integer,
+ lastLogin integer,
+ rootInventoryFolderID varchar(255),
+ userInventoryURI varchar(255),
+ userAssetURI varchar(255),
+ profileCanDoMask integer,
+ profileWantDoMask integer,
+ profileAboutText varchar(255),
+ profileFirstText varchar(255),
+ profileImage varchar(255),
+ profileFirstImage varchar(255),
+ webLoginKey text default '00000000-0000-0000-0000-000000000000');
+-- friends table
+CREATE TABLE userfriends(
+ ownerID varchar(255),
+ friendID varchar(255),
+ friendPerms integer,
+ ownerPerms integer,
+ datetimestamp integer);
+
+COMMIT;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
new file mode 100644
index 0000000000..5339b84dfd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TEMPORARY TABLE assets_backup(UUID,Name,Description,Type,Local,Temporary,Data);
+INSERT INTO assets_backup SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets;
+DROP TABLE assets;
+CREATE TABLE assets(UUID,Name,Description,Type,Local,Temporary,Data);
+INSERT INTO assets SELECT UUID,Name,Description,Type,Local,Temporary,Data FROM assets_backup;
+DROP TABLE assets_backup;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
new file mode 100644
index 0000000000..3237b68fd6
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey) SELECT `UUID` AS UUID, `passwordHash` AS passwordHash, `passwordSalt` AS passwordSalt, `webLoginKey` AS webLoginKey FROM users;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
new file mode 100644
index 0000000000..6733502224
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
new file mode 100644
index 0000000000..01951d6582
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql
@@ -0,0 +1,8 @@
+BEGIN TRANSACTION;
+
+create index inventoryfolders_agentid on inventoryfolders(agentid);
+create index inventoryfolders_parentid on inventoryfolders(parentid);
+create index inventoryitems_parentfolderid on inventoryitems(parentfolderid);
+create index inventoryitems_avatarid on inventoryitems(avatarid);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
new file mode 100644
index 0000000000..c5c7c99455
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql
@@ -0,0 +1,10 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE regionban(
+ regionUUID varchar (255),
+ bannedUUID varchar (255),
+ bannedIp varchar (255),
+ bannedIpHostMask varchar (255)
+ );
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
new file mode 100644
index 0000000000..c7a62932ac
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+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;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
new file mode 100644
index 0000000000..48fc680b33
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE users add homeRegionID varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
new file mode 100644
index 0000000000..f54f8d98a2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql
@@ -0,0 +1 @@
+DELETE FROM assets WHERE UUID = 'dc4b9f0bd00845c696a401dd947ac621'
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
new file mode 100644
index 0000000000..4c6da91aab
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+alter table inventoryitems add column inventoryGroupPermissions integer unsigned not null default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
new file mode 100644
index 0000000000..4db2f7587d
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE primitems add flags integer not null default 0;
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
new file mode 100644
index 0000000000..6f890eeec1
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE users add userFlags integer NOT NULL default 0;
+ALTER TABLE users add godLevel integer NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
new file mode 100644
index 0000000000..39421c4434
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql
@@ -0,0 +1,7 @@
+BEGIN;
+
+update assets
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
new file mode 100644
index 0000000000..e8f4d46333
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql
@@ -0,0 +1,36 @@
+BEGIN;
+
+update inventoryitems
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+update inventoryitems
+ set assetID = substr(assetID, 1, 8) || "-" || substr(assetID, 9, 4) || "-" || substr(assetID, 13, 4) || "-" || substr(assetID, 17, 4) || "-" || substr(assetID, 21, 12)
+ where assetID not like '%-%';
+
+update inventoryitems
+ set parentFolderID = substr(parentFolderID, 1, 8) || "-" || substr(parentFolderID, 9, 4) || "-" || substr(parentFolderID, 13, 4) || "-" || substr(parentFolderID, 17, 4) || "-" || substr(parentFolderID, 21, 12)
+ where parentFolderID not like '%-%';
+
+update inventoryitems
+ set avatarID = substr(avatarID, 1, 8) || "-" || substr(avatarID, 9, 4) || "-" || substr(avatarID, 13, 4) || "-" || substr(avatarID, 17, 4) || "-" || substr(avatarID, 21, 12)
+ where avatarID not like '%-%';
+
+update inventoryitems
+ set creatorsID = substr(creatorsID, 1, 8) || "-" || substr(creatorsID, 9, 4) || "-" || substr(creatorsID, 13, 4) || "-" || substr(creatorsID, 17, 4) || "-" || substr(creatorsID, 21, 12)
+ where creatorsID not like '%-%';
+
+
+update inventoryfolders
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+update inventoryfolders
+ set agentID = substr(agentID, 1, 8) || "-" || substr(agentID, 9, 4) || "-" || substr(agentID, 13, 4) || "-" || substr(agentID, 17, 4) || "-" || substr(agentID, 21, 12)
+ where agentID not like '%-%';
+
+update inventoryfolders
+ set parentID = substr(parentID, 1, 8) || "-" || substr(parentID, 9, 4) || "-" || substr(parentID, 13, 4) || "-" || substr(parentID, 17, 4) || "-" || substr(parentID, 21, 12)
+ where parentID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
new file mode 100644
index 0000000000..de328cb47a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql
@@ -0,0 +1,38 @@
+BEGIN;
+
+create table regionsettings (
+ regionUUID char(36) not null,
+ block_terraform integer not null,
+ block_fly integer not null,
+ allow_damage integer not null,
+ restrict_pushing integer not null,
+ allow_land_resell integer not null,
+ allow_land_join_divide integer not null,
+ block_show_in_search integer not null,
+ agent_limit integer not null,
+ object_bonus float not null,
+ maturity integer not null,
+ disable_scripts integer not null,
+ disable_collisions integer not null,
+ disable_physics integer not null,
+ terrain_texture_1 char(36) not null,
+ terrain_texture_2 char(36) not null,
+ terrain_texture_3 char(36) not null,
+ terrain_texture_4 char(36) not null,
+ elevation_1_nw float not null,
+ elevation_2_nw float not null,
+ elevation_1_ne float not null,
+ elevation_2_ne float not null,
+ elevation_1_se float not null,
+ elevation_2_se float not null,
+ elevation_1_sw float not null,
+ elevation_2_sw float not null,
+ water_height float not null,
+ terrain_raise_limit float not null,
+ terrain_lower_limit float not null,
+ use_estate_sun integer not null,
+ fixed_sun integer not null,
+ sun_position float not null,
+ covenant char(36));
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
new file mode 100644
index 0000000000..03142afa37
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE users add customType varchar(32) not null default '';
+ALTER TABLE users add partner char(36) not null default '00000000-0000-0000-0000-000000000000';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
new file mode 100644
index 0000000000..1f6d1bd271
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+delete from regionsettings;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
new file mode 100644
index 0000000000..e45c09a493
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+CREATE TABLE `avatarattachments` (`UUID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `attachpoint` int(11) NOT NULL DEFAULT 0, `item` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', `asset` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000');
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
new file mode 100644
index 0000000000..94ed8181cd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql
@@ -0,0 +1,102 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE estate_groups (
+ EstateID int(10) NOT NULL,
+ uuid char(36) NOT NULL
+);
+
+CREATE TABLE estate_managers (
+ EstateID int(10) NOT NULL,
+ uuid char(36) NOT NULL
+);
+
+CREATE TABLE estate_map (
+ RegionID char(36) NOT NULL default '00000000-0000-0000-0000-000000000000',
+ EstateID int(11) NOT NULL
+);
+
+CREATE TABLE estate_settings (
+ EstateID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ EstateName varchar(64) default NULL,
+ AbuseEmailToEstateOwner tinyint(4) NOT NULL,
+ DenyAnonymous tinyint(4) NOT NULL,
+ ResetHomeOnTeleport tinyint(4) NOT NULL,
+ FixedSun tinyint(4) NOT NULL,
+ DenyTransacted tinyint(4) NOT NULL,
+ BlockDwell tinyint(4) NOT NULL,
+ DenyIdentified tinyint(4) NOT NULL,
+ AllowVoice tinyint(4) NOT NULL,
+ UseGlobalTime tinyint(4) NOT NULL,
+ PricePerMeter int(11) NOT NULL,
+ TaxFree tinyint(4) NOT NULL,
+ AllowDirectTeleport tinyint(4) NOT NULL,
+ RedirectGridX int(11) NOT NULL,
+ RedirectGridY int(11) NOT NULL,
+ ParentEstateID int(10) NOT NULL,
+ SunPosition double NOT NULL,
+ EstateSkipScripts tinyint(4) NOT NULL,
+ BillableFactor float NOT NULL,
+ PublicAccess tinyint(4) NOT NULL
+);
+insert into estate_settings (EstateID,EstateName,AbuseEmailToEstateOwner,DenyAnonymous,ResetHomeOnTeleport,FixedSun,DenyTransacted,BlockDwell,DenyIdentified,AllowVoice,UseGlobalTime,PricePerMeter,TaxFree,AllowDirectTeleport,RedirectGridX,RedirectGridY,ParentEstateID,SunPosition,PublicAccess,EstateSkipScripts,BillableFactor) values ( 99, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '');
+delete from estate_settings;
+CREATE TABLE estate_users (
+ EstateID int(10) NOT NULL,
+ uuid char(36) NOT NULL
+);
+
+CREATE TABLE estateban (
+ EstateID int(10) NOT NULL,
+ bannedUUID varchar(36) NOT NULL,
+ bannedIp varchar(16) NOT NULL,
+ bannedIpHostMask varchar(16) NOT NULL,
+ bannedNameMask varchar(64) default NULL
+);
+
+drop table regionsettings;
+CREATE TABLE regionsettings (
+ regionUUID char(36) NOT NULL,
+ block_terraform int(11) NOT NULL,
+ block_fly int(11) NOT NULL,
+ allow_damage int(11) NOT NULL,
+ restrict_pushing int(11) NOT NULL,
+ allow_land_resell int(11) NOT NULL,
+ allow_land_join_divide int(11) NOT NULL,
+ block_show_in_search int(11) NOT NULL,
+ agent_limit int(11) NOT NULL,
+ object_bonus float NOT NULL,
+ maturity int(11) NOT NULL,
+ disable_scripts int(11) NOT NULL,
+ disable_collisions int(11) NOT NULL,
+ disable_physics int(11) NOT NULL,
+ terrain_texture_1 char(36) NOT NULL,
+ terrain_texture_2 char(36) NOT NULL,
+ terrain_texture_3 char(36) NOT NULL,
+ terrain_texture_4 char(36) NOT NULL,
+ elevation_1_nw float NOT NULL,
+ elevation_2_nw float NOT NULL,
+ elevation_1_ne float NOT NULL,
+ elevation_2_ne float NOT NULL,
+ elevation_1_se float NOT NULL,
+ elevation_2_se float NOT NULL,
+ elevation_1_sw float NOT NULL,
+ elevation_2_sw float NOT NULL,
+ water_height float NOT NULL,
+ terrain_raise_limit float NOT NULL,
+ terrain_lower_limit float NOT NULL,
+ use_estate_sun int(11) NOT NULL,
+ fixed_sun int(11) NOT NULL,
+ sun_position float NOT NULL,
+ covenant char(36) default NULL,
+ Sandbox tinyint(4) NOT NULL,
+ PRIMARY KEY (regionUUID)
+);
+
+CREATE INDEX estate_ban_estate_id on estateban(EstateID);
+CREATE INDEX estate_groups_estate_id on estate_groups(EstateID);
+CREATE INDEX estate_managers_estate_id on estate_managers(EstateID);
+CREATE INDEX estate_map_estate_id on estate_map(EstateID);
+CREATE UNIQUE INDEX estate_map_region_id on estate_map(RegionID);
+CREATE INDEX estate_users_estate_id on estate_users(EstateID);
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
new file mode 100644
index 0000000000..f9454c55cf
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql
@@ -0,0 +1,20 @@
+BEGIN TRANSACTION;
+
+-- usersagents table
+CREATE TABLE IF NOT EXISTS useragents(
+ UUID varchar(255) primary key,
+ agentIP varchar(255),
+ agentPort integer,
+ agentOnline boolean,
+ sessionID varchar(255),
+ secureSessionID varchar(255),
+ regionID varchar(255),
+ loginTime integer,
+ logoutTime integer,
+ currentRegion varchar(255),
+ currentHandle varchar(255),
+ currentPosX float,
+ currentPosY float,
+ currentPosZ float);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
new file mode 100644
index 0000000000..1c813a0d40
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql
@@ -0,0 +1,8 @@
+begin;
+
+alter table estate_settings add column AbuseEmail varchar(255) not null default '';
+
+alter table estate_settings add column EstateOwner varchar(36) not null default '';
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
new file mode 100644
index 0000000000..8b0cd285c7
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql
@@ -0,0 +1,7 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE useragents add currentLookAtX float not null default 128;
+ALTER TABLE useragents add currentLookAtY float not null default 128;
+ALTER TABLE useragents add currentLookAtZ float not null default 70;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
new file mode 100644
index 0000000000..28bfbf59c3
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql
@@ -0,0 +1,6 @@
+begin;
+
+alter table estate_settings add column DenyMinors tinyint not null default 0;
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
new file mode 100644
index 0000000000..97da81848c
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql
@@ -0,0 +1,5 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE users add email varchar(250);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
new file mode 100644
index 0000000000..1f40548f36
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql
@@ -0,0 +1,8 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN ColorR integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorG integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorB integer not null default 0;
+ALTER TABLE prims ADD COLUMN ColorA integer not null default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
new file mode 100644
index 0000000000..8ab03ef897
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql
@@ -0,0 +1,11 @@
+BEGIN;
+
+update users
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+update useragents
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
new file mode 100644
index 0000000000..b91ccf0a8d
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN ClickAction INTEGER NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
new file mode 100644
index 0000000000..5f956dadfd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql
@@ -0,0 +1,37 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE IF NOT EXISTS avatarappearance(
+ Owner varchar(36) NOT NULL primary key,
+ BodyItem varchar(36) DEFAULT NULL,
+ BodyAsset varchar(36) DEFAULT NULL,
+ SkinItem varchar(36) DEFAULT NULL,
+ SkinAsset varchar(36) DEFAULT NULL,
+ HairItem varchar(36) DEFAULT NULL,
+ HairAsset varchar(36) DEFAULT NULL,
+ EyesItem varchar(36) DEFAULT NULL,
+ EyesAsset varchar(36) DEFAULT NULL,
+ ShirtItem varchar(36) DEFAULT NULL,
+ ShirtAsset varchar(36) DEFAULT NULL,
+ PantsItem varchar(36) DEFAULT NULL,
+ PantsAsset varchar(36) DEFAULT NULL,
+ ShoesItem varchar(36) DEFAULT NULL,
+ ShoesAsset varchar(36) DEFAULT NULL,
+ SocksItem varchar(36) DEFAULT NULL,
+ SocksAsset varchar(36) DEFAULT NULL,
+ JacketItem varchar(36) DEFAULT NULL,
+ JacketAsset varchar(36) DEFAULT NULL,
+ GlovesItem varchar(36) DEFAULT NULL,
+ GlovesAsset varchar(36) DEFAULT NULL,
+ UnderShirtItem varchar(36) DEFAULT NULL,
+ UnderShirtAsset varchar(36) DEFAULT NULL,
+ UnderPantsItem varchar(36) DEFAULT NULL,
+ UnderPantsAsset varchar(36) DEFAULT NULL,
+ SkirtItem varchar(36) DEFAULT NULL,
+ SkirtAsset varchar(36) DEFAULT NULL,
+ Texture blob,
+ VisualParams blob,
+ Serial int DEFAULT NULL,
+ AvatarHeight float DEFAULT NULL
+);
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
new file mode 100644
index 0000000000..42bef89616
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql
@@ -0,0 +1,28 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN PayPrice INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton1 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton2 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton3 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN PayButton4 INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN LoopedSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+ALTER TABLE prims ADD COLUMN LoopedSoundGain float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN TextureAnimation string;
+ALTER TABLE prims ADD COLUMN ParticleSystem string;
+ALTER TABLE prims ADD COLUMN OmegaX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN OmegaY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN OmegaZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraEyeOffsetZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetX float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetY float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN CameraAtOffsetZ float NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN ForceMouselook string NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN ScriptAccessPin INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN AllowedDrop INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN DieAtEdge string NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN SalePrice INTEGER NOT NULL default 0;
+ALTER TABLE prims ADD COLUMN SaleType string NOT NULL default 0;
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
new file mode 100644
index 0000000000..d952b78bd2
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN Material INTEGER NOT NULL default 3;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
new file mode 100644
index 0000000000..11529cd3f1
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE land ADD COLUMN OtherCleanTime INTEGER NOT NULL default 0;
+ALTER TABLE land ADD COLUMN Dwell INTEGER NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
new file mode 100644
index 0000000000..c59b27e745
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql
@@ -0,0 +1,8 @@
+begin;
+
+ALTER TABLE regionsettings ADD COLUMN sunvectorx double NOT NULL default 0;
+ALTER TABLE regionsettings ADD COLUMN sunvectory double NOT NULL default 0;
+ALTER TABLE regionsettings ADD COLUMN sunvectorz double NOT NULL default 0;
+
+commit;
+
diff --git a/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
new file mode 100644
index 0000000000..c43f356be3
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql
@@ -0,0 +1,6 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN CollisionSound varchar(36) NOT NULL default '00000000-0000-0000-0000-000000000000';
+ALTER TABLE prims ADD COLUMN CollisionSoundVolume float NOT NULL default 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
new file mode 100644
index 0000000000..52f160cdbc
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql
@@ -0,0 +1,5 @@
+BEGIN;
+
+ALTER TABLE prims ADD COLUMN VolumeDetect INTEGER NOT NULL DEFAULT 0;
+
+COMMIT;
diff --git a/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
new file mode 100644
index 0000000000..6c6b7b5d40
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql
@@ -0,0 +1,8 @@
+BEGIN;
+CREATE TEMPORARY TABLE prims_backup(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
+INSERT INTO prims_backup SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims;
+DROP TABLE prims;
+CREATE TABLE prims(UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect);
+INSERT INTO prims SELECT UUID,RegionUUID,CreationDate,Name,SceneGroupID,Text,Description,SitName,TouchName,CreatorID,OwnerID,GroupID,LastOwnerID,OwnerMask,NextOwnerMask,GroupMask,EveryoneMask,BaseMask,PositionX,PositionY,PositionZ,GroupPositionX,GroupPositionY,GroupPositionZ,VelocityX,VelocityY,VelocityZ,AngularVelocityX,AngularVelocityY,AngularVelocityZ,AccelerationX,AccelerationY,AccelerationZ,RotationX,RotationY,RotationZ,RotationW,ObjectFlags,SitTargetOffsetX,SitTargetOffsetY,SitTargetOffsetZ,SitTargetOrientW,SitTargetOrientX,SitTargetOrientY,SitTargetOrientZ,ColorR,ColorG,ColorB,ColorA,ClickAction,PayPrice,PayButton1,PayButton2,PayButton3,PayButton4,LoopedSound,LoopedSoundGain,TextureAnimation,ParticleSystem,OmegaX,OmegaY,OmegaZ,CameraEyeOffsetX,CameraEyeOffsetY,CameraEyeOffsetZ,CameraAtOffsetX,CameraAtOffsetY,CameraAtOffsetZ,ForceMouselook,ScriptAccessPin,AllowedDrop,DieAtEdge,SalePrice,SaleType,Material,CollisionSound,CollisionSoundVolume,VolumeDetect FROM prims_backup;
+DROP TABLE prims_backup;
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
new file mode 100644
index 0000000000..6a390c2161
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql
@@ -0,0 +1,79 @@
+BEGIN;
+
+update terrain
+ set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
+ where RegionUUID not like '%-%';
+
+
+update landaccesslist
+ set LandUUID = substr(LandUUID, 1, 8) || "-" || substr(LandUUID, 9, 4) || "-" || substr(LandUUID, 13, 4) || "-" || substr(LandUUID, 17, 4) || "-" || substr(LandUUID, 21, 12)
+ where LandUUID not like '%-%';
+
+update landaccesslist
+ set AccessUUID = substr(AccessUUID, 1, 8) || "-" || substr(AccessUUID, 9, 4) || "-" || substr(AccessUUID, 13, 4) || "-" || substr(AccessUUID, 17, 4) || "-" || substr(AccessUUID, 21, 12)
+ where AccessUUID not like '%-%';
+
+
+update prims
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+update prims
+ set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
+ where RegionUUID not like '%-%';
+
+update prims
+ set SceneGroupID = substr(SceneGroupID, 1, 8) || "-" || substr(SceneGroupID, 9, 4) || "-" || substr(SceneGroupID, 13, 4) || "-" || substr(SceneGroupID, 17, 4) || "-" || substr(SceneGroupID, 21, 12)
+ where SceneGroupID not like '%-%';
+
+update prims
+ set CreatorID = substr(CreatorID, 1, 8) || "-" || substr(CreatorID, 9, 4) || "-" || substr(CreatorID, 13, 4) || "-" || substr(CreatorID, 17, 4) || "-" || substr(CreatorID, 21, 12)
+ where CreatorID not like '%-%';
+
+update prims
+ set OwnerID = substr(OwnerID, 1, 8) || "-" || substr(OwnerID, 9, 4) || "-" || substr(OwnerID, 13, 4) || "-" || substr(OwnerID, 17, 4) || "-" || substr(OwnerID, 21, 12)
+ where OwnerID not like '%-%';
+
+update prims
+ set GroupID = substr(GroupID, 1, 8) || "-" || substr(GroupID, 9, 4) || "-" || substr(GroupID, 13, 4) || "-" || substr(GroupID, 17, 4) || "-" || substr(GroupID, 21, 12)
+ where GroupID not like '%-%';
+
+update prims
+ set LastOwnerID = substr(LastOwnerID, 1, 8) || "-" || substr(LastOwnerID, 9, 4) || "-" || substr(LastOwnerID, 13, 4) || "-" || substr(LastOwnerID, 17, 4) || "-" || substr(LastOwnerID, 21, 12)
+ where LastOwnerID not like '%-%';
+
+
+update primshapes
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+
+update land
+ set UUID = substr(UUID, 1, 8) || "-" || substr(UUID, 9, 4) || "-" || substr(UUID, 13, 4) || "-" || substr(UUID, 17, 4) || "-" || substr(UUID, 21, 12)
+ where UUID not like '%-%';
+
+update land
+ set RegionUUID = substr(RegionUUID, 1, 8) || "-" || substr(RegionUUID, 9, 4) || "-" || substr(RegionUUID, 13, 4) || "-" || substr(RegionUUID, 17, 4) || "-" || substr(RegionUUID, 21, 12)
+ where RegionUUID not like '%-%';
+
+update land
+ set OwnerUUID = substr(OwnerUUID, 1, 8) || "-" || substr(OwnerUUID, 9, 4) || "-" || substr(OwnerUUID, 13, 4) || "-" || substr(OwnerUUID, 17, 4) || "-" || substr(OwnerUUID, 21, 12)
+ where OwnerUUID not like '%-%';
+
+update land
+ set GroupUUID = substr(GroupUUID, 1, 8) || "-" || substr(GroupUUID, 9, 4) || "-" || substr(GroupUUID, 13, 4) || "-" || substr(GroupUUID, 17, 4) || "-" || substr(GroupUUID, 21, 12)
+ where GroupUUID not like '%-%';
+
+update land
+ set MediaTextureUUID = substr(MediaTextureUUID, 1, 8) || "-" || substr(MediaTextureUUID, 9, 4) || "-" || substr(MediaTextureUUID, 13, 4) || "-" || substr(MediaTextureUUID, 17, 4) || "-" || substr(MediaTextureUUID, 21, 12)
+ where MediaTextureUUID not like '%-%';
+
+update land
+ set SnapshotUUID = substr(SnapshotUUID, 1, 8) || "-" || substr(SnapshotUUID, 9, 4) || "-" || substr(SnapshotUUID, 13, 4) || "-" || substr(SnapshotUUID, 17, 4) || "-" || substr(SnapshotUUID, 21, 12)
+ where SnapshotUUID not like '%-%';
+
+update land
+ set AuthbuyerID = substr(AuthbuyerID, 1, 8) || "-" || substr(AuthbuyerID, 9, 4) || "-" || substr(AuthbuyerID, 13, 4) || "-" || substr(AuthbuyerID, 17, 4) || "-" || substr(AuthbuyerID, 21, 12)
+ where AuthbuyerID not like '%-%';
+
+COMMIT;
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
new file mode 100644
index 0000000000..e6764facbd
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
new file mode 100644
index 0000000000..a032670588
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using System.Reflection;
+using System.Collections.Generic;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// An asset storage interface for the SQLite database system
+ ///
+ public class SQLiteAssetData : AssetDataBase
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private const string SelectAssetSQL = "select * from assets where UUID=:UUID";
+ private const string SelectAssetMetadataSQL = "select Name, Description, Type, Temporary, UUID from assets limit :start, :count";
+ private const string DeleteAssetSQL = "delete from assets where UUID=:UUID";
+ private const string InsertAssetSQL = "insert into assets(UUID, Name, Description, Type, Local, Temporary, Data) values(:UUID, :Name, :Description, :Type, :Local, :Temporary, :Data)";
+ private const string UpdateAssetSQL = "update assets set Name=:Name, Description=:Description, Type=:Type, Local=:Local, Temporary=:Temporary, Data=:Data where UUID=:UUID";
+ private const string assetSelect = "select * from assets";
+
+ private SqliteConnection m_conn;
+
+ override public void Dispose()
+ {
+ if (m_conn != null)
+ {
+ m_conn.Close();
+ m_conn = null;
+ }
+ }
+
+ ///
+ ///
+ /// - Initialises AssetData interface
+ /// - Loads and initialises a new SQLite connection and maintains it.
+ /// - use default URI if connect string is empty.
+ ///
+ ///
+ /// connect string
+ override public void Initialise(string dbconnect)
+ {
+ if (dbconnect == string.Empty)
+ {
+ dbconnect = "URI=file:Asset.db,version=3";
+ }
+ m_conn = new SqliteConnection(dbconnect);
+ m_conn.Open();
+
+ Assembly assem = GetType().Assembly;
+ Migration m = new Migration(m_conn, assem, "AssetStore");
+ m.Update();
+
+ return;
+ }
+
+ ///
+ /// Fetch Asset
+ ///
+ /// UUID of ... ?
+ /// Asset base
+ override public AssetBase GetAsset(UUID uuid)
+ {
+ lock (this)
+ {
+ using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+ using (IDataReader reader = cmd.ExecuteReader())
+ {
+ if (reader.Read())
+ {
+ AssetBase asset = buildAsset(reader);
+ reader.Close();
+ return asset;
+ }
+ else
+ {
+ reader.Close();
+ return null;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Create an asset
+ ///
+ /// Asset Base
+ override public void StoreAsset(AssetBase asset)
+ {
+ //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
+ if (ExistsAsset(asset.FullID))
+ {
+ //LogAssetLoad(asset);
+
+ lock (this)
+ {
+ using (SqliteCommand cmd = new SqliteCommand(UpdateAssetSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
+ cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
+ cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
+ cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
+ cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
+ cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ else
+ {
+ lock (this)
+ {
+ using (SqliteCommand cmd = new SqliteCommand(InsertAssetSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":UUID", asset.FullID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":Name", asset.Name));
+ cmd.Parameters.Add(new SqliteParameter(":Description", asset.Description));
+ cmd.Parameters.Add(new SqliteParameter(":Type", asset.Type));
+ cmd.Parameters.Add(new SqliteParameter(":Local", asset.Local));
+ cmd.Parameters.Add(new SqliteParameter(":Temporary", asset.Temporary));
+ cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+ }
+
+// ///
+// /// Some... logging functionnality
+// ///
+// ///
+// private static void LogAssetLoad(AssetBase asset)
+// {
+// string temporary = asset.Temporary ? "Temporary" : "Stored";
+// string local = asset.Local ? "Local" : "Remote";
+//
+// int assetLength = (asset.Data != null) ? asset.Data.Length : 0;
+//
+// m_log.Debug("[ASSET DB]: " +
+// string.Format("Loaded {5} {4} Asset: [{0}][{3}] \"{1}\":{2} ({6} bytes)",
+// asset.FullID, asset.Name, asset.Description, asset.Type,
+// temporary, local, assetLength));
+// }
+
+ ///
+ /// Check if an asset exist in database
+ ///
+ /// The asset UUID
+ /// True if exist, or false.
+ override public bool ExistsAsset(UUID uuid)
+ {
+ lock (this) {
+ using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+ using (IDataReader reader = cmd.ExecuteReader())
+ {
+ if (reader.Read())
+ {
+ reader.Close();
+ return true;
+ }
+ else
+ {
+ reader.Close();
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Delete an asset from database
+ ///
+ ///
+ public void DeleteAsset(UUID uuid)
+ {
+ using (SqliteCommand cmd = new SqliteCommand(DeleteAssetSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
+
+ cmd.ExecuteNonQuery();
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static AssetBase buildAsset(IDataReader row)
+ {
+ // TODO: this doesn't work yet because something more
+ // interesting has to be done to actually get these values
+ // back out. Not enough time to figure it out yet.
+ AssetBase asset = new AssetBase(
+ new UUID((String)row["UUID"]),
+ (String)row["Name"],
+ Convert.ToSByte(row["Type"]),
+ UUID.Zero.ToString()
+ );
+
+ asset.Description = (String) row["Description"];
+ asset.Local = Convert.ToBoolean(row["Local"]);
+ asset.Temporary = Convert.ToBoolean(row["Temporary"]);
+ asset.Data = (byte[]) row["Data"];
+ return asset;
+ }
+
+ private static AssetMetadata buildAssetMetadata(IDataReader row)
+ {
+ AssetMetadata metadata = new AssetMetadata();
+
+ metadata.FullID = new UUID((string) row["UUID"]);
+ metadata.Name = (string) row["Name"];
+ metadata.Description = (string) row["Description"];
+ metadata.Type = Convert.ToSByte(row["Type"]);
+ metadata.Temporary = Convert.ToBoolean(row["Temporary"]); // Not sure if this is correct.
+
+ // Current SHA1s are not stored/computed.
+ metadata.SHA1 = new byte[] {};
+
+ return metadata;
+ }
+
+ ///
+ /// Returns a list of AssetMetadata objects. The list is a subset of
+ /// the entire data set offset by containing
+ /// elements.
+ ///
+ /// The number of results to discard from the total data set.
+ /// The number of rows the returned list should contain.
+ /// A list of AssetMetadata objects.
+ public override List FetchAssetMetadataSet(int start, int count)
+ {
+ List retList = new List(count);
+
+ lock (this)
+ {
+ using (SqliteCommand cmd = new SqliteCommand(SelectAssetMetadataSQL, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":start", start));
+ cmd.Parameters.Add(new SqliteParameter(":count", count));
+
+ using (IDataReader reader = cmd.ExecuteReader())
+ {
+ while (reader.Read())
+ {
+ AssetMetadata metadata = buildAssetMetadata(reader);
+ retList.Add(metadata);
+ }
+ }
+ }
+ }
+
+ return retList;
+ }
+
+ /***********************************************************************
+ *
+ * Database Binding functions
+ *
+ * These will be db specific due to typing, and minor differences
+ * in databases.
+ *
+ **********************************************************************/
+
+ #region IPlugin interface
+
+ ///
+ ///
+ ///
+ override public string Version
+ {
+ get
+ {
+ Module module = GetType().Module;
+ // string dllName = module.Assembly.ManifestModule.Name;
+ Version dllVersion = module.Assembly.GetName().Version;
+
+ return
+ string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
+ dllVersion.Revision);
+ }
+ }
+
+ ///
+ /// Initialise the AssetData interface using default URI
+ ///
+ override public void Initialise()
+ {
+ Initialise("URI=file:Asset.db,version=3");
+ }
+
+ ///
+ /// Name of this DB provider
+ ///
+ override public string Name
+ {
+ get { return "SQLite Asset storage engine"; }
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
new file mode 100644
index 0000000000..aa10734d50
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData
+ {
+ private string m_Realm;
+ private List m_ColumnNames;
+ private int m_LastExpire;
+ private string m_connectionString;
+
+ protected static SqliteConnection m_Connection;
+ private static bool m_initialized = false;
+
+ public SQLiteAuthenticationData(string connectionString, string realm)
+ : base(connectionString)
+ {
+ m_Realm = realm;
+ m_connectionString = connectionString;
+
+ if (!m_initialized)
+ {
+ m_Connection = new SqliteConnection(connectionString);
+ m_Connection.Open();
+
+ using (SqliteConnection dbcon = (SqliteConnection)((ICloneable)m_Connection).Clone())
+ {
+ dbcon.Open();
+ Migration m = new Migration(dbcon, GetType().Assembly, "AuthStore");
+ m.Update();
+ dbcon.Close();
+ }
+
+ m_initialized = true;
+ }
+ }
+
+ public AuthenticationData Get(UUID principalID)
+ {
+ AuthenticationData ret = new AuthenticationData();
+ ret.Data = new Dictionary();
+
+ SqliteCommand cmd = new SqliteCommand("select * from `" + m_Realm + "` where UUID = :PrincipalID");
+ cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
+
+ IDataReader result = ExecuteReader(cmd, m_Connection);
+
+ try
+ {
+ if (result.Read())
+ {
+ ret.PrincipalID = principalID;
+
+ if (m_ColumnNames == null)
+ {
+ m_ColumnNames = new List();
+
+ DataTable schemaTable = result.GetSchemaTable();
+ foreach (DataRow row in schemaTable.Rows)
+ m_ColumnNames.Add(row["ColumnName"].ToString());
+ }
+
+ foreach (string s in m_ColumnNames)
+ {
+ if (s == "UUID")
+ continue;
+
+ ret.Data[s] = result[s].ToString();
+ }
+
+ return ret;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ catch
+ {
+ }
+ finally
+ {
+ CloseCommand(cmd);
+ }
+
+ return null;
+ }
+
+ public bool Store(AuthenticationData data)
+ {
+ if (data.Data.ContainsKey("UUID"))
+ data.Data.Remove("UUID");
+
+ string[] fields = new List(data.Data.Keys).ToArray();
+ string[] values = new string[data.Data.Count];
+ int i = 0;
+ foreach (object o in data.Data.Values)
+ values[i++] = o.ToString();
+
+ SqliteCommand cmd = new SqliteCommand();
+
+ if (Get(data.PrincipalID) != null)
+ {
+
+
+ string update = "update `" + m_Realm + "` set ";
+ bool first = true;
+ foreach (string field in fields)
+ {
+ if (!first)
+ update += ", ";
+ update += "`" + field + "` = :" + field;
+ cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
+
+ first = false;
+ }
+
+ update += " where UUID = :UUID";
+ cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
+
+ cmd.CommandText = update;
+ try
+ {
+ if (ExecuteNonQuery(cmd, m_Connection) < 1)
+ {
+ CloseCommand(cmd);
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ CloseCommand(cmd);
+ return false;
+ }
+ }
+
+ else
+ {
+ string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
+ String.Join("`, `", fields) +
+ "`) values (:UUID, :" + String.Join(", :", fields) + ")";
+
+ cmd.Parameters.Add(new SqliteParameter(":UUID", data.PrincipalID.ToString()));
+ foreach (string field in fields)
+ cmd.Parameters.Add(new SqliteParameter(":" + field, data.Data[field]));
+
+ cmd.CommandText = insert;
+
+ try
+ {
+ if (ExecuteNonQuery(cmd, m_Connection) < 1)
+ {
+ CloseCommand(cmd);
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ CloseCommand(cmd);
+ return false;
+ }
+ }
+
+ CloseCommand(cmd);
+
+ return true;
+ }
+
+ public bool SetDataItem(UUID principalID, string item, string value)
+ {
+ SqliteCommand cmd = new SqliteCommand("update `" + m_Realm +
+ "` set `" + item + "` = " + value + " where UUID = '" + principalID.ToString() + "'");
+
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ return true;
+
+ return false;
+ }
+
+ public bool SetToken(UUID principalID, string token, int lifetime)
+ {
+ if (System.Environment.TickCount - m_LastExpire > 30000)
+ DoExpire();
+
+ SqliteCommand cmd = new SqliteCommand("insert into tokens (UUID, token, validity) values ('" + principalID.ToString() +
+ "', '" + token + "', datetime('now', 'localtime', '+" + lifetime.ToString() + " minutes'))");
+
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ {
+ cmd.Dispose();
+ return true;
+ }
+
+ cmd.Dispose();
+ return false;
+ }
+
+ public bool CheckToken(UUID principalID, string token, int lifetime)
+ {
+ if (System.Environment.TickCount - m_LastExpire > 30000)
+ DoExpire();
+
+ SqliteCommand cmd = new SqliteCommand("update tokens set validity = datetime('now', 'localtime', '+" + lifetime.ToString() +
+ " minutes') where UUID = '" + principalID.ToString() + "' and token = '" + token + "' and validity > datetime('now', 'localtime')");
+
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ {
+ cmd.Dispose();
+ return true;
+ }
+
+ cmd.Dispose();
+
+ return false;
+ }
+
+ private void DoExpire()
+ {
+ SqliteCommand cmd = new SqliteCommand("delete from tokens where validity < datetime('now', 'localtime')");
+ ExecuteNonQuery(cmd, m_Connection);
+
+ cmd.Dispose();
+
+ m_LastExpire = System.Environment.TickCount;
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
new file mode 100644
index 0000000000..b3f4a4c077
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using System.Threading;
+using log4net;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// A SQLite Interface for Avatar Data
+ ///
+ public class SQLiteAvatarData : SQLiteGenericTableHandler,
+ IAvatarData
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public SQLiteAvatarData(string connectionString, string realm) :
+ base(connectionString, realm, "Avatar")
+ {
+ }
+
+ public bool Delete(UUID principalID, string name)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm);
+ cmd.Parameters.Add(":PrincipalID", principalID.ToString());
+ cmd.Parameters.Add(":Name", name);
+
+ try
+ {
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ return true;
+
+ return false;
+ }
+ finally
+ {
+ CloseCommand(cmd);
+ }
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
new file mode 100644
index 0000000000..bd6b776f80
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Data.SQLite
+{
+ public class SQLiteEstateStore : IEstateDataStore
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private SqliteConnection m_connection;
+ private string m_connectionString;
+
+ private FieldInfo[] m_Fields;
+ private Dictionary m_FieldMap =
+ new Dictionary();
+
+ public void Initialise(string connectionString)
+ {
+ m_connectionString = connectionString;
+
+ m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
+
+ m_connection = new SqliteConnection(m_connectionString);
+ m_connection.Open();
+
+ Assembly assem = GetType().Assembly;
+ Migration m = new Migration(m_connection, assem, "EstateStore");
+ m.Update();
+
+ m_connection.Close();
+ m_connection.Open();
+
+ Type t = typeof(EstateSettings);
+ m_Fields = t.GetFields(BindingFlags.NonPublic |
+ BindingFlags.Instance |
+ BindingFlags.DeclaredOnly);
+
+ foreach (FieldInfo f in m_Fields)
+ if (f.Name.Substring(0, 2) == "m_")
+ m_FieldMap[f.Name.Substring(2)] = f;
+ }
+
+ private string[] FieldList
+ {
+ get { return new List(m_FieldMap.Keys).ToArray(); }
+ }
+
+ public EstateSettings LoadEstateSettings(UUID regionID, bool create)
+ {
+ 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";
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = sql;
+ cmd.Parameters.Add(":RegionID", regionID.ToString());
+
+ return DoLoad(cmd, regionID, create);
+ }
+
+ private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create)
+ {
+ EstateSettings es = new EstateSettings();
+ es.OnSave += StoreEstateSettings;
+
+ IDataReader r = cmd.ExecuteReader();
+
+ if (r.Read())
+ {
+ foreach (string name in FieldList)
+ {
+ if (m_FieldMap[name].GetValue(es) is bool)
+ {
+ int v = Convert.ToInt32(r[name]);
+ if (v != 0)
+ m_FieldMap[name].SetValue(es, true);
+ else
+ m_FieldMap[name].SetValue(es, false);
+ }
+ else if (m_FieldMap[name].GetValue(es) is UUID)
+ {
+ UUID uuid = UUID.Zero;
+
+ UUID.TryParse(r[name].ToString(), out uuid);
+ m_FieldMap[name].SetValue(es, uuid);
+ }
+ else
+ {
+ m_FieldMap[name].SetValue(es, Convert.ChangeType(r[name], m_FieldMap[name].FieldType));
+ }
+ }
+ r.Close();
+ }
+ else if (create)
+ {
+ r.Close();
+
+ List names = new List(FieldList);
+
+ names.Remove("EstateID");
+
+ string sql = "insert into estate_settings ("+String.Join(",", names.ToArray())+") values ( :"+String.Join(", :", names.ToArray())+")";
+
+ cmd.CommandText = sql;
+ cmd.Parameters.Clear();
+
+ foreach (string name in FieldList)
+ {
+ if (m_FieldMap[name].GetValue(es) is bool)
+ {
+ if ((bool)m_FieldMap[name].GetValue(es))
+ cmd.Parameters.Add(":"+name, "1");
+ else
+ cmd.Parameters.Add(":"+name, "0");
+ }
+ else
+ {
+ cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString());
+ }
+ }
+
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "select LAST_INSERT_ROWID() as id";
+ cmd.Parameters.Clear();
+
+ r = cmd.ExecuteReader();
+
+ r.Read();
+
+ es.EstateID = Convert.ToUInt32(r["id"]);
+
+ r.Close();
+
+ cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
+ cmd.Parameters.Add(":RegionID", regionID.ToString());
+ cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+
+ // This will throw on dupe key
+ try
+ {
+ cmd.ExecuteNonQuery();
+ }
+ catch (Exception)
+ {
+ }
+
+ es.Save();
+ }
+
+ LoadBanList(es);
+
+ es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
+ es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
+ es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
+ return es;
+ }
+
+ public void StoreEstateSettings(EstateSettings es)
+ {
+ List fields = new List(FieldList);
+ fields.Remove("EstateID");
+
+ List terms = new List();
+
+ foreach (string f in fields)
+ terms.Add(f+" = :"+f);
+
+ string sql = "update estate_settings set "+String.Join(", ", terms.ToArray())+" where EstateID = :EstateID";
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = sql;
+
+ foreach (string name in FieldList)
+ {
+ if (m_FieldMap[name].GetValue(es) is bool)
+ {
+ if ((bool)m_FieldMap[name].GetValue(es))
+ cmd.Parameters.Add(":"+name, "1");
+ else
+ cmd.Parameters.Add(":"+name, "0");
+ }
+ else
+ {
+ cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString());
+ }
+ }
+
+ cmd.ExecuteNonQuery();
+
+ SaveBanList(es);
+ SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
+ SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
+ SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
+ }
+
+ private void LoadBanList(EstateSettings es)
+ {
+ es.ClearBans();
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID";
+ cmd.Parameters.Add(":EstateID", es.EstateID);
+
+ IDataReader r = cmd.ExecuteReader();
+
+ while (r.Read())
+ {
+ EstateBan eb = new EstateBan();
+
+ UUID uuid = new UUID();
+ UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
+
+ eb.BannedUserID = uuid;
+ eb.BannedHostAddress = "0.0.0.0";
+ eb.BannedHostIPMask = "0.0.0.0";
+ es.AddBan(eb);
+ }
+ r.Close();
+ }
+
+ private void SaveBanList(EstateSettings es)
+ {
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = "delete from estateban where EstateID = :EstateID";
+ cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+
+ cmd.ExecuteNonQuery();
+
+ cmd.Parameters.Clear();
+
+ cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( :EstateID, :bannedUUID, '', '', '' )";
+
+ foreach (EstateBan b in es.EstateBans)
+ {
+ cmd.Parameters.Add(":EstateID", es.EstateID.ToString());
+ cmd.Parameters.Add(":bannedUUID", b.BannedUserID.ToString());
+
+ cmd.ExecuteNonQuery();
+ cmd.Parameters.Clear();
+ }
+ }
+
+ void SaveUUIDList(uint EstateID, string table, UUID[] data)
+ {
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = "delete from "+table+" where EstateID = :EstateID";
+ cmd.Parameters.Add(":EstateID", EstateID.ToString());
+
+ cmd.ExecuteNonQuery();
+
+ cmd.Parameters.Clear();
+
+ cmd.CommandText = "insert into "+table+" (EstateID, uuid) values ( :EstateID, :uuid )";
+
+ foreach (UUID uuid in data)
+ {
+ cmd.Parameters.Add(":EstateID", EstateID.ToString());
+ cmd.Parameters.Add(":uuid", uuid.ToString());
+
+ cmd.ExecuteNonQuery();
+ cmd.Parameters.Clear();
+ }
+ }
+
+ UUID[] LoadUUIDList(uint EstateID, string table)
+ {
+ List uuids = new List();
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID";
+ cmd.Parameters.Add(":EstateID", EstateID);
+
+ IDataReader r = cmd.ExecuteReader();
+
+ while (r.Read())
+ {
+ // EstateBan eb = new EstateBan();
+
+ UUID uuid = new UUID();
+ UUID.TryParse(r["uuid"].ToString(), out uuid);
+
+ uuids.Add(uuid);
+ }
+ r.Close();
+
+ return uuids.ToArray();
+ }
+
+ public EstateSettings LoadEstateSettings(int estateID)
+ {
+ string sql = "select estate_settings."+String.Join(",estate_settings.", FieldList)+" from estate_settings where estate_settings.EstateID :EstateID";
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = sql;
+ cmd.Parameters.Add(":EstateID", estateID.ToString());
+
+ return DoLoad(cmd, UUID.Zero, false);
+ }
+
+ public List GetEstates(string search)
+ {
+ List result = new List();
+
+ string sql = "select EstateID from estate_settings where estate_settings.EstateName :EstateName";
+
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = sql;
+ cmd.Parameters.Add(":EstateName", search);
+
+ IDataReader r = cmd.ExecuteReader();
+
+ while (r.Read())
+ {
+ result.Add(Convert.ToInt32(r["EstateID"]));
+ }
+ r.Close();
+
+ return result;
+ }
+
+ public bool LinkRegion(UUID regionID, int estateID)
+ {
+ SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand();
+
+ cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)";
+ cmd.Parameters.Add(":RegionID", regionID.ToString());
+ cmd.Parameters.Add(":EstateID", estateID.ToString());
+
+ if (cmd.ExecuteNonQuery() == 0)
+ return false;
+
+ return true;
+ }
+
+ public List GetRegions(int estateID)
+ {
+ return new List();
+ }
+
+ public bool DeleteEstate(int estateID)
+ {
+ return false;
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
new file mode 100644
index 0000000000..20b508515a
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// A database interface class to a user profile storage system
+ ///
+ public class SQLiteFramework
+ {
+ protected Object m_lockObject = new Object();
+
+ protected SQLiteFramework(string connectionString)
+ {
+ }
+
+ //////////////////////////////////////////////////////////////
+ //
+ // All non queries are funneled through one connection
+ // to increase performance a little
+ //
+ protected int ExecuteNonQuery(SqliteCommand cmd, SqliteConnection connection)
+ {
+ lock (connection)
+ {
+ SqliteConnection newConnection =
+ (SqliteConnection)((ICloneable)connection).Clone();
+ newConnection.Open();
+
+ cmd.Connection = newConnection;
+ //Console.WriteLine("XXX " + cmd.CommandText);
+
+ return cmd.ExecuteNonQuery();
+ }
+ }
+
+ protected IDataReader ExecuteReader(SqliteCommand cmd, SqliteConnection connection)
+ {
+ lock (connection)
+ {
+ SqliteConnection newConnection =
+ (SqliteConnection)((ICloneable)connection).Clone();
+ newConnection.Open();
+
+ cmd.Connection = newConnection;
+ //Console.WriteLine("XXX " + cmd.CommandText);
+
+ return cmd.ExecuteReader();
+ }
+ }
+
+ protected void CloseCommand(SqliteCommand cmd)
+ {
+ cmd.Connection.Close();
+ cmd.Connection.Dispose();
+ cmd.Dispose();
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
new file mode 100644
index 0000000000..0b121826d6
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ public class SQLiteFriendsData : SQLiteGenericTableHandler, IFriendsData
+ {
+ public SQLiteFriendsData(string connectionString, string realm)
+ : base(connectionString, realm, "FriendsStore")
+ {
+ }
+
+ public FriendsData[] GetFriends(UUID userID)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ 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);
+ cmd.Parameters.Add(":PrincipalID", userID.ToString());
+
+ return DoQuery(cmd);
+
+ }
+
+ public bool Delete(UUID principalID, string friend)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
+ cmd.Parameters.Add(":PrincipalID", principalID.ToString());
+ cmd.Parameters.Add(":Friend", friend);
+
+ ExecuteNonQuery(cmd, cmd.Connection);
+
+ return true;
+ }
+
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
new file mode 100644
index 0000000000..b39bb19fb7
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+
+namespace OpenSim.Data.SQLite
+{
+ public class SQLiteGenericTableHandler : SQLiteFramework where T: class, new()
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ protected Dictionary m_Fields =
+ new Dictionary();
+
+ protected List m_ColumnNames = null;
+ protected string m_Realm;
+ protected FieldInfo m_DataField = null;
+
+ protected static SqliteConnection m_Connection;
+ private static bool m_initialized;
+
+ public SQLiteGenericTableHandler(string connectionString,
+ string realm, string storeName) : base(connectionString)
+ {
+ m_Realm = realm;
+
+ if (!m_initialized)
+ {
+ m_Connection = new SqliteConnection(connectionString);
+ m_Connection.Open();
+
+ if (storeName != String.Empty)
+ {
+ Assembly assem = GetType().Assembly;
+ SqliteConnection newConnection =
+ (SqliteConnection)((ICloneable)m_Connection).Clone();
+ newConnection.Open();
+
+ Migration m = new Migration(newConnection, assem, storeName);
+ m.Update();
+ newConnection.Close();
+ newConnection.Dispose();
+ }
+
+ m_initialized = true;
+ }
+
+ Type t = typeof(T);
+ FieldInfo[] fields = t.GetFields(BindingFlags.Public |
+ BindingFlags.Instance |
+ BindingFlags.DeclaredOnly);
+
+ if (fields.Length == 0)
+ return;
+
+ foreach (FieldInfo f in fields)
+ {
+ if (f.Name != "Data")
+ m_Fields[f.Name] = f;
+ else
+ m_DataField = f;
+ }
+ }
+
+ private void CheckColumnNames(IDataReader reader)
+ {
+ if (m_ColumnNames != null)
+ return;
+
+ m_ColumnNames = new List();
+
+ DataTable schemaTable = reader.GetSchemaTable();
+ foreach (DataRow row in schemaTable.Rows)
+ {
+ if (row["ColumnName"] != null &&
+ (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
+ m_ColumnNames.Add(row["ColumnName"].ToString());
+ }
+ }
+
+ public T[] Get(string field, string key)
+ {
+ return Get(new string[] { field }, new string[] { key });
+ }
+
+ public T[] Get(string[] fields, string[] keys)
+ {
+ if (fields.Length != keys.Length)
+ return new T[0];
+
+ List terms = new List();
+
+ SqliteCommand cmd = new SqliteCommand();
+
+ for (int i = 0 ; i < fields.Length ; i++)
+ {
+ cmd.Parameters.Add(new SqliteParameter(":" + fields[i], keys[i]));
+ terms.Add("`" + fields[i] + "` = :" + fields[i]);
+ }
+
+ string where = String.Join(" and ", terms.ToArray());
+
+ string query = String.Format("select * from {0} where {1}",
+ m_Realm, where);
+
+ cmd.CommandText = query;
+
+ return DoQuery(cmd);
+ }
+
+ protected T[] DoQuery(SqliteCommand cmd)
+ {
+ IDataReader reader = ExecuteReader(cmd, m_Connection);
+ if (reader == null)
+ return new T[0];
+
+ CheckColumnNames(reader);
+
+ List result = new List();
+
+ while (reader.Read())
+ {
+ T row = new T();
+
+ foreach (string name in m_Fields.Keys)
+ {
+ if (m_Fields[name].GetValue(row) is bool)
+ {
+ int v = Convert.ToInt32(reader[name]);
+ m_Fields[name].SetValue(row, v != 0 ? true : false);
+ }
+ else if (m_Fields[name].GetValue(row) is UUID)
+ {
+ UUID uuid = UUID.Zero;
+
+ UUID.TryParse(reader[name].ToString(), out uuid);
+ m_Fields[name].SetValue(row, uuid);
+ }
+ else if (m_Fields[name].GetValue(row) is int)
+ {
+ int v = Convert.ToInt32(reader[name]);
+ m_Fields[name].SetValue(row, v);
+ }
+ else
+ {
+ m_Fields[name].SetValue(row, reader[name]);
+ }
+ }
+
+ if (m_DataField != null)
+ {
+ Dictionary data =
+ new Dictionary();
+
+ foreach (string col in m_ColumnNames)
+ {
+ data[col] = reader[col].ToString();
+ if (data[col] == null)
+ data[col] = String.Empty;
+ }
+
+ m_DataField.SetValue(row, data);
+ }
+
+ result.Add(row);
+ }
+
+ CloseCommand(cmd);
+
+ return result.ToArray();
+ }
+
+ public T[] Get(string where)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ string query = String.Format("select * from {0} where {1}",
+ m_Realm, where);
+
+ cmd.CommandText = query;
+
+ return DoQuery(cmd);
+ }
+
+ public bool Store(T row)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ string query = "";
+ List names = new List();
+ List values = new List();
+
+ foreach (FieldInfo fi in m_Fields.Values)
+ {
+ names.Add(fi.Name);
+ values.Add(":" + fi.Name);
+ cmd.Parameters.Add(new SqliteParameter(":" + fi.Name, fi.GetValue(row).ToString()));
+ }
+
+ if (m_DataField != null)
+ {
+ Dictionary data =
+ (Dictionary)m_DataField.GetValue(row);
+
+ foreach (KeyValuePair kvp in data)
+ {
+ names.Add(kvp.Key);
+ values.Add(":" + kvp.Key);
+ cmd.Parameters.Add(new SqliteParameter(":" + kvp.Key, kvp.Value));
+ }
+ }
+
+ query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values (" + String.Join(",", values.ToArray()) + ")";
+
+ cmd.CommandText = query;
+
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ return true;
+
+ return false;
+ }
+
+ public bool Delete(string field, string val)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ cmd.CommandText = String.Format("delete from {0} where `{1}` = :{1}", m_Realm, field);
+ cmd.Parameters.Add(new SqliteParameter(field, val));
+
+ if (ExecuteNonQuery(cmd, m_Connection) > 0)
+ return true;
+
+ return false;
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
new file mode 100644
index 0000000000..a5e051726e
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// An Inventory Interface to the SQLite database
+ ///
+ public class SQLiteInventoryStore : SQLiteUtil, IInventoryDataPlugin
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private const string invItemsSelect = "select * from inventoryitems";
+ private const string invFoldersSelect = "select * from inventoryfolders";
+
+ private static SqliteConnection conn;
+ private static DataSet ds;
+ private static SqliteDataAdapter invItemsDa;
+ private static SqliteDataAdapter invFoldersDa;
+
+ private static bool m_Initialized = false;
+
+ public void Initialise()
+ {
+ m_log.Info("[SQLiteInventoryData]: " + Name + " cannot be default-initialized!");
+ throw new PluginNotInitialisedException(Name);
+ }
+
+ ///
+ ///
+ /// - Initialises Inventory interface
+ /// - Loads and initialises a new SQLite connection and maintains it.
+ /// - use default URI if connect string string is empty.
+ ///
+ ///
+ /// connect string
+ public void Initialise(string dbconnect)
+ {
+ if (!m_Initialized)
+ {
+ m_Initialized = true;
+
+ if (dbconnect == string.Empty)
+ {
+ dbconnect = "URI=file:inventoryStore.db,version=3";
+ }
+ m_log.Info("[INVENTORY DB]: Sqlite - connecting: " + dbconnect);
+ conn = new SqliteConnection(dbconnect);
+
+ conn.Open();
+
+ Assembly assem = GetType().Assembly;
+ Migration m = new Migration(conn, assem, "InventoryStore");
+ m.Update();
+
+ SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn);
+ invItemsDa = new SqliteDataAdapter(itemsSelectCmd);
+ // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
+
+ SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn);
+ invFoldersDa = new SqliteDataAdapter(foldersSelectCmd);
+
+ ds = new DataSet();
+
+ ds.Tables.Add(createInventoryFoldersTable());
+ invFoldersDa.Fill(ds.Tables["inventoryfolders"]);
+ setupFoldersCommands(invFoldersDa, conn);
+ m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions");
+
+ ds.Tables.Add(createInventoryItemsTable());
+ invItemsDa.Fill(ds.Tables["inventoryitems"]);
+ setupItemsCommands(invItemsDa, conn);
+ m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions");
+
+ ds.AcceptChanges();
+ }
+ }
+
+ ///
+ /// Closes the inventory interface
+ ///
+ public void Dispose()
+ {
+ if (conn != null)
+ {
+ conn.Close();
+ conn = null;
+ }
+ if (invItemsDa != null)
+ {
+ invItemsDa.Dispose();
+ invItemsDa = null;
+ }
+ if (invFoldersDa != null)
+ {
+ invFoldersDa.Dispose();
+ invFoldersDa = null;
+ }
+ if (ds != null)
+ {
+ ds.Dispose();
+ ds = null;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public InventoryItemBase buildItem(DataRow row)
+ {
+ InventoryItemBase item = new InventoryItemBase();
+ item.ID = new UUID((string) row["UUID"]);
+ item.AssetID = new UUID((string) row["assetID"]);
+ item.AssetType = Convert.ToInt32(row["assetType"]);
+ item.InvType = Convert.ToInt32(row["invType"]);
+ item.Folder = new UUID((string) row["parentFolderID"]);
+ item.Owner = new UUID((string) row["avatarID"]);
+ item.CreatorId = (string)row["creatorsID"];
+ item.Name = (string) row["inventoryName"];
+ item.Description = (string) row["inventoryDescription"];
+
+ item.NextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]);
+ item.CurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]);
+ item.BasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]);
+ item.EveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]);
+ item.GroupPermissions = Convert.ToUInt32(row["inventoryGroupPermissions"]);
+
+ // new fields
+ if (!Convert.IsDBNull(row["salePrice"]))
+ item.SalePrice = Convert.ToInt32(row["salePrice"]);
+
+ if (!Convert.IsDBNull(row["saleType"]))
+ item.SaleType = Convert.ToByte(row["saleType"]);
+
+ if (!Convert.IsDBNull(row["creationDate"]))
+ item.CreationDate = Convert.ToInt32(row["creationDate"]);
+
+ if (!Convert.IsDBNull(row["groupID"]))
+ item.GroupID = new UUID((string)row["groupID"]);
+
+ if (!Convert.IsDBNull(row["groupOwned"]))
+ item.GroupOwned = Convert.ToBoolean(row["groupOwned"]);
+
+ if (!Convert.IsDBNull(row["Flags"]))
+ item.Flags = Convert.ToUInt32(row["Flags"]);
+
+ return item;
+ }
+
+ ///
+ /// Fill a database row with item data
+ ///
+ ///
+ ///
+ private static void fillItemRow(DataRow row, InventoryItemBase item)
+ {
+ row["UUID"] = item.ID.ToString();
+ row["assetID"] = item.AssetID.ToString();
+ row["assetType"] = item.AssetType;
+ row["invType"] = item.InvType;
+ row["parentFolderID"] = item.Folder.ToString();
+ row["avatarID"] = item.Owner.ToString();
+ row["creatorsID"] = item.CreatorId.ToString();
+ row["inventoryName"] = item.Name;
+ row["inventoryDescription"] = item.Description;
+
+ row["inventoryNextPermissions"] = item.NextPermissions;
+ row["inventoryCurrentPermissions"] = item.CurrentPermissions;
+ row["inventoryBasePermissions"] = item.BasePermissions;
+ row["inventoryEveryOnePermissions"] = item.EveryOnePermissions;
+ row["inventoryGroupPermissions"] = item.GroupPermissions;
+
+ // new fields
+ row["salePrice"] = item.SalePrice;
+ row["saleType"] = item.SaleType;
+ row["creationDate"] = item.CreationDate;
+ row["groupID"] = item.GroupID.ToString();
+ row["groupOwned"] = item.GroupOwned;
+ row["flags"] = item.Flags;
+ }
+
+ ///
+ /// Add inventory folder
+ ///
+ /// Folder base
+ /// true=create folder. false=update existing folder
+ /// nasty
+ private void addFolder(InventoryFolderBase folder, bool add)
+ {
+ lock (ds)
+ {
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+ DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
+ if (inventoryRow == null)
+ {
+ if (! add)
+ m_log.ErrorFormat("Interface Misuse: Attempting to Update non-existant inventory folder: {0}", folder.ID);
+
+ inventoryRow = inventoryFolderTable.NewRow();
+ fillFolderRow(inventoryRow, folder);
+ inventoryFolderTable.Rows.Add(inventoryRow);
+ }
+ else
+ {
+ if (add)
+ m_log.ErrorFormat("Interface Misuse: Attempting to Add inventory folder that already exists: {0}", folder.ID);
+
+ fillFolderRow(inventoryRow, folder);
+ }
+
+ invFoldersDa.Update(ds, "inventoryfolders");
+ }
+ }
+
+ ///
+ /// Move an inventory folder
+ ///
+ /// folder base
+ private void moveFolder(InventoryFolderBase folder)
+ {
+ lock (ds)
+ {
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+ DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.ID.ToString());
+ if (inventoryRow == null)
+ {
+ inventoryRow = inventoryFolderTable.NewRow();
+ fillFolderRow(inventoryRow, folder);
+ inventoryFolderTable.Rows.Add(inventoryRow);
+ }
+ else
+ {
+ moveFolderRow(inventoryRow, folder);
+ }
+
+ invFoldersDa.Update(ds, "inventoryfolders");
+ }
+ }
+
+ ///
+ /// add an item in inventory
+ ///
+ /// the item
+ /// true=add item ; false=update existing item
+ private void addItem(InventoryItemBase item, bool add)
+ {
+ lock (ds)
+ {
+ DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+
+ DataRow inventoryRow = inventoryItemTable.Rows.Find(item.ID.ToString());
+ if (inventoryRow == null)
+ {
+ if (!add)
+ m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Update non-existant inventory item: {0}", item.ID);
+
+ inventoryRow = inventoryItemTable.NewRow();
+ fillItemRow(inventoryRow, item);
+ inventoryItemTable.Rows.Add(inventoryRow);
+ }
+ else
+ {
+ if (add)
+ m_log.ErrorFormat("[INVENTORY DB]: Interface Misuse: Attempting to Add inventory item that already exists: {0}", item.ID);
+
+ fillItemRow(inventoryRow, item);
+ }
+
+ invItemsDa.Update(ds, "inventoryitems");
+
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+
+ inventoryRow = inventoryFolderTable.Rows.Find(item.Folder.ToString());
+ if (inventoryRow != null) //MySQL doesn't throw an exception here, so sqlite shouldn't either.
+ inventoryRow["version"] = (int)inventoryRow["version"] + 1;
+
+ invFoldersDa.Update(ds, "inventoryfolders");
+ }
+ }
+
+ ///
+ /// TODO : DataSet commit
+ ///
+ public void Shutdown()
+ {
+ // TODO: DataSet commit
+ }
+
+ ///
+ /// The name of this DB provider
+ ///
+ /// Name of DB provider
+ public string Name
+ {
+ get { return "SQLite Inventory Data Interface"; }
+ }
+
+ ///
+ /// Returns the version of this DB provider
+ ///
+ /// A string containing the DB provider version
+ public string Version
+ {
+ get
+ {
+ Module module = GetType().Module;
+ // string dllName = module.Assembly.ManifestModule.Name;
+ Version dllVersion = module.Assembly.GetName().Version;
+
+
+ return
+ string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
+ dllVersion.Revision);
+ }
+ }
+
+ ///
+ /// Returns a list of inventory items contained within the specified folder
+ ///
+ /// The UUID of the target folder
+ /// A List of InventoryItemBase items
+ public List getInventoryInFolder(UUID folderID)
+ {
+ lock (ds)
+ {
+ List retval = new List();
+ DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+ string selectExp = "parentFolderID = '" + folderID + "'";
+ DataRow[] rows = inventoryItemTable.Select(selectExp);
+ foreach (DataRow row in rows)
+ {
+ retval.Add(buildItem(row));
+ }
+
+ return retval;
+ }
+ }
+
+ ///
+ /// Returns a list of the root folders within a users inventory
+ ///
+ /// The user whos inventory is to be searched
+ /// A list of folder objects
+ public List getUserRootFolders(UUID user)
+ {
+ return new List();
+ }
+
+ // see InventoryItemBase.getUserRootFolder
+ public InventoryFolderBase getUserRootFolder(UUID user)
+ {
+ lock (ds)
+ {
+ List folders = new List();
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+ string selectExp = "agentID = '" + user + "' AND parentID = '" + UUID.Zero + "'";
+ DataRow[] rows = inventoryFolderTable.Select(selectExp);
+ foreach (DataRow row in rows)
+ {
+ folders.Add(buildFolder(row));
+ }
+
+ // There should only ever be one root folder for a user. However, if there's more
+ // than one we'll simply use the first one rather than failing. It would be even
+ // nicer to print some message to this effect, but this feels like it's too low a
+ // to put such a message out, and it's too minor right now to spare the time to
+ // suitably refactor.
+ if (folders.Count > 0)
+ {
+ return folders[0];
+ }
+
+ return null;
+ }
+ }
+
+ ///
+ /// Append a list of all the child folders of a parent folder
+ ///
+ /// list where folders will be appended
+ /// ID of parent
+ protected void getInventoryFolders(ref List folders, UUID parentID)
+ {
+ lock (ds)
+ {
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+ string selectExp = "parentID = '" + parentID + "'";
+ DataRow[] rows = inventoryFolderTable.Select(selectExp);
+ foreach (DataRow row in rows)
+ {
+ folders.Add(buildFolder(row));
+ }
+
+ }
+ }
+
+ ///
+ /// Returns a list of inventory folders contained in the folder 'parentID'
+ ///
+ /// The folder to get subfolders for
+ /// A list of inventory folders
+ public List getInventoryFolders(UUID parentID)
+ {
+ List folders = new List();
+ getInventoryFolders(ref folders, parentID);
+ return folders;
+ }
+
+ ///
+ /// See IInventoryDataPlugin
+ ///
+ ///
+ ///
+ public List getFolderHierarchy(UUID parentID)
+ {
+ /* Note: There are subtle changes between this implementation of getFolderHierarchy and the previous one
+ * - We will only need to hit the database twice instead of n times.
+ * - We assume the database is well-formed - no stranded/dangling folders, all folders in heirarchy owned
+ * by the same person, each user only has 1 inventory heirarchy
+ * - The returned list is not ordered, instead of breadth-first ordered
+ There are basically 2 usage cases for getFolderHeirarchy:
+ 1) Getting the user's entire inventory heirarchy when they log in
+ 2) Finding a subfolder heirarchy to delete when emptying the trash.
+ This implementation will pull all inventory folders from the database, and then prune away any folder that
+ is not part of the requested sub-heirarchy. The theory is that it is cheaper to make 1 request from the
+ database than to make n requests. This pays off only if requested heirarchy is large.
+ By making this choice, we are making the worst case better at the cost of making the best case worse
+ - Francis
+ */
+
+ List folders = new List();
+ DataRow[] folderRows = null, parentRow;
+ InventoryFolderBase parentFolder = null;
+ lock (ds)
+ {
+ /* Fetch the parent folder from the database to determine the agent ID.
+ * Then fetch all inventory folders for that agent from the agent ID.
+ */
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+ string selectExp = "UUID = '" + parentID + "'";
+ parentRow = inventoryFolderTable.Select(selectExp); // Assume at most 1 result
+ if (parentRow.GetLength(0) >= 1) // No result means parent folder does not exist
+ {
+ parentFolder = buildFolder(parentRow[0]);
+ UUID agentID = parentFolder.Owner;
+ selectExp = "agentID = '" + agentID + "'";
+ folderRows = inventoryFolderTable.Select(selectExp);
+ }
+
+ if (folderRows != null && folderRows.GetLength(0) >= 1) // No result means parent folder does not exist
+ { // or has no children
+ /* if we're querying the root folder, just return an unordered list of all folders in the user's
+ * inventory
+ */
+ if (parentFolder.ParentID == UUID.Zero)
+ {
+ foreach (DataRow row in folderRows)
+ {
+ InventoryFolderBase curFolder = buildFolder(row);
+ if (curFolder.ID != parentID) // Return all folders except the parent folder of heirarchy
+ folders.Add(buildFolder(row));
+ }
+ } // If requesting root folder
+ /* else we are querying a non-root folder. We currently have a list of all of the user's folders,
+ * we must construct a list of all folders in the heirarchy below parentID.
+ * Our first step will be to construct a hash table of all folders, indexed by parent ID.
+ * Once we have constructed the hash table, we will do a breadth-first traversal on the tree using the
+ * hash table to find child folders.
+ */
+ else
+ { // Querying a non-root folder
+
+ // Build a hash table of all user's inventory folders, indexed by each folder's parent ID
+ Dictionary> hashtable =
+ new Dictionary>(folderRows.GetLength(0));
+
+ foreach (DataRow row in folderRows)
+ {
+ InventoryFolderBase curFolder = buildFolder(row);
+ if (curFolder.ParentID != UUID.Zero) // Discard root of tree - not needed
+ {
+ if (hashtable.ContainsKey(curFolder.ParentID))
+ {
+ // Current folder already has a sibling - append to sibling list
+ hashtable[curFolder.ParentID].Add(curFolder);
+ }
+ else
+ {
+ List siblingList = new List();
+ siblingList.Add(curFolder);
+ // Current folder has no known (yet) siblings
+ hashtable.Add(curFolder.ParentID, siblingList);
+ }
+ }
+ } // For all inventory folders
+
+ // Note: Could release the ds lock here - we don't access folderRows or the database anymore.
+ // This is somewhat of a moot point as the callers of this function usually lock db anyways.
+
+ if (hashtable.ContainsKey(parentID)) // if requested folder does have children
+ folders.AddRange(hashtable[parentID]);
+
+ // BreadthFirstSearch build inventory tree **Note: folders.Count is *not* static
+ for (int i = 0; i < folders.Count; i++)
+ if (hashtable.ContainsKey(folders[i].ID))
+ folders.AddRange(hashtable[folders[i].ID]);
+
+ } // if requesting a subfolder heirarchy
+ } // if folder parentID exists and has children
+ } // lock ds
+ return folders;
+ }
+
+ ///
+ /// Returns an inventory item by its UUID
+ ///
+ /// The UUID of the item to be returned
+ /// A class containing item information
+ public InventoryItemBase getInventoryItem(UUID item)
+ {
+ lock (ds)
+ {
+ DataRow row = ds.Tables["inventoryitems"].Rows.Find(item.ToString());
+ if (row != null)
+ {
+ return buildItem(row);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ ///
+ /// Returns a specified inventory folder by its UUID
+ ///
+ /// The UUID of the folder to be returned
+ /// A class containing folder information
+ public InventoryFolderBase getInventoryFolder(UUID folder)
+ {
+ // TODO: Deep voodoo here. If you enable this code then
+ // multi region breaks. No idea why, but I figured it was
+ // better to leave multi region at this point. It does mean
+ // that you don't get to see system textures why creating
+ // clothes and the like. :(
+ lock (ds)
+ {
+ DataRow row = ds.Tables["inventoryfolders"].Rows.Find(folder.ToString());
+ if (row != null)
+ {
+ return buildFolder(row);
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ ///
+ /// Creates a new inventory item based on item
+ ///
+ /// The item to be created
+ public void addInventoryItem(InventoryItemBase item)
+ {
+ addItem(item, true);
+ }
+
+ ///
+ /// Updates an inventory item with item (updates based on ID)
+ ///
+ /// The updated item
+ public void updateInventoryItem(InventoryItemBase item)
+ {
+ addItem(item, false);
+ }
+
+ ///
+ /// Delete an inventory item
+ ///
+ /// The item UUID
+ public void deleteInventoryItem(UUID itemID)
+ {
+ lock (ds)
+ {
+ DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+
+ DataRow inventoryRow = inventoryItemTable.Rows.Find(itemID.ToString());
+ if (inventoryRow != null)
+ {
+ inventoryRow.Delete();
+ }
+
+ invItemsDa.Update(ds, "inventoryitems");
+ }
+ }
+
+ public InventoryItemBase queryInventoryItem(UUID itemID)
+ {
+ return getInventoryItem(itemID);
+ }
+
+ public InventoryFolderBase queryInventoryFolder(UUID folderID)
+ {
+ return getInventoryFolder(folderID);
+ }
+
+ ///
+ /// Delete all items in the specified folder
+ ///
+ /// id of the folder, whose item content should be deleted
+ /// this is horribly inefficient, but I don't want to ruin the overall structure of this implementation
+ private void deleteItemsInFolder(UUID folderId)
+ {
+ List items = getInventoryInFolder(folderId);
+
+ foreach (InventoryItemBase i in items)
+ deleteInventoryItem(i.ID);
+ }
+
+ ///
+ /// Adds a new folder specified by folder
+ ///
+ /// The inventory folder
+ public void addInventoryFolder(InventoryFolderBase folder)
+ {
+ addFolder(folder, true);
+ }
+
+ ///
+ /// Updates a folder based on its ID with folder
+ ///
+ /// The inventory folder
+ public void updateInventoryFolder(InventoryFolderBase folder)
+ {
+ addFolder(folder, false);
+ }
+
+ ///
+ /// Moves a folder based on its ID with folder
+ ///
+ /// The inventory folder
+ public void moveInventoryFolder(InventoryFolderBase folder)
+ {
+ moveFolder(folder);
+ }
+
+ ///
+ /// Delete a folder
+ ///
+ ///
+ /// This will clean-up any child folders and child items as well
+ ///
+ /// the folder UUID
+ public void deleteInventoryFolder(UUID folderID)
+ {
+ lock (ds)
+ {
+ List subFolders = getFolderHierarchy(folderID);
+
+ DataTable inventoryFolderTable = ds.Tables["inventoryfolders"];
+ DataRow inventoryRow;
+
+ //Delete all sub-folders
+ foreach (InventoryFolderBase f in subFolders)
+ {
+ inventoryRow = inventoryFolderTable.Rows.Find(f.ID.ToString());
+ if (inventoryRow != null)
+ {
+ deleteItemsInFolder(f.ID);
+ inventoryRow.Delete();
+ }
+ }
+
+ //Delete the actual row
+ inventoryRow = inventoryFolderTable.Rows.Find(folderID.ToString());
+ if (inventoryRow != null)
+ {
+ deleteItemsInFolder(folderID);
+ inventoryRow.Delete();
+ }
+
+ invFoldersDa.Update(ds, "inventoryfolders");
+ }
+ }
+
+ /***********************************************************************
+ *
+ * Data Table definitions
+ *
+ **********************************************************************/
+
+ ///
+ /// Create the "inventoryitems" table
+ ///
+ private static DataTable createInventoryItemsTable()
+ {
+ DataTable inv = new DataTable("inventoryitems");
+
+ createCol(inv, "UUID", typeof (String)); //inventoryID
+ createCol(inv, "assetID", typeof (String));
+ createCol(inv, "assetType", typeof (Int32));
+ createCol(inv, "invType", typeof (Int32));
+ createCol(inv, "parentFolderID", typeof (String));
+ createCol(inv, "avatarID", typeof (String));
+ createCol(inv, "creatorsID", typeof (String));
+
+ createCol(inv, "inventoryName", typeof (String));
+ createCol(inv, "inventoryDescription", typeof (String));
+ // permissions
+ createCol(inv, "inventoryNextPermissions", typeof (Int32));
+ createCol(inv, "inventoryCurrentPermissions", typeof (Int32));
+ createCol(inv, "inventoryBasePermissions", typeof (Int32));
+ createCol(inv, "inventoryEveryOnePermissions", typeof (Int32));
+ createCol(inv, "inventoryGroupPermissions", typeof (Int32));
+
+ // sale info
+ createCol(inv, "salePrice", typeof(Int32));
+ createCol(inv, "saleType", typeof(Byte));
+
+ // creation date
+ createCol(inv, "creationDate", typeof(Int32));
+
+ // group info
+ createCol(inv, "groupID", typeof(String));
+ createCol(inv, "groupOwned", typeof(Boolean));
+
+ // Flags
+ createCol(inv, "flags", typeof(UInt32));
+
+ inv.PrimaryKey = new DataColumn[] { inv.Columns["UUID"] };
+ return inv;
+ }
+
+ ///
+ /// Creates the "inventoryfolders" table
+ ///
+ ///
+ private static DataTable createInventoryFoldersTable()
+ {
+ DataTable fol = new DataTable("inventoryfolders");
+
+ createCol(fol, "UUID", typeof (String)); //folderID
+ createCol(fol, "name", typeof (String));
+ createCol(fol, "agentID", typeof (String));
+ createCol(fol, "parentID", typeof (String));
+ createCol(fol, "type", typeof (Int32));
+ createCol(fol, "version", typeof (Int32));
+
+ fol.PrimaryKey = new DataColumn[] {fol.Columns["UUID"]};
+ return fol;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ lock (ds)
+ {
+ da.InsertCommand = createInsertCommand("inventoryitems", ds.Tables["inventoryitems"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", ds.Tables["inventoryitems"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID");
+ delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+ delete.Connection = conn;
+ da.DeleteCommand = delete;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ lock (ds)
+ {
+ da.InsertCommand = createInsertCommand("inventoryfolders", ds.Tables["inventoryfolders"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", ds.Tables["inventoryfolders"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID");
+ delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+ delete.Connection = conn;
+ da.DeleteCommand = delete;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static InventoryFolderBase buildFolder(DataRow row)
+ {
+ InventoryFolderBase folder = new InventoryFolderBase();
+ folder.ID = new UUID((string) row["UUID"]);
+ folder.Name = (string) row["name"];
+ folder.Owner = new UUID((string) row["agentID"]);
+ folder.ParentID = new UUID((string) row["parentID"]);
+ folder.Type = Convert.ToInt16(row["type"]);
+ folder.Version = Convert.ToUInt16(row["version"]);
+ return folder;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillFolderRow(DataRow row, InventoryFolderBase folder)
+ {
+ row["UUID"] = folder.ID.ToString();
+ row["name"] = folder.Name;
+ row["agentID"] = folder.Owner.ToString();
+ row["parentID"] = folder.ParentID.ToString();
+ row["type"] = folder.Type;
+ row["version"] = folder.Version;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void moveFolderRow(DataRow row, InventoryFolderBase folder)
+ {
+ row["UUID"] = folder.ID.ToString();
+ row["parentID"] = folder.ParentID.ToString();
+ }
+
+ public List fetchActiveGestures (UUID avatarID)
+ {
+ lock (ds)
+ {
+ List items = new List();
+
+ DataTable inventoryItemTable = ds.Tables["inventoryitems"];
+ string selectExp
+ = "avatarID = '" + avatarID + "' AND assetType = " + (int)AssetType.Gesture + " AND flags = 1";
+ //m_log.DebugFormat("[SQL]: sql = " + selectExp);
+ DataRow[] rows = inventoryItemTable.Select(selectExp);
+ foreach (DataRow row in rows)
+ {
+ items.Add(buildItem(row));
+ }
+ return items;
+ }
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
new file mode 100644
index 0000000000..d2ba9ae298
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs
@@ -0,0 +1,2264 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Reflection;
+using log4net;
+using Mono.Data.SqliteClient;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// A RegionData Interface to the SQLite database
+ ///
+ public class SQLiteRegionData : IRegionDataStore
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private const string primSelect = "select * from prims";
+ private const string shapeSelect = "select * from primshapes";
+ private const string itemsSelect = "select * from primitems";
+ private const string terrainSelect = "select * from terrain limit 1";
+ private const string landSelect = "select * from land";
+ private const string landAccessListSelect = "select distinct * from landaccesslist";
+ private const string regionbanListSelect = "select * from regionban";
+ private const string regionSettingsSelect = "select * from regionsettings";
+
+ private DataSet ds;
+ private SqliteDataAdapter primDa;
+ private SqliteDataAdapter shapeDa;
+ private SqliteDataAdapter itemsDa;
+ private SqliteDataAdapter terrainDa;
+ private SqliteDataAdapter landDa;
+ private SqliteDataAdapter landAccessListDa;
+ private SqliteDataAdapter regionSettingsDa;
+
+ private SqliteConnection m_conn;
+
+ private String m_connectionString;
+
+ // Temporary attribute while this is experimental
+
+ /***********************************************************************
+ *
+ * Public Interface Functions
+ *
+ **********************************************************************/
+
+ ///
+ /// See IRegionDataStore
+ ///
+ /// - Initialises RegionData Interface
+ /// - Loads and initialises a new SQLite connection and maintains it.
+ ///
+ ///
+ /// the connection string
+ public void Initialise(string connectionString)
+ {
+ m_connectionString = connectionString;
+
+ ds = new DataSet();
+
+ m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString);
+ m_conn = new SqliteConnection(m_connectionString);
+ m_conn.Open();
+
+
+
+ SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn);
+ primDa = new SqliteDataAdapter(primSelectCmd);
+ // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa);
+
+ SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn);
+ shapeDa = new SqliteDataAdapter(shapeSelectCmd);
+ // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa);
+
+ SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn);
+ itemsDa = new SqliteDataAdapter(itemsSelectCmd);
+
+ SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn);
+ terrainDa = new SqliteDataAdapter(terrainSelectCmd);
+
+ SqliteCommand landSelectCmd = new SqliteCommand(landSelect, m_conn);
+ landDa = new SqliteDataAdapter(landSelectCmd);
+
+ SqliteCommand landAccessListSelectCmd = new SqliteCommand(landAccessListSelect, m_conn);
+ landAccessListDa = new SqliteDataAdapter(landAccessListSelectCmd);
+
+ SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
+ regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
+ // This actually does the roll forward assembly stuff
+ Assembly assem = GetType().Assembly;
+ Migration m = new Migration(m_conn, assem, "RegionStore");
+ m.Update();
+
+ lock (ds)
+ {
+ ds.Tables.Add(createPrimTable());
+ setupPrimCommands(primDa, m_conn);
+ primDa.Fill(ds.Tables["prims"]);
+
+ ds.Tables.Add(createShapeTable());
+ setupShapeCommands(shapeDa, m_conn);
+
+ ds.Tables.Add(createItemsTable());
+ setupItemsCommands(itemsDa, m_conn);
+ itemsDa.Fill(ds.Tables["primitems"]);
+
+ ds.Tables.Add(createTerrainTable());
+ setupTerrainCommands(terrainDa, m_conn);
+
+ ds.Tables.Add(createLandTable());
+ setupLandCommands(landDa, m_conn);
+
+ ds.Tables.Add(createLandAccessListTable());
+ setupLandAccessCommands(landAccessListDa, m_conn);
+
+ ds.Tables.Add(createRegionSettingsTable());
+
+ setupRegionSettingsCommands(regionSettingsDa, m_conn);
+
+ // WORKAROUND: This is a work around for sqlite on
+ // windows, which gets really unhappy with blob columns
+ // that have no sample data in them. At some point we
+ // need to actually find a proper way to handle this.
+ try
+ {
+ shapeDa.Fill(ds.Tables["primshapes"]);
+ }
+ catch (Exception)
+ {
+ m_log.Info("[REGION DB]: Caught fill error on primshapes table");
+ }
+
+ try
+ {
+ terrainDa.Fill(ds.Tables["terrain"]);
+ }
+ catch (Exception)
+ {
+ m_log.Info("[REGION DB]: Caught fill error on terrain table");
+ }
+
+ try
+ {
+ landDa.Fill(ds.Tables["land"]);
+ }
+ catch (Exception)
+ {
+ m_log.Info("[REGION DB]: Caught fill error on land table");
+ }
+
+ try
+ {
+ landAccessListDa.Fill(ds.Tables["landaccesslist"]);
+ }
+ catch (Exception)
+ {
+ m_log.Info("[REGION DB]: Caught fill error on landaccesslist table");
+ }
+
+ try
+ {
+ regionSettingsDa.Fill(ds.Tables["regionsettings"]);
+ }
+ catch (Exception)
+ {
+ m_log.Info("[REGION DB]: Caught fill error on regionsettings table");
+ }
+ return;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (m_conn != null)
+ {
+ m_conn.Close();
+ m_conn = null;
+ }
+ if (ds != null)
+ {
+ ds.Dispose();
+ ds = null;
+ }
+ if (primDa != null)
+ {
+ primDa.Dispose();
+ primDa = null;
+ }
+ if (shapeDa != null)
+ {
+ shapeDa.Dispose();
+ shapeDa = null;
+ }
+ if (itemsDa != null)
+ {
+ itemsDa.Dispose();
+ itemsDa = null;
+ }
+ if (terrainDa != null)
+ {
+ terrainDa.Dispose();
+ terrainDa = null;
+ }
+ if (landDa != null)
+ {
+ landDa.Dispose();
+ landDa = null;
+ }
+ if (landAccessListDa != null)
+ {
+ landAccessListDa.Dispose();
+ landAccessListDa = null;
+ }
+ if (regionSettingsDa != null)
+ {
+ regionSettingsDa.Dispose();
+ regionSettingsDa = null;
+ }
+ }
+
+ public void StoreRegionSettings(RegionSettings rs)
+ {
+ lock (ds)
+ {
+ DataTable regionsettings = ds.Tables["regionsettings"];
+
+ DataRow settingsRow = regionsettings.Rows.Find(rs.RegionUUID.ToString());
+ if (settingsRow == null)
+ {
+ settingsRow = regionsettings.NewRow();
+ fillRegionSettingsRow(settingsRow, rs);
+ regionsettings.Rows.Add(settingsRow);
+ }
+ else
+ {
+ fillRegionSettingsRow(settingsRow, rs);
+ }
+
+ Commit();
+ }
+ }
+ public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
+ {
+ //This connector doesn't support the windlight module yet
+ //Return default LL windlight settings
+ return new RegionLightShareData();
+ }
+ public void StoreRegionWindlightSettings(RegionLightShareData wl)
+ {
+ //This connector doesn't support the windlight module yet
+ }
+ public RegionSettings LoadRegionSettings(UUID regionUUID)
+ {
+ lock (ds)
+ {
+ DataTable regionsettings = ds.Tables["regionsettings"];
+
+ string searchExp = "regionUUID = '" + regionUUID.ToString() + "'";
+ DataRow[] rawsettings = regionsettings.Select(searchExp);
+ if (rawsettings.Length == 0)
+ {
+ RegionSettings rs = new RegionSettings();
+ rs.RegionUUID = regionUUID;
+ rs.OnSave += StoreRegionSettings;
+
+ StoreRegionSettings(rs);
+
+ return rs;
+ }
+ DataRow row = rawsettings[0];
+
+ RegionSettings newSettings = buildRegionSettings(row);
+ newSettings.OnSave += StoreRegionSettings;
+
+ return newSettings;
+ }
+ }
+
+ ///
+ /// Adds an object into region storage
+ ///
+ /// the object
+ /// the region UUID
+ public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
+ {
+ uint flags = obj.RootPart.GetEffectiveObjectFlags();
+
+ // Eligibility check
+ //
+ if ((flags & (uint)PrimFlags.Temporary) != 0)
+ return;
+ if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
+ return;
+
+ lock (ds)
+ {
+ foreach (SceneObjectPart prim in obj.Children.Values)
+ {
+// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID);
+ addPrim(prim, obj.UUID, regionUUID);
+ }
+ }
+
+ Commit();
+ // m_log.Info("[Dump of prims]: " + ds.GetXml());
+ }
+
+ ///
+ /// Removes an object from region storage
+ ///
+ /// the object
+ /// the region UUID
+ public void RemoveObject(UUID obj, UUID regionUUID)
+ {
+ // m_log.InfoFormat("[REGION DB]: Removing obj: {0} from region: {1}", obj.Guid, regionUUID);
+
+ DataTable prims = ds.Tables["prims"];
+ DataTable shapes = ds.Tables["primshapes"];
+
+ string selectExp = "SceneGroupID = '" + obj + "' and RegionUUID = '" + regionUUID + "'";
+ lock (ds)
+ {
+ DataRow[] primRows = prims.Select(selectExp);
+ foreach (DataRow row in primRows)
+ {
+ // Remove shape rows
+ UUID uuid = new UUID((string) row["UUID"]);
+ DataRow shapeRow = shapes.Rows.Find(uuid.ToString());
+ if (shapeRow != null)
+ {
+ shapeRow.Delete();
+ }
+
+ RemoveItems(uuid);
+
+ // Remove prim row
+ row.Delete();
+ }
+ }
+
+ Commit();
+ }
+
+ ///
+ /// Remove all persisted items of the given prim.
+ /// The caller must acquire the necessrary synchronization locks and commit or rollback changes.
+ ///
+ /// The item UUID
+ private void RemoveItems(UUID uuid)
+ {
+ DataTable items = ds.Tables["primitems"];
+
+ String sql = String.Format("primID = '{0}'", uuid);
+ DataRow[] itemRows = items.Select(sql);
+
+ foreach (DataRow itemRow in itemRows)
+ {
+ itemRow.Delete();
+ }
+ }
+
+ ///
+ /// Load persisted objects from region storage.
+ ///
+ /// The region UUID
+ /// List of loaded groups
+ public List LoadObjects(UUID regionUUID)
+ {
+ Dictionary createdObjects = new Dictionary();
+
+ List retvals = new List();
+
+ DataTable prims = ds.Tables["prims"];
+ DataTable shapes = ds.Tables["primshapes"];
+
+ string byRegion = "RegionUUID = '" + regionUUID + "'";
+
+ lock (ds)
+ {
+ DataRow[] primsForRegion = prims.Select(byRegion);
+ m_log.Info("[REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID);
+
+ // First, create all groups
+ foreach (DataRow primRow in primsForRegion)
+ {
+ try
+ {
+ SceneObjectPart prim = null;
+
+ string uuid = (string) primRow["UUID"];
+ string objID = (string) primRow["SceneGroupID"];
+
+ if (uuid == objID) //is new SceneObjectGroup ?
+ {
+ prim = buildPrim(primRow);
+ DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+ if (shapeRow != null)
+ {
+ prim.Shape = buildShape(shapeRow);
+ }
+ else
+ {
+ m_log.Info(
+ "[REGION DB]: No shape found for prim in storage, so setting default box shape");
+ prim.Shape = PrimitiveBaseShape.Default;
+ }
+
+ SceneObjectGroup group = new SceneObjectGroup(prim);
+ createdObjects.Add(group.UUID, group);
+ retvals.Add(group);
+ LoadItems(prim);
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[REGION DB]: Failed create prim object in new group, exception and data follows");
+ m_log.Info("[REGION DB]: " + e.ToString());
+ foreach (DataColumn col in prims.Columns)
+ {
+ m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
+ }
+ }
+ }
+
+ // Now fill the groups with part data
+ foreach (DataRow primRow in primsForRegion)
+ {
+ try
+ {
+ SceneObjectPart prim = null;
+
+ string uuid = (string) primRow["UUID"];
+ string objID = (string) primRow["SceneGroupID"];
+ if (uuid != objID) //is new SceneObjectGroup ?
+ {
+ prim = buildPrim(primRow);
+ DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+ if (shapeRow != null)
+ {
+ prim.Shape = buildShape(shapeRow);
+ }
+ else
+ {
+ m_log.Warn(
+ "[REGION DB]: No shape found for prim in storage, so setting default box shape");
+ prim.Shape = PrimitiveBaseShape.Default;
+ }
+
+ createdObjects[new UUID(objID)].AddPart(prim);
+ LoadItems(prim);
+ }
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[REGION DB]: Failed create prim object in group, exception and data follows");
+ m_log.Info("[REGION DB]: " + e.ToString());
+ foreach (DataColumn col in prims.Columns)
+ {
+ m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]);
+ }
+ }
+ }
+ }
+ return retvals;
+ }
+
+ ///
+ /// Load in a prim's persisted inventory.
+ ///
+ /// the prim
+ private void LoadItems(SceneObjectPart prim)
+ {
+ //m_log.DebugFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID);
+
+ DataTable dbItems = ds.Tables["primitems"];
+ String sql = String.Format("primID = '{0}'", prim.UUID.ToString());
+ DataRow[] dbItemRows = dbItems.Select(sql);
+ IList inventory = new List();
+
+ foreach (DataRow row in dbItemRows)
+ {
+ TaskInventoryItem item = buildItem(row);
+ inventory.Add(item);
+
+ //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID);
+ }
+
+ prim.Inventory.RestoreInventoryItems(inventory);
+ }
+
+ ///
+ /// Store a terrain revision in region storage
+ ///
+ /// terrain heightfield
+ /// region UUID
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ lock (ds)
+ {
+ int revision = Util.UnixTimeSinceEpoch();
+
+ // This is added to get rid of the infinitely growing
+ // terrain databases which negatively impact on SQLite
+ // over time. Before reenabling this feature there
+ // needs to be a limitter put on the number of
+ // revisions in the database, as this old
+ // implementation is a DOS attack waiting to happen.
+
+ using (
+ SqliteCommand cmd =
+ new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
+ m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
+ cmd.ExecuteNonQuery();
+ }
+
+ // the following is an work around for .NET. The perf
+ // issues associated with it aren't as bad as you think.
+ m_log.Info("[REGION DB]: Storing terrain revision r" + revision.ToString());
+ String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
+ " values(:RegionUUID, :Revision, :Heightfield)";
+
+ using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
+ cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
+ cmd.ExecuteNonQuery();
+ }
+ }
+ }
+
+ ///
+ /// Load the latest terrain revision from region storage
+ ///
+ /// the region UUID
+ /// Heightfield data
+ public double[,] LoadTerrain(UUID regionID)
+ {
+ lock (ds)
+ {
+ double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
+ terret.Initialize();
+
+ String sql = "select RegionUUID, Revision, Heightfield from terrain" +
+ " where RegionUUID=:RegionUUID order by Revision desc";
+
+ using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
+ {
+ cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
+
+ using (IDataReader row = cmd.ExecuteReader())
+ {
+ int rev = 0;
+ if (row.Read())
+ {
+ // TODO: put this into a function
+ using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
+ {
+ using (BinaryReader br = new BinaryReader(str))
+ {
+ for (int x = 0; x < (int)Constants.RegionSize; x++)
+ {
+ for (int y = 0; y < (int)Constants.RegionSize; y++)
+ {
+ terret[x, y] = br.ReadDouble();
+ }
+ }
+ }
+ }
+ rev = (int) row["Revision"];
+ }
+ else
+ {
+ m_log.Info("[REGION DB]: No terrain found for region");
+ return null;
+ }
+
+ m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString());
+ }
+ }
+ return terret;
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void RemoveLandObject(UUID globalID)
+ {
+ lock (ds)
+ {
+ // Can't use blanket SQL statements when using SqlAdapters unless you re-read the data into the adapter
+ // after you're done.
+ // replaced below code with the SqliteAdapter version.
+ //using (SqliteCommand cmd = new SqliteCommand("delete from land where UUID=:UUID", m_conn))
+ //{
+ // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
+ // cmd.ExecuteNonQuery();
+ //}
+
+ //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:UUID", m_conn))
+ //{
+ // cmd.Parameters.Add(new SqliteParameter(":UUID", globalID.ToString()));
+ // cmd.ExecuteNonQuery();
+ //}
+
+ DataTable land = ds.Tables["land"];
+ DataTable landaccesslist = ds.Tables["landaccesslist"];
+ DataRow landRow = land.Rows.Find(globalID.ToString());
+ if (landRow != null)
+ {
+ land.Rows.Remove(landRow);
+ }
+ List rowsToDelete = new List();
+ foreach (DataRow rowToCheck in landaccesslist.Rows)
+ {
+ if (rowToCheck["LandUUID"].ToString() == globalID.ToString())
+ rowsToDelete.Add(rowToCheck);
+ }
+ for (int iter = 0; iter < rowsToDelete.Count; iter++)
+ {
+ landaccesslist.Rows.Remove(rowsToDelete[iter]);
+ }
+
+
+ }
+ Commit();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void StoreLandObject(ILandObject parcel)
+ {
+ lock (ds)
+ {
+ DataTable land = ds.Tables["land"];
+ DataTable landaccesslist = ds.Tables["landaccesslist"];
+
+ DataRow landRow = land.Rows.Find(parcel.LandData.GlobalID.ToString());
+ if (landRow == null)
+ {
+ landRow = land.NewRow();
+ fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
+ land.Rows.Add(landRow);
+ }
+ else
+ {
+ fillLandRow(landRow, parcel.LandData, parcel.RegionUUID);
+ }
+
+ // I know this caused someone issues before, but OpenSim is unusable if we leave this stuff around
+ //using (SqliteCommand cmd = new SqliteCommand("delete from landaccesslist where LandUUID=:LandUUID", m_conn))
+ //{
+ // cmd.Parameters.Add(new SqliteParameter(":LandUUID", parcel.LandData.GlobalID.ToString()));
+ // cmd.ExecuteNonQuery();
+
+// }
+
+ // This is the slower.. but more appropriate thing to do
+
+ // We can't modify the table with direct queries before calling Commit() and re-filling them.
+ List rowsToDelete = new List();
+ foreach (DataRow rowToCheck in landaccesslist.Rows)
+ {
+ if (rowToCheck["LandUUID"].ToString() == parcel.LandData.GlobalID.ToString())
+ rowsToDelete.Add(rowToCheck);
+ }
+ for (int iter = 0; iter < rowsToDelete.Count; iter++)
+ {
+ landaccesslist.Rows.Remove(rowsToDelete[iter]);
+ }
+ rowsToDelete.Clear();
+ foreach (ParcelManager.ParcelAccessEntry entry in parcel.LandData.ParcelAccessList)
+ {
+ DataRow newAccessRow = landaccesslist.NewRow();
+ fillLandAccessRow(newAccessRow, entry, parcel.LandData.GlobalID);
+ landaccesslist.Rows.Add(newAccessRow);
+ }
+ }
+
+ Commit();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List LoadLandObjects(UUID regionUUID)
+ {
+ List landDataForRegion = new List();
+ lock (ds)
+ {
+ DataTable land = ds.Tables["land"];
+ DataTable landaccesslist = ds.Tables["landaccesslist"];
+ string searchExp = "RegionUUID = '" + regionUUID + "'";
+ DataRow[] rawDataForRegion = land.Select(searchExp);
+ foreach (DataRow rawDataLand in rawDataForRegion)
+ {
+ LandData newLand = buildLandData(rawDataLand);
+ string accessListSearchExp = "LandUUID = '" + newLand.GlobalID + "'";
+ DataRow[] rawDataForLandAccessList = landaccesslist.Select(accessListSearchExp);
+ foreach (DataRow rawDataLandAccess in rawDataForLandAccessList)
+ {
+ newLand.ParcelAccessList.Add(buildLandAccessData(rawDataLandAccess));
+ }
+
+ landDataForRegion.Add(newLand);
+ }
+ }
+ return landDataForRegion;
+ }
+
+ ///
+ ///
+ ///
+ public void Commit()
+ {
+ lock (ds)
+ {
+ primDa.Update(ds, "prims");
+ shapeDa.Update(ds, "primshapes");
+
+ itemsDa.Update(ds, "primitems");
+
+ terrainDa.Update(ds, "terrain");
+ landDa.Update(ds, "land");
+ landAccessListDa.Update(ds, "landaccesslist");
+ try
+ {
+ regionSettingsDa.Update(ds, "regionsettings");
+ }
+ catch (SqliteExecutionException SqlEx)
+ {
+ if (SqlEx.Message.Contains("logic error"))
+ {
+ throw new Exception(
+ "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!",
+ SqlEx);
+ }
+ else
+ {
+ throw SqlEx;
+ }
+ }
+ ds.AcceptChanges();
+ }
+ }
+
+ ///
+ /// See
+ ///
+ public void Shutdown()
+ {
+ Commit();
+ }
+
+ /***********************************************************************
+ *
+ * Database Definition Functions
+ *
+ * This should be db agnostic as we define them in ADO.NET terms
+ *
+ **********************************************************************/
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void createCol(DataTable dt, string name, Type type)
+ {
+ DataColumn col = new DataColumn(name, type);
+ dt.Columns.Add(col);
+ }
+
+ ///
+ /// Creates the "terrain" table
+ ///
+ /// terrain table DataTable
+ private static DataTable createTerrainTable()
+ {
+ DataTable terrain = new DataTable("terrain");
+
+ createCol(terrain, "RegionUUID", typeof (String));
+ createCol(terrain, "Revision", typeof (Int32));
+ createCol(terrain, "Heightfield", typeof (Byte[]));
+
+ return terrain;
+ }
+
+ ///
+ /// Creates the "prims" table
+ ///
+ /// prim table DataTable
+ private static DataTable createPrimTable()
+ {
+ DataTable prims = new DataTable("prims");
+
+ createCol(prims, "UUID", typeof (String));
+ createCol(prims, "RegionUUID", typeof (String));
+ createCol(prims, "CreationDate", typeof (Int32));
+ createCol(prims, "Name", typeof (String));
+ createCol(prims, "SceneGroupID", typeof (String));
+ // various text fields
+ createCol(prims, "Text", typeof (String));
+ createCol(prims, "ColorR", typeof (Int32));
+ createCol(prims, "ColorG", typeof (Int32));
+ createCol(prims, "ColorB", typeof (Int32));
+ createCol(prims, "ColorA", typeof (Int32));
+ createCol(prims, "Description", typeof (String));
+ createCol(prims, "SitName", typeof (String));
+ createCol(prims, "TouchName", typeof (String));
+ // permissions
+ createCol(prims, "ObjectFlags", typeof (Int32));
+ createCol(prims, "CreatorID", typeof (String));
+ createCol(prims, "OwnerID", typeof (String));
+ createCol(prims, "GroupID", typeof (String));
+ createCol(prims, "LastOwnerID", typeof (String));
+ createCol(prims, "OwnerMask", typeof (Int32));
+ createCol(prims, "NextOwnerMask", typeof (Int32));
+ createCol(prims, "GroupMask", typeof (Int32));
+ createCol(prims, "EveryoneMask", typeof (Int32));
+ createCol(prims, "BaseMask", typeof (Int32));
+ // vectors
+ createCol(prims, "PositionX", typeof (Double));
+ createCol(prims, "PositionY", typeof (Double));
+ createCol(prims, "PositionZ", typeof (Double));
+ createCol(prims, "GroupPositionX", typeof (Double));
+ createCol(prims, "GroupPositionY", typeof (Double));
+ createCol(prims, "GroupPositionZ", typeof (Double));
+ createCol(prims, "VelocityX", typeof (Double));
+ createCol(prims, "VelocityY", typeof (Double));
+ createCol(prims, "VelocityZ", typeof (Double));
+ createCol(prims, "AngularVelocityX", typeof (Double));
+ createCol(prims, "AngularVelocityY", typeof (Double));
+ createCol(prims, "AngularVelocityZ", typeof (Double));
+ createCol(prims, "AccelerationX", typeof (Double));
+ createCol(prims, "AccelerationY", typeof (Double));
+ createCol(prims, "AccelerationZ", typeof (Double));
+ // quaternions
+ createCol(prims, "RotationX", typeof (Double));
+ createCol(prims, "RotationY", typeof (Double));
+ createCol(prims, "RotationZ", typeof (Double));
+ createCol(prims, "RotationW", typeof (Double));
+
+ // sit target
+ createCol(prims, "SitTargetOffsetX", typeof (Double));
+ createCol(prims, "SitTargetOffsetY", typeof (Double));
+ createCol(prims, "SitTargetOffsetZ", typeof (Double));
+
+ createCol(prims, "SitTargetOrientW", typeof (Double));
+ createCol(prims, "SitTargetOrientX", typeof (Double));
+ createCol(prims, "SitTargetOrientY", typeof (Double));
+ createCol(prims, "SitTargetOrientZ", typeof (Double));
+
+ createCol(prims, "PayPrice", typeof(Int32));
+ createCol(prims, "PayButton1", typeof(Int32));
+ createCol(prims, "PayButton2", typeof(Int32));
+ createCol(prims, "PayButton3", typeof(Int32));
+ createCol(prims, "PayButton4", typeof(Int32));
+
+ createCol(prims, "LoopedSound", typeof(String));
+ createCol(prims, "LoopedSoundGain", typeof(Double));
+ createCol(prims, "TextureAnimation", typeof(String));
+ createCol(prims, "ParticleSystem", typeof(String));
+
+ createCol(prims, "OmegaX", typeof(Double));
+ createCol(prims, "OmegaY", typeof(Double));
+ createCol(prims, "OmegaZ", typeof(Double));
+
+ createCol(prims, "CameraEyeOffsetX", typeof(Double));
+ createCol(prims, "CameraEyeOffsetY", typeof(Double));
+ createCol(prims, "CameraEyeOffsetZ", typeof(Double));
+
+ createCol(prims, "CameraAtOffsetX", typeof(Double));
+ createCol(prims, "CameraAtOffsetY", typeof(Double));
+ createCol(prims, "CameraAtOffsetZ", typeof(Double));
+
+ createCol(prims, "ForceMouselook", typeof(Int16));
+
+ createCol(prims, "ScriptAccessPin", typeof(Int32));
+
+ createCol(prims, "AllowedDrop", typeof(Int16));
+ createCol(prims, "DieAtEdge", typeof(Int16));
+
+ createCol(prims, "SalePrice", typeof(Int32));
+ createCol(prims, "SaleType", typeof(Int16));
+
+ // click action
+ createCol(prims, "ClickAction", typeof (Byte));
+
+ createCol(prims, "Material", typeof(Byte));
+
+ createCol(prims, "CollisionSound", typeof(String));
+ createCol(prims, "CollisionSoundVolume", typeof(Double));
+
+ createCol(prims, "VolumeDetect", typeof(Int16));
+
+ // Add in contraints
+ prims.PrimaryKey = new DataColumn[] {prims.Columns["UUID"]};
+
+ return prims;
+ }
+
+ ///
+ /// Creates "primshapes" table
+ ///
+ /// shape table DataTable
+ private static DataTable createShapeTable()
+ {
+ DataTable shapes = new DataTable("primshapes");
+ createCol(shapes, "UUID", typeof (String));
+ // shape is an enum
+ createCol(shapes, "Shape", typeof (Int32));
+ // vectors
+ createCol(shapes, "ScaleX", typeof (Double));
+ createCol(shapes, "ScaleY", typeof (Double));
+ createCol(shapes, "ScaleZ", typeof (Double));
+ // paths
+ createCol(shapes, "PCode", typeof (Int32));
+ createCol(shapes, "PathBegin", typeof (Int32));
+ createCol(shapes, "PathEnd", typeof (Int32));
+ createCol(shapes, "PathScaleX", typeof (Int32));
+ createCol(shapes, "PathScaleY", typeof (Int32));
+ createCol(shapes, "PathShearX", typeof (Int32));
+ createCol(shapes, "PathShearY", typeof (Int32));
+ createCol(shapes, "PathSkew", typeof (Int32));
+ createCol(shapes, "PathCurve", typeof (Int32));
+ createCol(shapes, "PathRadiusOffset", typeof (Int32));
+ createCol(shapes, "PathRevolutions", typeof (Int32));
+ createCol(shapes, "PathTaperX", typeof (Int32));
+ createCol(shapes, "PathTaperY", typeof (Int32));
+ createCol(shapes, "PathTwist", typeof (Int32));
+ createCol(shapes, "PathTwistBegin", typeof (Int32));
+ // profile
+ createCol(shapes, "ProfileBegin", typeof (Int32));
+ createCol(shapes, "ProfileEnd", typeof (Int32));
+ createCol(shapes, "ProfileCurve", typeof (Int32));
+ createCol(shapes, "ProfileHollow", typeof (Int32));
+ createCol(shapes, "State", typeof(Int32));
+ // text TODO: this isn't right, but I'm not sure the right
+ // way to specify this as a blob atm
+ createCol(shapes, "Texture", typeof (Byte[]));
+ createCol(shapes, "ExtraParams", typeof (Byte[]));
+
+ shapes.PrimaryKey = new DataColumn[] {shapes.Columns["UUID"]};
+
+ return shapes;
+ }
+
+ ///
+ /// creates "primitems" table
+ ///
+ /// item table DataTable
+ private static DataTable createItemsTable()
+ {
+ DataTable items = new DataTable("primitems");
+
+ createCol(items, "itemID", typeof (String));
+ createCol(items, "primID", typeof (String));
+ createCol(items, "assetID", typeof (String));
+ createCol(items, "parentFolderID", typeof (String));
+
+ createCol(items, "invType", typeof (Int32));
+ createCol(items, "assetType", typeof (Int32));
+
+ createCol(items, "name", typeof (String));
+ createCol(items, "description", typeof (String));
+
+ createCol(items, "creationDate", typeof (Int64));
+ createCol(items, "creatorID", typeof (String));
+ createCol(items, "ownerID", typeof (String));
+ createCol(items, "lastOwnerID", typeof (String));
+ createCol(items, "groupID", typeof (String));
+
+ createCol(items, "nextPermissions", typeof (UInt32));
+ createCol(items, "currentPermissions", typeof (UInt32));
+ createCol(items, "basePermissions", typeof (UInt32));
+ createCol(items, "everyonePermissions", typeof (UInt32));
+ createCol(items, "groupPermissions", typeof (UInt32));
+ createCol(items, "flags", typeof (UInt32));
+
+ items.PrimaryKey = new DataColumn[] { items.Columns["itemID"] };
+
+ return items;
+ }
+
+ ///
+ /// Creates "land" table
+ ///
+ /// land table DataTable
+ private static DataTable createLandTable()
+ {
+ DataTable land = new DataTable("land");
+ createCol(land, "UUID", typeof (String));
+ createCol(land, "RegionUUID", typeof (String));
+ createCol(land, "LocalLandID", typeof (UInt32));
+
+ // Bitmap is a byte[512]
+ createCol(land, "Bitmap", typeof (Byte[]));
+
+ createCol(land, "Name", typeof (String));
+ createCol(land, "Desc", typeof (String));
+ createCol(land, "OwnerUUID", typeof (String));
+ createCol(land, "IsGroupOwned", typeof (Boolean));
+ createCol(land, "Area", typeof (Int32));
+ createCol(land, "AuctionID", typeof (Int32)); //Unemplemented
+ createCol(land, "Category", typeof (Int32)); //Enum OpenMetaverse.Parcel.ParcelCategory
+ createCol(land, "ClaimDate", typeof (Int32));
+ createCol(land, "ClaimPrice", typeof (Int32));
+ createCol(land, "GroupUUID", typeof (string));
+ createCol(land, "SalePrice", typeof (Int32));
+ createCol(land, "LandStatus", typeof (Int32)); //Enum. OpenMetaverse.Parcel.ParcelStatus
+ createCol(land, "LandFlags", typeof (UInt32));
+ createCol(land, "LandingType", typeof (Byte));
+ createCol(land, "MediaAutoScale", typeof (Byte));
+ createCol(land, "MediaTextureUUID", typeof (String));
+ createCol(land, "MediaURL", typeof (String));
+ createCol(land, "MusicURL", typeof (String));
+ createCol(land, "PassHours", typeof (Double));
+ createCol(land, "PassPrice", typeof (UInt32));
+ createCol(land, "SnapshotUUID", typeof (String));
+ createCol(land, "UserLocationX", typeof (Double));
+ createCol(land, "UserLocationY", typeof (Double));
+ createCol(land, "UserLocationZ", typeof (Double));
+ createCol(land, "UserLookAtX", typeof (Double));
+ createCol(land, "UserLookAtY", typeof (Double));
+ createCol(land, "UserLookAtZ", typeof (Double));
+ createCol(land, "AuthbuyerID", typeof(String));
+ createCol(land, "OtherCleanTime", typeof(Int32));
+ createCol(land, "Dwell", typeof(Int32));
+
+ land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]};
+
+ return land;
+ }
+
+ ///
+ /// create "landaccesslist" table
+ ///
+ /// Landacceslist DataTable
+ private static DataTable createLandAccessListTable()
+ {
+ DataTable landaccess = new DataTable("landaccesslist");
+ createCol(landaccess, "LandUUID", typeof (String));
+ createCol(landaccess, "AccessUUID", typeof (String));
+ createCol(landaccess, "Flags", typeof (UInt32));
+
+ return landaccess;
+ }
+
+ private static DataTable createRegionSettingsTable()
+ {
+ DataTable regionsettings = new DataTable("regionsettings");
+ createCol(regionsettings, "regionUUID", typeof(String));
+ createCol(regionsettings, "block_terraform", typeof (Int32));
+ createCol(regionsettings, "block_fly", typeof (Int32));
+ createCol(regionsettings, "allow_damage", typeof (Int32));
+ createCol(regionsettings, "restrict_pushing", typeof (Int32));
+ createCol(regionsettings, "allow_land_resell", typeof (Int32));
+ createCol(regionsettings, "allow_land_join_divide", typeof (Int32));
+ createCol(regionsettings, "block_show_in_search", typeof (Int32));
+ createCol(regionsettings, "agent_limit", typeof (Int32));
+ createCol(regionsettings, "object_bonus", typeof (Double));
+ createCol(regionsettings, "maturity", typeof (Int32));
+ createCol(regionsettings, "disable_scripts", typeof (Int32));
+ createCol(regionsettings, "disable_collisions", typeof (Int32));
+ createCol(regionsettings, "disable_physics", typeof (Int32));
+ createCol(regionsettings, "terrain_texture_1", typeof(String));
+ createCol(regionsettings, "terrain_texture_2", typeof(String));
+ createCol(regionsettings, "terrain_texture_3", typeof(String));
+ createCol(regionsettings, "terrain_texture_4", typeof(String));
+ createCol(regionsettings, "elevation_1_nw", typeof (Double));
+ createCol(regionsettings, "elevation_2_nw", typeof (Double));
+ createCol(regionsettings, "elevation_1_ne", typeof (Double));
+ createCol(regionsettings, "elevation_2_ne", typeof (Double));
+ createCol(regionsettings, "elevation_1_se", typeof (Double));
+ createCol(regionsettings, "elevation_2_se", typeof (Double));
+ createCol(regionsettings, "elevation_1_sw", typeof (Double));
+ createCol(regionsettings, "elevation_2_sw", typeof (Double));
+ createCol(regionsettings, "water_height", typeof (Double));
+ createCol(regionsettings, "terrain_raise_limit", typeof (Double));
+ createCol(regionsettings, "terrain_lower_limit", typeof (Double));
+ createCol(regionsettings, "use_estate_sun", typeof (Int32));
+ createCol(regionsettings, "sandbox", typeof (Int32));
+ createCol(regionsettings, "sunvectorx",typeof (Double));
+ createCol(regionsettings, "sunvectory",typeof (Double));
+ createCol(regionsettings, "sunvectorz",typeof (Double));
+ createCol(regionsettings, "fixed_sun", typeof (Int32));
+ createCol(regionsettings, "sun_position", typeof (Double));
+ createCol(regionsettings, "covenant", typeof(String));
+ regionsettings.PrimaryKey = new DataColumn[] { regionsettings.Columns["regionUUID"] };
+ return regionsettings;
+ }
+
+ /***********************************************************************
+ *
+ * Convert between ADO.NET <=> OpenSim Objects
+ *
+ * These should be database independant
+ *
+ **********************************************************************/
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private SceneObjectPart buildPrim(DataRow row)
+ {
+ // Code commented. Uncomment to test the unit test inline.
+
+ // The unit test mentions this commented code for the purposes
+ // of debugging a unit test failure
+
+ // SceneObjectGroup sog = new SceneObjectGroup();
+ // SceneObjectPart sop = new SceneObjectPart();
+ // sop.LocalId = 1;
+ // sop.Name = "object1";
+ // sop.Description = "object1";
+ // sop.Text = "";
+ // sop.SitName = "";
+ // sop.TouchName = "";
+ // sop.UUID = UUID.Random();
+ // sop.Shape = PrimitiveBaseShape.Default;
+ // sog.SetRootPart(sop);
+ // Add breakpoint in above line. Check sop fields.
+
+ // TODO: this doesn't work yet because something more
+ // interesting has to be done to actually get these values
+ // back out. Not enough time to figure it out yet.
+
+ SceneObjectPart prim = new SceneObjectPart();
+ prim.UUID = new UUID((String) row["UUID"]);
+ // explicit conversion of integers is required, which sort
+ // of sucks. No idea if there is a shortcut here or not.
+ prim.CreationDate = Convert.ToInt32(row["CreationDate"]);
+ prim.Name = row["Name"] == DBNull.Value ? string.Empty : (string)row["Name"];
+ // various text fields
+ prim.Text = (String) row["Text"];
+ prim.Color = Color.FromArgb(Convert.ToInt32(row["ColorA"]),
+ Convert.ToInt32(row["ColorR"]),
+ Convert.ToInt32(row["ColorG"]),
+ Convert.ToInt32(row["ColorB"]));
+ prim.Description = (String) row["Description"];
+ prim.SitName = (String) row["SitName"];
+ prim.TouchName = (String) row["TouchName"];
+ // permissions
+ prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
+ prim.CreatorID = new UUID((String) row["CreatorID"]);
+ prim.OwnerID = new UUID((String) row["OwnerID"]);
+ prim.GroupID = new UUID((String) row["GroupID"]);
+ prim.LastOwnerID = new UUID((String) row["LastOwnerID"]);
+ prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]);
+ prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]);
+ prim.GroupMask = Convert.ToUInt32(row["GroupMask"]);
+ prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]);
+ prim.BaseMask = Convert.ToUInt32(row["BaseMask"]);
+ // vectors
+ prim.OffsetPosition = new Vector3(
+ Convert.ToSingle(row["PositionX"]),
+ Convert.ToSingle(row["PositionY"]),
+ Convert.ToSingle(row["PositionZ"])
+ );
+ prim.GroupPosition = new Vector3(
+ Convert.ToSingle(row["GroupPositionX"]),
+ Convert.ToSingle(row["GroupPositionY"]),
+ Convert.ToSingle(row["GroupPositionZ"])
+ );
+ prim.Velocity = new Vector3(
+ Convert.ToSingle(row["VelocityX"]),
+ Convert.ToSingle(row["VelocityY"]),
+ Convert.ToSingle(row["VelocityZ"])
+ );
+ prim.AngularVelocity = new Vector3(
+ Convert.ToSingle(row["AngularVelocityX"]),
+ Convert.ToSingle(row["AngularVelocityY"]),
+ Convert.ToSingle(row["AngularVelocityZ"])
+ );
+ prim.Acceleration = new Vector3(
+ Convert.ToSingle(row["AccelerationX"]),
+ Convert.ToSingle(row["AccelerationY"]),
+ Convert.ToSingle(row["AccelerationZ"])
+ );
+ // quaternions
+ prim.RotationOffset = new Quaternion(
+ Convert.ToSingle(row["RotationX"]),
+ Convert.ToSingle(row["RotationY"]),
+ Convert.ToSingle(row["RotationZ"]),
+ Convert.ToSingle(row["RotationW"])
+ );
+
+ prim.SitTargetPositionLL = new Vector3(
+ Convert.ToSingle(row["SitTargetOffsetX"]),
+ Convert.ToSingle(row["SitTargetOffsetY"]),
+ Convert.ToSingle(row["SitTargetOffsetZ"]));
+ prim.SitTargetOrientationLL = new Quaternion(
+ Convert.ToSingle(
+ row["SitTargetOrientX"]),
+ Convert.ToSingle(
+ row["SitTargetOrientY"]),
+ Convert.ToSingle(
+ row["SitTargetOrientZ"]),
+ Convert.ToSingle(
+ row["SitTargetOrientW"]));
+
+ prim.ClickAction = Convert.ToByte(row["ClickAction"]);
+ prim.PayPrice[0] = Convert.ToInt32(row["PayPrice"]);
+ prim.PayPrice[1] = Convert.ToInt32(row["PayButton1"]);
+ prim.PayPrice[2] = Convert.ToInt32(row["PayButton2"]);
+ prim.PayPrice[3] = Convert.ToInt32(row["PayButton3"]);
+ prim.PayPrice[4] = Convert.ToInt32(row["PayButton4"]);
+
+ prim.Sound = new UUID(row["LoopedSound"].ToString());
+ prim.SoundGain = Convert.ToSingle(row["LoopedSoundGain"]);
+ prim.SoundFlags = 1; // If it's persisted at all, it's looped
+
+ if (!row.IsNull("TextureAnimation"))
+ prim.TextureAnimation = Convert.FromBase64String(row["TextureAnimation"].ToString());
+ if (!row.IsNull("ParticleSystem"))
+ prim.ParticleSystem = Convert.FromBase64String(row["ParticleSystem"].ToString());
+
+ prim.AngularVelocity = new Vector3(
+ Convert.ToSingle(row["OmegaX"]),
+ Convert.ToSingle(row["OmegaY"]),
+ Convert.ToSingle(row["OmegaZ"])
+ );
+
+ prim.SetCameraEyeOffset(new Vector3(
+ Convert.ToSingle(row["CameraEyeOffsetX"]),
+ Convert.ToSingle(row["CameraEyeOffsetY"]),
+ Convert.ToSingle(row["CameraEyeOffsetZ"])
+ ));
+
+ prim.SetCameraAtOffset(new Vector3(
+ Convert.ToSingle(row["CameraAtOffsetX"]),
+ Convert.ToSingle(row["CameraAtOffsetY"]),
+ Convert.ToSingle(row["CameraAtOffsetZ"])
+ ));
+
+ if (Convert.ToInt16(row["ForceMouselook"]) != 0)
+ prim.SetForceMouselook(true);
+
+ prim.ScriptAccessPin = Convert.ToInt32(row["ScriptAccessPin"]);
+
+ if (Convert.ToInt16(row["AllowedDrop"]) != 0)
+ prim.AllowedDrop = true;
+
+ if (Convert.ToInt16(row["DieAtEdge"]) != 0)
+ prim.DIE_AT_EDGE = true;
+
+ prim.SalePrice = Convert.ToInt32(row["SalePrice"]);
+ prim.ObjectSaleType = Convert.ToByte(row["SaleType"]);
+
+ prim.Material = Convert.ToByte(row["Material"]);
+
+ prim.CollisionSound = new UUID(row["CollisionSound"].ToString());
+ prim.CollisionSoundVolume = Convert.ToSingle(row["CollisionSoundVolume"]);
+
+ if (Convert.ToInt16(row["VolumeDetect"]) != 0)
+ prim.VolumeDetectActive = true;
+
+ return prim;
+ }
+
+ ///
+ /// Build a prim inventory item from the persisted data.
+ ///
+ ///
+ ///
+ private static TaskInventoryItem buildItem(DataRow row)
+ {
+ TaskInventoryItem taskItem = new TaskInventoryItem();
+
+ taskItem.ItemID = new UUID((String)row["itemID"]);
+ taskItem.ParentPartID = new UUID((String)row["primID"]);
+ taskItem.AssetID = new UUID((String)row["assetID"]);
+ taskItem.ParentID = new UUID((String)row["parentFolderID"]);
+
+ taskItem.InvType = Convert.ToInt32(row["invType"]);
+ taskItem.Type = Convert.ToInt32(row["assetType"]);
+
+ taskItem.Name = (String)row["name"];
+ taskItem.Description = (String)row["description"];
+ taskItem.CreationDate = Convert.ToUInt32(row["creationDate"]);
+ taskItem.CreatorID = new UUID((String)row["creatorID"]);
+ taskItem.OwnerID = new UUID((String)row["ownerID"]);
+ taskItem.LastOwnerID = new UUID((String)row["lastOwnerID"]);
+ taskItem.GroupID = new UUID((String)row["groupID"]);
+
+ taskItem.NextPermissions = Convert.ToUInt32(row["nextPermissions"]);
+ taskItem.CurrentPermissions = Convert.ToUInt32(row["currentPermissions"]);
+ taskItem.BasePermissions = Convert.ToUInt32(row["basePermissions"]);
+ taskItem.EveryonePermissions = Convert.ToUInt32(row["everyonePermissions"]);
+ taskItem.GroupPermissions = Convert.ToUInt32(row["groupPermissions"]);
+ taskItem.Flags = Convert.ToUInt32(row["flags"]);
+
+ return taskItem;
+ }
+
+ ///
+ /// Build a Land Data from the persisted data.
+ ///
+ ///
+ ///
+ private LandData buildLandData(DataRow row)
+ {
+ LandData newData = new LandData();
+
+ newData.GlobalID = new UUID((String) row["UUID"]);
+ newData.LocalID = Convert.ToInt32(row["LocalLandID"]);
+
+ // Bitmap is a byte[512]
+ newData.Bitmap = (Byte[]) row["Bitmap"];
+
+ newData.Name = (String) row["Name"];
+ newData.Description = (String) row["Desc"];
+ newData.OwnerID = (UUID)(String) row["OwnerUUID"];
+ newData.IsGroupOwned = (Boolean) row["IsGroupOwned"];
+ newData.Area = Convert.ToInt32(row["Area"]);
+ newData.AuctionID = Convert.ToUInt32(row["AuctionID"]); //Unemplemented
+ newData.Category = (ParcelCategory) Convert.ToInt32(row["Category"]);
+ //Enum OpenMetaverse.Parcel.ParcelCategory
+ newData.ClaimDate = Convert.ToInt32(row["ClaimDate"]);
+ newData.ClaimPrice = Convert.ToInt32(row["ClaimPrice"]);
+ newData.GroupID = new UUID((String) row["GroupUUID"]);
+ newData.SalePrice = Convert.ToInt32(row["SalePrice"]);
+ newData.Status = (ParcelStatus) Convert.ToInt32(row["LandStatus"]);
+ //Enum. OpenMetaverse.Parcel.ParcelStatus
+ newData.Flags = Convert.ToUInt32(row["LandFlags"]);
+ newData.LandingType = (Byte) row["LandingType"];
+ newData.MediaAutoScale = (Byte) row["MediaAutoScale"];
+ newData.MediaID = new UUID((String) row["MediaTextureUUID"]);
+ newData.MediaURL = (String) row["MediaURL"];
+ newData.MusicURL = (String) row["MusicURL"];
+ newData.PassHours = Convert.ToSingle(row["PassHours"]);
+ newData.PassPrice = Convert.ToInt32(row["PassPrice"]);
+ newData.SnapshotID = (UUID)(String) row["SnapshotUUID"];
+ try
+ {
+
+ newData.UserLocation =
+ new Vector3(Convert.ToSingle(row["UserLocationX"]), Convert.ToSingle(row["UserLocationY"]),
+ Convert.ToSingle(row["UserLocationZ"]));
+ newData.UserLookAt =
+ new Vector3(Convert.ToSingle(row["UserLookAtX"]), Convert.ToSingle(row["UserLookAtY"]),
+ Convert.ToSingle(row["UserLookAtZ"]));
+
+ }
+ catch (InvalidCastException)
+ {
+ m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name);
+ newData.UserLocation = Vector3.Zero;
+ newData.UserLookAt = Vector3.Zero;
+ }
+ newData.ParcelAccessList = new List();
+ UUID authBuyerID = UUID.Zero;
+
+ UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID);
+
+ newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
+ newData.Dwell = Convert.ToInt32(row["Dwell"]);
+
+ return newData;
+ }
+
+ private RegionSettings buildRegionSettings(DataRow row)
+ {
+ RegionSettings newSettings = new RegionSettings();
+
+ newSettings.RegionUUID = new UUID((string) row["regionUUID"]);
+ newSettings.BlockTerraform = Convert.ToBoolean(row["block_terraform"]);
+ newSettings.AllowDamage = Convert.ToBoolean(row["allow_damage"]);
+ newSettings.BlockFly = Convert.ToBoolean(row["block_fly"]);
+ newSettings.RestrictPushing = Convert.ToBoolean(row["restrict_pushing"]);
+ newSettings.AllowLandResell = Convert.ToBoolean(row["allow_land_resell"]);
+ newSettings.AllowLandJoinDivide = Convert.ToBoolean(row["allow_land_join_divide"]);
+ newSettings.BlockShowInSearch = Convert.ToBoolean(row["block_show_in_search"]);
+ newSettings.AgentLimit = Convert.ToInt32(row["agent_limit"]);
+ newSettings.ObjectBonus = Convert.ToDouble(row["object_bonus"]);
+ newSettings.Maturity = Convert.ToInt32(row["maturity"]);
+ newSettings.DisableScripts = Convert.ToBoolean(row["disable_scripts"]);
+ newSettings.DisableCollisions = Convert.ToBoolean(row["disable_collisions"]);
+ newSettings.DisablePhysics = Convert.ToBoolean(row["disable_physics"]);
+ newSettings.TerrainTexture1 = new UUID((String) row["terrain_texture_1"]);
+ newSettings.TerrainTexture2 = new UUID((String) row["terrain_texture_2"]);
+ newSettings.TerrainTexture3 = new UUID((String) row["terrain_texture_3"]);
+ newSettings.TerrainTexture4 = new UUID((String) row["terrain_texture_4"]);
+ newSettings.Elevation1NW = Convert.ToDouble(row["elevation_1_nw"]);
+ newSettings.Elevation2NW = Convert.ToDouble(row["elevation_2_nw"]);
+ newSettings.Elevation1NE = Convert.ToDouble(row["elevation_1_ne"]);
+ newSettings.Elevation2NE = Convert.ToDouble(row["elevation_2_ne"]);
+ newSettings.Elevation1SE = Convert.ToDouble(row["elevation_1_se"]);
+ newSettings.Elevation2SE = Convert.ToDouble(row["elevation_2_se"]);
+ newSettings.Elevation1SW = Convert.ToDouble(row["elevation_1_sw"]);
+ newSettings.Elevation2SW = Convert.ToDouble(row["elevation_2_sw"]);
+ newSettings.WaterHeight = Convert.ToDouble(row["water_height"]);
+ newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
+ newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
+ newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
+ newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
+ newSettings.SunVector = new Vector3 (
+ Convert.ToSingle(row["sunvectorx"]),
+ Convert.ToSingle(row["sunvectory"]),
+ Convert.ToSingle(row["sunvectorz"])
+ );
+ newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
+ newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
+ newSettings.Covenant = new UUID((String) row["covenant"]);
+
+ return newSettings;
+ }
+
+ ///
+ /// Build a land access entry from the persisted data.
+ ///
+ ///
+ ///
+ private static ParcelManager.ParcelAccessEntry buildLandAccessData(DataRow row)
+ {
+ ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry();
+ entry.AgentID = new UUID((string) row["AccessUUID"]);
+ entry.Flags = (AccessList) row["Flags"];
+ entry.Time = new DateTime();
+ return entry;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static Array serializeTerrain(double[,] val)
+ {
+ MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) *sizeof (double));
+ BinaryWriter bw = new BinaryWriter(str);
+
+ // TODO: COMPATIBILITY - Add byte-order conversions
+ for (int x = 0; x < (int)Constants.RegionSize; x++)
+ for (int y = 0; y < (int)Constants.RegionSize; y++)
+ bw.Write(val[x, y]);
+
+ return str.ToArray();
+ }
+
+// private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
+// {
+// row["RegionUUID"] = regionUUID;
+// row["Revision"] = rev;
+
+ // MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize)*sizeof (double));
+// BinaryWriter bw = new BinaryWriter(str);
+
+// // TODO: COMPATIBILITY - Add byte-order conversions
+ // for (int x = 0; x < (int)Constants.RegionSize; x++)
+ // for (int y = 0; y < (int)Constants.RegionSize; y++)
+// bw.Write(val[x, y]);
+
+// row["Heightfield"] = str.ToArray();
+// }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillPrimRow(DataRow row, SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
+ {
+ row["UUID"] = prim.UUID.ToString();
+ row["RegionUUID"] = regionUUID.ToString();
+ row["CreationDate"] = prim.CreationDate;
+ row["Name"] = prim.Name;
+ row["SceneGroupID"] = sceneGroupID.ToString();
+ // the UUID of the root part for this SceneObjectGroup
+ // various text fields
+ row["Text"] = prim.Text;
+ row["Description"] = prim.Description;
+ row["SitName"] = prim.SitName;
+ row["TouchName"] = prim.TouchName;
+ // permissions
+ row["ObjectFlags"] = prim.ObjectFlags;
+ row["CreatorID"] = prim.CreatorID.ToString();
+ row["OwnerID"] = prim.OwnerID.ToString();
+ row["GroupID"] = prim.GroupID.ToString();
+ row["LastOwnerID"] = prim.LastOwnerID.ToString();
+ row["OwnerMask"] = prim.OwnerMask;
+ row["NextOwnerMask"] = prim.NextOwnerMask;
+ row["GroupMask"] = prim.GroupMask;
+ row["EveryoneMask"] = prim.EveryoneMask;
+ row["BaseMask"] = prim.BaseMask;
+ // vectors
+ row["PositionX"] = prim.OffsetPosition.X;
+ row["PositionY"] = prim.OffsetPosition.Y;
+ row["PositionZ"] = prim.OffsetPosition.Z;
+ row["GroupPositionX"] = prim.GroupPosition.X;
+ row["GroupPositionY"] = prim.GroupPosition.Y;
+ row["GroupPositionZ"] = prim.GroupPosition.Z;
+ row["VelocityX"] = prim.Velocity.X;
+ row["VelocityY"] = prim.Velocity.Y;
+ row["VelocityZ"] = prim.Velocity.Z;
+ row["AngularVelocityX"] = prim.AngularVelocity.X;
+ row["AngularVelocityY"] = prim.AngularVelocity.Y;
+ row["AngularVelocityZ"] = prim.AngularVelocity.Z;
+ row["AccelerationX"] = prim.Acceleration.X;
+ row["AccelerationY"] = prim.Acceleration.Y;
+ row["AccelerationZ"] = prim.Acceleration.Z;
+ // quaternions
+ row["RotationX"] = prim.RotationOffset.X;
+ row["RotationY"] = prim.RotationOffset.Y;
+ row["RotationZ"] = prim.RotationOffset.Z;
+ row["RotationW"] = prim.RotationOffset.W;
+
+ // Sit target
+ Vector3 sitTargetPos = prim.SitTargetPositionLL;
+ row["SitTargetOffsetX"] = sitTargetPos.X;
+ row["SitTargetOffsetY"] = sitTargetPos.Y;
+ row["SitTargetOffsetZ"] = sitTargetPos.Z;
+
+ Quaternion sitTargetOrient = prim.SitTargetOrientationLL;
+ row["SitTargetOrientW"] = sitTargetOrient.W;
+ row["SitTargetOrientX"] = sitTargetOrient.X;
+ row["SitTargetOrientY"] = sitTargetOrient.Y;
+ row["SitTargetOrientZ"] = sitTargetOrient.Z;
+ row["ColorR"] = Convert.ToInt32(prim.Color.R);
+ row["ColorG"] = Convert.ToInt32(prim.Color.G);
+ row["ColorB"] = Convert.ToInt32(prim.Color.B);
+ row["ColorA"] = Convert.ToInt32(prim.Color.A);
+ row["PayPrice"] = prim.PayPrice[0];
+ row["PayButton1"] = prim.PayPrice[1];
+ row["PayButton2"] = prim.PayPrice[2];
+ row["PayButton3"] = prim.PayPrice[3];
+ row["PayButton4"] = prim.PayPrice[4];
+
+
+ row["TextureAnimation"] = Convert.ToBase64String(prim.TextureAnimation);
+ row["ParticleSystem"] = Convert.ToBase64String(prim.ParticleSystem);
+
+ row["OmegaX"] = prim.AngularVelocity.X;
+ row["OmegaY"] = prim.AngularVelocity.Y;
+ row["OmegaZ"] = prim.AngularVelocity.Z;
+
+ row["CameraEyeOffsetX"] = prim.GetCameraEyeOffset().X;
+ row["CameraEyeOffsetY"] = prim.GetCameraEyeOffset().Y;
+ row["CameraEyeOffsetZ"] = prim.GetCameraEyeOffset().Z;
+
+ row["CameraAtOffsetX"] = prim.GetCameraAtOffset().X;
+ row["CameraAtOffsetY"] = prim.GetCameraAtOffset().Y;
+ row["CameraAtOffsetZ"] = prim.GetCameraAtOffset().Z;
+
+
+ if ((prim.SoundFlags & 1) != 0) // Looped
+ {
+ row["LoopedSound"] = prim.Sound.ToString();
+ row["LoopedSoundGain"] = prim.SoundGain;
+ }
+ else
+ {
+ row["LoopedSound"] = UUID.Zero.ToString();
+ row["LoopedSoundGain"] = 0.0f;
+ }
+
+ if (prim.GetForceMouselook())
+ row["ForceMouselook"] = 1;
+ else
+ row["ForceMouselook"] = 0;
+
+ row["ScriptAccessPin"] = prim.ScriptAccessPin;
+
+ if (prim.AllowedDrop)
+ row["AllowedDrop"] = 1;
+ else
+ row["AllowedDrop"] = 0;
+
+ if (prim.DIE_AT_EDGE)
+ row["DieAtEdge"] = 1;
+ else
+ row["DieAtEdge"] = 0;
+
+ row["SalePrice"] = prim.SalePrice;
+ row["SaleType"] = Convert.ToInt16(prim.ObjectSaleType);
+
+ // click action
+ row["ClickAction"] = prim.ClickAction;
+
+ row["SalePrice"] = prim.SalePrice;
+ row["Material"] = prim.Material;
+
+ row["CollisionSound"] = prim.CollisionSound.ToString();
+ row["CollisionSoundVolume"] = prim.CollisionSoundVolume;
+ if (prim.VolumeDetectActive)
+ row["VolumeDetect"] = 1;
+ else
+ row["VolumeDetect"] = 0;
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillItemRow(DataRow row, TaskInventoryItem taskItem)
+ {
+ row["itemID"] = taskItem.ItemID.ToString();
+ row["primID"] = taskItem.ParentPartID.ToString();
+ row["assetID"] = taskItem.AssetID.ToString();
+ row["parentFolderID"] = taskItem.ParentID.ToString();
+
+ row["invType"] = taskItem.InvType;
+ row["assetType"] = taskItem.Type;
+
+ row["name"] = taskItem.Name;
+ row["description"] = taskItem.Description;
+ row["creationDate"] = taskItem.CreationDate;
+ row["creatorID"] = taskItem.CreatorID.ToString();
+ row["ownerID"] = taskItem.OwnerID.ToString();
+ row["lastOwnerID"] = taskItem.LastOwnerID.ToString();
+ row["groupID"] = taskItem.GroupID.ToString();
+ row["nextPermissions"] = taskItem.NextPermissions;
+ row["currentPermissions"] = taskItem.CurrentPermissions;
+ row["basePermissions"] = taskItem.BasePermissions;
+ row["everyonePermissions"] = taskItem.EveryonePermissions;
+ row["groupPermissions"] = taskItem.GroupPermissions;
+ row["flags"] = taskItem.Flags;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillLandRow(DataRow row, LandData land, UUID regionUUID)
+ {
+ row["UUID"] = land.GlobalID.ToString();
+ row["RegionUUID"] = regionUUID.ToString();
+ row["LocalLandID"] = land.LocalID;
+
+ // Bitmap is a byte[512]
+ row["Bitmap"] = land.Bitmap;
+
+ row["Name"] = land.Name;
+ row["Desc"] = land.Description;
+ row["OwnerUUID"] = land.OwnerID.ToString();
+ row["IsGroupOwned"] = land.IsGroupOwned;
+ row["Area"] = land.Area;
+ row["AuctionID"] = land.AuctionID; //Unemplemented
+ row["Category"] = land.Category; //Enum OpenMetaverse.Parcel.ParcelCategory
+ row["ClaimDate"] = land.ClaimDate;
+ row["ClaimPrice"] = land.ClaimPrice;
+ row["GroupUUID"] = land.GroupID.ToString();
+ row["SalePrice"] = land.SalePrice;
+ row["LandStatus"] = land.Status; //Enum. OpenMetaverse.Parcel.ParcelStatus
+ row["LandFlags"] = land.Flags;
+ row["LandingType"] = land.LandingType;
+ row["MediaAutoScale"] = land.MediaAutoScale;
+ row["MediaTextureUUID"] = land.MediaID.ToString();
+ row["MediaURL"] = land.MediaURL;
+ row["MusicURL"] = land.MusicURL;
+ row["PassHours"] = land.PassHours;
+ row["PassPrice"] = land.PassPrice;
+ row["SnapshotUUID"] = land.SnapshotID.ToString();
+ row["UserLocationX"] = land.UserLocation.X;
+ row["UserLocationY"] = land.UserLocation.Y;
+ row["UserLocationZ"] = land.UserLocation.Z;
+ row["UserLookAtX"] = land.UserLookAt.X;
+ row["UserLookAtY"] = land.UserLookAt.Y;
+ row["UserLookAtZ"] = land.UserLookAt.Z;
+ row["AuthbuyerID"] = land.AuthBuyerID.ToString();
+ row["OtherCleanTime"] = land.OtherCleanTime;
+ row["Dwell"] = land.Dwell;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillLandAccessRow(DataRow row, ParcelManager.ParcelAccessEntry entry, UUID parcelID)
+ {
+ row["LandUUID"] = parcelID.ToString();
+ row["AccessUUID"] = entry.AgentID.ToString();
+ row["Flags"] = entry.Flags;
+ }
+
+ private static void fillRegionSettingsRow(DataRow row, RegionSettings settings)
+ {
+ row["regionUUID"] = settings.RegionUUID.ToString();
+ row["block_terraform"] = settings.BlockTerraform;
+ row["block_fly"] = settings.BlockFly;
+ row["allow_damage"] = settings.AllowDamage;
+ row["restrict_pushing"] = settings.RestrictPushing;
+ row["allow_land_resell"] = settings.AllowLandResell;
+ row["allow_land_join_divide"] = settings.AllowLandJoinDivide;
+ row["block_show_in_search"] = settings.BlockShowInSearch;
+ row["agent_limit"] = settings.AgentLimit;
+ row["object_bonus"] = settings.ObjectBonus;
+ row["maturity"] = settings.Maturity;
+ row["disable_scripts"] = settings.DisableScripts;
+ row["disable_collisions"] = settings.DisableCollisions;
+ row["disable_physics"] = settings.DisablePhysics;
+ row["terrain_texture_1"] = settings.TerrainTexture1.ToString();
+ row["terrain_texture_2"] = settings.TerrainTexture2.ToString();
+ row["terrain_texture_3"] = settings.TerrainTexture3.ToString();
+ row["terrain_texture_4"] = settings.TerrainTexture4.ToString();
+ row["elevation_1_nw"] = settings.Elevation1NW;
+ row["elevation_2_nw"] = settings.Elevation2NW;
+ row["elevation_1_ne"] = settings.Elevation1NE;
+ row["elevation_2_ne"] = settings.Elevation2NE;
+ row["elevation_1_se"] = settings.Elevation1SE;
+ row["elevation_2_se"] = settings.Elevation2SE;
+ row["elevation_1_sw"] = settings.Elevation1SW;
+ row["elevation_2_sw"] = settings.Elevation2SW;
+ row["water_height"] = settings.WaterHeight;
+ row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
+ row["terrain_lower_limit"] = settings.TerrainLowerLimit;
+ row["use_estate_sun"] = settings.UseEstateSun;
+ row["Sandbox"] = settings.Sandbox; // database uses upper case S for sandbox
+ row["sunvectorx"] = settings.SunVector.X;
+ row["sunvectory"] = settings.SunVector.Y;
+ row["sunvectorz"] = settings.SunVector.Z;
+ row["fixed_sun"] = settings.FixedSun;
+ row["sun_position"] = settings.SunPosition;
+ row["covenant"] = settings.Covenant.ToString();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private PrimitiveBaseShape buildShape(DataRow row)
+ {
+ PrimitiveBaseShape s = new PrimitiveBaseShape();
+ s.Scale = new Vector3(
+ Convert.ToSingle(row["ScaleX"]),
+ Convert.ToSingle(row["ScaleY"]),
+ Convert.ToSingle(row["ScaleZ"])
+ );
+ // paths
+ s.PCode = Convert.ToByte(row["PCode"]);
+ s.PathBegin = Convert.ToUInt16(row["PathBegin"]);
+ s.PathEnd = Convert.ToUInt16(row["PathEnd"]);
+ s.PathScaleX = Convert.ToByte(row["PathScaleX"]);
+ s.PathScaleY = Convert.ToByte(row["PathScaleY"]);
+ s.PathShearX = Convert.ToByte(row["PathShearX"]);
+ s.PathShearY = Convert.ToByte(row["PathShearY"]);
+ s.PathSkew = Convert.ToSByte(row["PathSkew"]);
+ s.PathCurve = Convert.ToByte(row["PathCurve"]);
+ s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]);
+ s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]);
+ s.PathTaperX = Convert.ToSByte(row["PathTaperX"]);
+ s.PathTaperY = Convert.ToSByte(row["PathTaperY"]);
+ s.PathTwist = Convert.ToSByte(row["PathTwist"]);
+ s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]);
+ // profile
+ s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]);
+ s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]);
+ s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]);
+ s.ProfileHollow = Convert.ToUInt16(row["ProfileHollow"]);
+ s.State = Convert.ToByte(row["State"]);
+
+ byte[] textureEntry = (byte[])row["Texture"];
+ s.TextureEntry = textureEntry;
+
+ s.ExtraParams = (byte[]) row["ExtraParams"];
+ return s;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private static void fillShapeRow(DataRow row, SceneObjectPart prim)
+ {
+ PrimitiveBaseShape s = prim.Shape;
+ row["UUID"] = prim.UUID.ToString();
+ // shape is an enum
+ row["Shape"] = 0;
+ // vectors
+ row["ScaleX"] = s.Scale.X;
+ row["ScaleY"] = s.Scale.Y;
+ row["ScaleZ"] = s.Scale.Z;
+ // paths
+ row["PCode"] = s.PCode;
+ row["PathBegin"] = s.PathBegin;
+ row["PathEnd"] = s.PathEnd;
+ row["PathScaleX"] = s.PathScaleX;
+ row["PathScaleY"] = s.PathScaleY;
+ row["PathShearX"] = s.PathShearX;
+ row["PathShearY"] = s.PathShearY;
+ row["PathSkew"] = s.PathSkew;
+ row["PathCurve"] = s.PathCurve;
+ row["PathRadiusOffset"] = s.PathRadiusOffset;
+ row["PathRevolutions"] = s.PathRevolutions;
+ row["PathTaperX"] = s.PathTaperX;
+ row["PathTaperY"] = s.PathTaperY;
+ row["PathTwist"] = s.PathTwist;
+ row["PathTwistBegin"] = s.PathTwistBegin;
+ // profile
+ row["ProfileBegin"] = s.ProfileBegin;
+ row["ProfileEnd"] = s.ProfileEnd;
+ row["ProfileCurve"] = s.ProfileCurve;
+ row["ProfileHollow"] = s.ProfileHollow;
+ row["State"] = s.State;
+
+ row["Texture"] = s.TextureEntry;
+ row["ExtraParams"] = s.ExtraParams;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void addPrim(SceneObjectPart prim, UUID sceneGroupID, UUID regionUUID)
+ {
+
+ DataTable prims = ds.Tables["prims"];
+ DataTable shapes = ds.Tables["primshapes"];
+
+ DataRow primRow = prims.Rows.Find(prim.UUID.ToString());
+ if (primRow == null)
+ {
+ primRow = prims.NewRow();
+ fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
+ prims.Rows.Add(primRow);
+ }
+ else
+ {
+ fillPrimRow(primRow, prim, sceneGroupID, regionUUID);
+ }
+
+ DataRow shapeRow = shapes.Rows.Find(prim.UUID.ToString());
+ if (shapeRow == null)
+ {
+ shapeRow = shapes.NewRow();
+ fillShapeRow(shapeRow, prim);
+ shapes.Rows.Add(shapeRow);
+ }
+ else
+ {
+ fillShapeRow(shapeRow, prim);
+ }
+ }
+
+ ///
+ /// see IRegionDatastore
+ ///
+ ///
+ ///
+ public void StorePrimInventory(UUID primID, ICollection items)
+ {
+ m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID);
+
+ DataTable dbItems = ds.Tables["primitems"];
+
+ // For now, we're just going to crudely remove all the previous inventory items
+ // no matter whether they have changed or not, and replace them with the current set.
+ lock (ds)
+ {
+ RemoveItems(primID);
+
+ // repalce with current inventory details
+ foreach (TaskInventoryItem newItem in items)
+ {
+// m_log.InfoFormat(
+// "[DATASTORE]: ",
+// "Adding item {0}, {1} to prim ID {2}",
+// newItem.Name, newItem.ItemID, newItem.ParentPartID);
+
+ DataRow newItemRow = dbItems.NewRow();
+ fillItemRow(newItemRow, newItem);
+ dbItems.Rows.Add(newItemRow);
+ }
+ }
+
+ Commit();
+ }
+
+ /***********************************************************************
+ *
+ * SQL Statement Creation Functions
+ *
+ * These functions create SQL statements for update, insert, and create.
+ * They can probably be factored later to have a db independant
+ * portion and a db specific portion
+ *
+ **********************************************************************/
+
+ ///
+ /// Create an insert command
+ ///
+ /// table name
+ /// data table
+ /// the created command
+ ///
+ /// This is subtle enough to deserve some commentary.
+ /// Instead of doing *lots* and *lots of hardcoded strings
+ /// for database definitions we'll use the fact that
+ /// realistically all insert statements look like "insert
+ /// into A(b, c) values(:b, :c) on the parameterized query
+ /// front. If we just have a list of b, c, etc... we can
+ /// generate these strings instead of typing them out.
+ ///
+ private static SqliteCommand createInsertCommand(string table, DataTable dt)
+ {
+ string[] cols = new string[dt.Columns.Count];
+ for (int i = 0; i < dt.Columns.Count; i++)
+ {
+ DataColumn col = dt.Columns[i];
+ cols[i] = col.ColumnName;
+ }
+
+ string sql = "insert into " + table + "(";
+ sql += String.Join(", ", cols);
+ // important, the first ':' needs to be here, the rest get added in the join
+ sql += ") values (:";
+ sql += String.Join(", :", cols);
+ sql += ")";
+ SqliteCommand cmd = new SqliteCommand(sql);
+
+ // this provides the binding for all our parameters, so
+ // much less code than it used to be
+ foreach (DataColumn col in dt.Columns)
+ {
+ cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+ }
+ return cmd;
+ }
+
+
+ ///
+ /// create an update command
+ ///
+ /// table name
+ ///
+ ///
+ /// the created command
+ private static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
+ {
+ string sql = "update " + table + " set ";
+ string subsql = String.Empty;
+ foreach (DataColumn col in dt.Columns)
+ {
+ if (subsql.Length > 0)
+ {
+ // a map function would rock so much here
+ subsql += ", ";
+ }
+ subsql += col.ColumnName + "= :" + col.ColumnName;
+ }
+ sql += subsql;
+ sql += " where " + pk;
+ SqliteCommand cmd = new SqliteCommand(sql);
+
+ // this provides the binding for all our parameters, so
+ // much less code than it used to be
+
+ foreach (DataColumn col in dt.Columns)
+ {
+ cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+ }
+ return cmd;
+ }
+
+ ///
+ /// create an update command
+ ///
+ /// table name
+ ///
+ ///
+ /// the created command
+ private static SqliteCommand createUpdateCommand(string table, string pk1, string pk2, DataTable dt)
+ {
+ string sql = "update " + table + " set ";
+ string subsql = String.Empty;
+ foreach (DataColumn col in dt.Columns)
+ {
+ if (subsql.Length > 0)
+ {
+ // a map function would rock so much here
+ subsql += ", ";
+ }
+ subsql += col.ColumnName + "= :" + col.ColumnName;
+ }
+ sql += subsql;
+ sql += " where " + pk1 + " and " + pk2;
+ SqliteCommand cmd = new SqliteCommand(sql);
+
+ // this provides the binding for all our parameters, so
+ // much less code than it used to be
+
+ foreach (DataColumn col in dt.Columns)
+ {
+ cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+ }
+ return cmd;
+ }
+
+ ///
+ ///
+ ///
+ /// Data Table
+ ///
+ // private static string defineTable(DataTable dt)
+ // {
+ // string sql = "create table " + dt.TableName + "(";
+ // string subsql = String.Empty;
+ // foreach (DataColumn col in dt.Columns)
+ // {
+ // if (subsql.Length > 0)
+ // {
+ // // a map function would rock so much here
+ // subsql += ",\n";
+ // }
+ // subsql += col.ColumnName + " " + sqliteType(col.DataType);
+ // if (dt.PrimaryKey.Length > 0 && col == dt.PrimaryKey[0])
+ // {
+ // subsql += " primary key";
+ // }
+ // }
+ // sql += subsql;
+ // sql += ")";
+ // return sql;
+ // }
+
+ /***********************************************************************
+ *
+ * Database Binding functions
+ *
+ * These will be db specific due to typing, and minor differences
+ * in databases.
+ *
+ **********************************************************************/
+
+ ///
+ /// This is a convenience function that collapses 5 repetitive
+ /// lines for defining SqliteParameters to 2 parameters:
+ /// column name and database type.
+ ///
+ /// It assumes certain conventions like :param as the param
+ /// name to replace in parametrized queries, and that source
+ /// version is always current version, both of which are fine
+ /// for us.
+ ///
+ ///a built sqlite parameter
+ private static SqliteParameter createSqliteParameter(string name, Type type)
+ {
+ SqliteParameter param = new SqliteParameter();
+ param.ParameterName = ":" + name;
+ param.DbType = dbtypeFromType(type);
+ param.SourceColumn = name;
+ param.SourceVersion = DataRowVersion.Current;
+ return param;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("prims", ds.Tables["prims"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", ds.Tables["prims"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID");
+ delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
+ delete.Connection = conn;
+ da.DeleteCommand = delete;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("primitems", ds.Tables["primitems"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("primitems", "itemID = :itemID", ds.Tables["primitems"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from primitems where itemID = :itemID");
+ delete.Parameters.Add(createSqliteParameter("itemID", typeof (String)));
+ delete.Connection = conn;
+ da.DeleteCommand = delete;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupTerrainCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("terrain", ds.Tables["terrain"]);
+ da.InsertCommand.Connection = conn;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupLandCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("land", ds.Tables["land"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("land", "UUID=:UUID", ds.Tables["land"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from land where UUID=:UUID");
+ delete.Parameters.Add(createSqliteParameter("UUID", typeof(String)));
+ da.DeleteCommand = delete;
+ da.DeleteCommand.Connection = conn;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupLandAccessCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("landaccesslist", ds.Tables["landaccesslist"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("landaccesslist", "LandUUID=:landUUID", "AccessUUID=:AccessUUID", ds.Tables["landaccesslist"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from landaccesslist where LandUUID= :LandUUID and AccessUUID= :AccessUUID");
+ delete.Parameters.Add(createSqliteParameter("LandUUID", typeof(String)));
+ delete.Parameters.Add(createSqliteParameter("AccessUUID", typeof(String)));
+ da.DeleteCommand = delete;
+ da.DeleteCommand.Connection = conn;
+
+ }
+
+ private void setupRegionSettingsCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("regionsettings", ds.Tables["regionsettings"]);
+ da.InsertCommand.Connection = conn;
+ da.UpdateCommand = createUpdateCommand("regionsettings", "regionUUID=:regionUUID", ds.Tables["regionsettings"]);
+ da.UpdateCommand.Connection = conn;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn)
+ {
+ da.InsertCommand = createInsertCommand("primshapes", ds.Tables["primshapes"]);
+ da.InsertCommand.Connection = conn;
+
+ da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", ds.Tables["primshapes"]);
+ da.UpdateCommand.Connection = conn;
+
+ SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID");
+ delete.Parameters.Add(createSqliteParameter("UUID", typeof (String)));
+ delete.Connection = conn;
+ da.DeleteCommand = delete;
+ }
+
+ /***********************************************************************
+ *
+ * Type conversion functions
+ *
+ **********************************************************************/
+
+ ///
+ /// Type conversion function
+ ///
+ ///
+ ///
+ private static DbType dbtypeFromType(Type type)
+ {
+ if (type == typeof (String))
+ {
+ return DbType.String;
+ }
+ else if (type == typeof (Int32))
+ {
+ return DbType.Int32;
+ }
+ else if (type == typeof (Double))
+ {
+ return DbType.Double;
+ }
+ else if (type == typeof (Byte))
+ {
+ return DbType.Byte;
+ }
+ else if (type == typeof (Double))
+ {
+ return DbType.Double;
+ }
+ else if (type == typeof (Byte[]))
+ {
+ return DbType.Binary;
+ }
+ else
+ {
+ return DbType.String;
+ }
+ }
+
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
new file mode 100644
index 0000000000..67cf7165b1
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Data;
+using OpenMetaverse;
+using OpenSim.Framework;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ public class SQLiteUserAccountData : SQLiteGenericTableHandler, IUserAccountData
+ {
+ public SQLiteUserAccountData(string connectionString, string realm)
+ : base(connectionString, realm, "UserAccount")
+ {
+ }
+
+ public UserAccountData[] GetUsers(UUID scopeID, string query)
+ {
+ string[] words = query.Split(new char[] {' '});
+
+ for (int i = 0 ; i < words.Length ; i++)
+ {
+ if (words[i].Length < 3)
+ {
+ if (i != words.Length - 1)
+ Array.Copy(words, i + 1, words, i, words.Length - i - 1);
+ Array.Resize(ref words, words.Length - 1);
+ }
+ }
+
+ if (words.Length == 0)
+ return new UserAccountData[0];
+
+ if (words.Length > 2)
+ return new UserAccountData[0];
+
+ SqliteCommand cmd = new SqliteCommand();
+
+ if (words.Length == 1)
+ {
+ 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}%')",
+ m_Realm, scopeID.ToString(), words[0]);
+ }
+ else
+ {
+ 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}%')",
+ m_Realm, scopeID.ToString(), words[0], words[1]);
+ }
+
+ return DoQuery(cmd);
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
new file mode 100644
index 0000000000..4a835ce52f
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using Mono.Data.SqliteClient;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// A base class for methods needed by all SQLite database classes
+ ///
+ public class SQLiteUtil
+ {
+ /***********************************************************************
+ *
+ * Database Definition Helper Functions
+ *
+ * This should be db agnostic as we define them in ADO.NET terms
+ *
+ **********************************************************************/
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void createCol(DataTable dt, string name, Type type)
+ {
+ DataColumn col = new DataColumn(name, type);
+ dt.Columns.Add(col);
+ }
+
+ /***********************************************************************
+ *
+ * SQL Statement Creation Functions
+ *
+ * These functions create SQL statements for update, insert, and create.
+ * They can probably be factored later to have a db independant
+ * portion and a db specific portion
+ *
+ **********************************************************************/
+
+ ///
+ /// Create an insert command
+ ///
+ /// table name
+ /// data table
+ /// the created command
+ ///
+ /// This is subtle enough to deserve some commentary.
+ /// Instead of doing *lots* and *lots of hardcoded strings
+ /// for database definitions we'll use the fact that
+ /// realistically all insert statements look like "insert
+ /// into A(b, c) values(:b, :c) on the parameterized query
+ /// front. If we just have a list of b, c, etc... we can
+ /// generate these strings instead of typing them out.
+ ///
+ public static SqliteCommand createInsertCommand(string table, DataTable dt)
+ {
+
+ string[] cols = new string[dt.Columns.Count];
+ for (int i = 0; i < dt.Columns.Count; i++)
+ {
+ DataColumn col = dt.Columns[i];
+ cols[i] = col.ColumnName;
+ }
+
+ string sql = "insert into " + table + "(";
+ sql += String.Join(", ", cols);
+ // important, the first ':' needs to be here, the rest get added in the join
+ sql += ") values (:";
+ sql += String.Join(", :", cols);
+ sql += ")";
+ SqliteCommand cmd = new SqliteCommand(sql);
+
+ // this provides the binding for all our parameters, so
+ // much less code than it used to be
+ foreach (DataColumn col in dt.Columns)
+ {
+ cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+ }
+ return cmd;
+ }
+
+ ///
+ /// create an update command
+ ///
+ /// table name
+ ///
+ ///
+ /// the created command
+ public static SqliteCommand createUpdateCommand(string table, string pk, DataTable dt)
+ {
+ string sql = "update " + table + " set ";
+ string subsql = String.Empty;
+ foreach (DataColumn col in dt.Columns)
+ {
+ if (subsql.Length > 0)
+ {
+ // a map function would rock so much here
+ subsql += ", ";
+ }
+ subsql += col.ColumnName + "= :" + col.ColumnName;
+ }
+ sql += subsql;
+ sql += " where " + pk;
+ SqliteCommand cmd = new SqliteCommand(sql);
+
+ // this provides the binding for all our parameters, so
+ // much less code than it used to be
+
+ foreach (DataColumn col in dt.Columns)
+ {
+ cmd.Parameters.Add(createSqliteParameter(col.ColumnName, col.DataType));
+ }
+ return cmd;
+ }
+
+ ///
+ ///
+ ///
+ /// Data Table
+ ///
+ public static string defineTable(DataTable dt)
+ {
+ string sql = "create table " + dt.TableName + "(";
+ string subsql = String.Empty;
+ foreach (DataColumn col in dt.Columns)
+ {
+ if (subsql.Length > 0)
+ {
+ // a map function would rock so much here
+ subsql += ",\n";
+ }
+ subsql += col.ColumnName + " " + sqliteType(col.DataType);
+ if (dt.PrimaryKey.Length > 0)
+ {
+ if (col == dt.PrimaryKey[0])
+ {
+ subsql += " primary key";
+ }
+ }
+ }
+ sql += subsql;
+ sql += ")";
+ return sql;
+ }
+
+ /***********************************************************************
+ *
+ * Database Binding functions
+ *
+ * These will be db specific due to typing, and minor differences
+ * in databases.
+ *
+ **********************************************************************/
+
+ ///
+ ///
+ /// This is a convenience function that collapses 5 repetitive
+ /// lines for defining SqliteParameters to 2 parameters:
+ /// column name and database type.
+ ///
+ ///
+ ///
+ /// It assumes certain conventions like :param as the param
+ /// name to replace in parametrized queries, and that source
+ /// version is always current version, both of which are fine
+ /// for us.
+ ///
+ ///
+ ///
+ ///
+ ///a built sqlite parameter
+ public static SqliteParameter createSqliteParameter(string name, Type type)
+ {
+ SqliteParameter param = new SqliteParameter();
+ param.ParameterName = ":" + name;
+ param.DbType = dbtypeFromType(type);
+ param.SourceColumn = name;
+ param.SourceVersion = DataRowVersion.Current;
+ return param;
+ }
+
+ /***********************************************************************
+ *
+ * Type conversion functions
+ *
+ **********************************************************************/
+
+ ///
+ /// Type conversion function
+ ///
+ /// a type
+ /// a DbType
+ public static DbType dbtypeFromType(Type type)
+ {
+ if (type == typeof (String))
+ {
+ return DbType.String;
+ }
+ else if (type == typeof (Int32))
+ {
+ return DbType.Int32;
+ }
+ else if (type == typeof (UInt32))
+ {
+ return DbType.UInt32;
+ }
+ else if (type == typeof (Int64))
+ {
+ return DbType.Int64;
+ }
+ else if (type == typeof (UInt64))
+ {
+ return DbType.UInt64;
+ }
+ else if (type == typeof (Double))
+ {
+ return DbType.Double;
+ }
+ else if (type == typeof (Boolean))
+ {
+ return DbType.Boolean;
+ }
+ else if (type == typeof (Byte[]))
+ {
+ return DbType.Binary;
+ }
+ else
+ {
+ return DbType.String;
+ }
+ }
+
+ ///
+ ///
+ /// a Type
+ /// a string
+ /// this is something we'll need to implement for each db slightly differently.
+ public static string sqliteType(Type type)
+ {
+ if (type == typeof (String))
+ {
+ return "varchar(255)";
+ }
+ else if (type == typeof (Int32))
+ {
+ return "integer";
+ }
+ else if (type == typeof (UInt32))
+ {
+ return "integer";
+ }
+ else if (type == typeof (Int64))
+ {
+ return "varchar(255)";
+ }
+ else if (type == typeof (UInt64))
+ {
+ return "varchar(255)";
+ }
+ else if (type == typeof (Double))
+ {
+ return "float";
+ }
+ else if (type == typeof (Boolean))
+ {
+ return "integer";
+ }
+ else if (type == typeof (Byte[]))
+ {
+ return "blob";
+ }
+ else
+ {
+ return "string";
+ }
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
new file mode 100644
index 0000000000..a66e0c6fe0
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Data;
+using System.Reflection;
+using System.Collections.Generic;
+using Mono.Data.SqliteClient;
+using log4net;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Data.SQLite
+{
+ ///
+ /// A MySQL Interface for the Asset Server
+ ///
+ public class SQLiteXInventoryData : IXInventoryData
+ {
+// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private SQLiteGenericTableHandler m_Folders;
+ private SqliteItemHandler m_Items;
+
+ public SQLiteXInventoryData(string conn, string realm)
+ {
+ m_Folders = new SQLiteGenericTableHandler(
+ conn, "inventoryfolders", "InventoryStore");
+ m_Items = new SqliteItemHandler(
+ conn, "inventoryitems", String.Empty);
+ }
+
+ public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
+ {
+ return m_Folders.Get(fields, vals);
+ }
+
+ public XInventoryItem[] GetItems(string[] fields, string[] vals)
+ {
+ return m_Items.Get(fields, vals);
+ }
+
+ public bool StoreFolder(XInventoryFolder folder)
+ {
+ return m_Folders.Store(folder);
+ }
+
+ public bool StoreItem(XInventoryItem item)
+ {
+ return m_Items.Store(item);
+ }
+
+ public bool DeleteFolders(string field, string val)
+ {
+ return m_Folders.Delete(field, val);
+ }
+
+ public bool DeleteItems(string field, string val)
+ {
+ return m_Items.Delete(field, val);
+ }
+
+ public bool MoveItem(string id, string newParent)
+ {
+ return m_Items.MoveItem(id, newParent);
+ }
+
+ public XInventoryItem[] GetActiveGestures(UUID principalID)
+ {
+ return m_Items.GetActiveGestures(principalID);
+ }
+
+ public int GetAssetPermissions(UUID principalID, UUID assetID)
+ {
+ return m_Items.GetAssetPermissions(principalID, assetID);
+ }
+ }
+
+ public class SqliteItemHandler : SQLiteGenericTableHandler
+ {
+ public SqliteItemHandler(string c, string t, string m) :
+ base(c, t, m)
+ {
+ }
+
+ public bool MoveItem(string id, string newParent)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where inventoryID = :InventoryID", m_Realm);
+ cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParent));
+ cmd.Parameters.Add(new SqliteParameter(":InventoryID", id));
+
+ return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
+ }
+
+ public XInventoryItem[] GetActiveGestures(UUID principalID)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+ cmd.CommandText = String.Format("select * from inventoryitems where avatarId = :uuid and assetType = :type and flags = 1", m_Realm);
+
+ cmd.Parameters.Add(new SqliteParameter(":uuid", principalID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":type", (int)AssetType.Gesture));
+
+ return DoQuery(cmd);
+ }
+
+ public int GetAssetPermissions(UUID principalID, UUID assetID)
+ {
+ SqliteCommand cmd = new SqliteCommand();
+
+ cmd.CommandText = String.Format("select inventoryCurrentPermissions from inventoryitems where avatarID = :PrincipalID and assetID = :AssetID", m_Realm);
+ cmd.Parameters.Add(new SqliteParameter(":PrincipalID", principalID.ToString()));
+ cmd.Parameters.Add(new SqliteParameter(":AssetID", assetID.ToString()));
+
+ IDataReader reader = ExecuteReader(cmd, m_Connection);
+
+ int perms = 0;
+
+ while (reader.Read())
+ {
+ perms |= Convert.ToInt32(reader["inventoryCurrentPermissions"]);
+ }
+
+ reader.Close();
+ CloseCommand(cmd);
+
+ return perms;
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs
new file mode 100644
index 0000000000..0c2f5dfefc
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+ [TestFixture, DatabaseTest]
+ public class SQLiteAssetTest : BasicAssetTest
+ {
+ public string file;
+ public string connect;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ // SQLite doesn't work on power or z linux
+ if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+ {
+ Assert.Ignore();
+ }
+
+ SuperInit();
+ file = Path.GetTempFileName() + ".db";
+ connect = "URI=file:" + file + ",version=3";
+ db = new SQLiteAssetData();
+ db.Initialise(connect);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ db.Dispose();
+ File.Delete(file);
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs
new file mode 100644
index 0000000000..30f66414a9
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+ [TestFixture, DatabaseTest]
+ public class SQLiteEstateTest : BasicEstateTest
+ {
+ public string file = "regiontest.db";
+ public string connect;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ // SQLite doesn't work on power or z linux
+ if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+ {
+ Assert.Ignore();
+ }
+
+ SuperInit();
+ file = Path.GetTempFileName() + ".db";
+ connect = "URI=file:" + file + ",version=3";
+ db = new SQLiteEstateStore();
+ db.Initialise(connect);
+ regionDb = new SQLiteRegionData();
+ regionDb.Initialise(connect);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ regionDb.Dispose();
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs
new file mode 100644
index 0000000000..98458a30ec
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+ [TestFixture, DatabaseTest]
+ public class SQLiteInventoryTest : BasicInventoryTest
+ {
+ public string file;
+ public string connect;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ // SQLite doesn't work on power or z linux
+ if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+ {
+ Assert.Ignore();
+ }
+
+ SuperInit();
+
+ file = Path.GetTempFileName() + ".db";
+ connect = "URI=file:" + file + ",version=3";
+
+ db = new SQLiteInventoryStore();
+ db.Initialise(connect);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ db.Dispose();
+ File.Delete(file);
+ }
+ }
+}
diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs
new file mode 100644
index 0000000000..abb97cfa4f
--- /dev/null
+++ b/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System.IO;
+using NUnit.Framework;
+using OpenSim.Data.Tests;
+using OpenSim.Tests.Common;
+
+namespace OpenSim.Data.SQLite.Tests
+{
+ [TestFixture, DatabaseTest]
+ public class SQLiteRegionTest : BasicRegionTest
+ {
+ public string file = "regiontest.db";
+ public string connect;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ // SQLite doesn't work on power or z linux
+ if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
+ {
+ Assert.Ignore();
+ }
+
+ SuperInit();
+ file = Path.GetTempFileName() + ".db";
+ connect = "URI=file:" + file + ",version=3";
+ db = new SQLiteRegionData();
+ db.Initialise(connect);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ db.Dispose();
+ File.Delete(file);
+ }
+ }
+}
diff --git a/prebuild.xml b/prebuild.xml
index 5cc742c45a..d6b6361182 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -2215,6 +2215,43 @@
+
+
+
+ ../../../bin/
+
+
+
+
+ ../../../bin/
+
+
+
+ ../../../bin/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+