From 959cd6022504fa3ffe2f69c66ed94827f6ae6951 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 23 Apr 2010 17:17:15 +0100 Subject: [PATCH 01/34] Duplicate OpenSim.Data.SQLite into OpenSim.Data.SQLiteNG. SQLiteNG will shortly be changed to work under mono 2.6 and above --- .../Data/SQLiteNG/Properties/AssemblyInfo.cs | 65 + .../SQLiteNG/Resources/001_AssetStore.sql | 12 + .../Data/SQLiteNG/Resources/001_AuthStore.sql | 18 + .../Data/SQLiteNG/Resources/001_Avatar.sql | 9 + .../SQLiteNG/Resources/001_FriendsStore.sql | 10 + .../SQLiteNG/Resources/001_InventoryStore.sql | 32 + .../SQLiteNG/Resources/001_RegionStore.sql | 144 ++ .../SQLiteNG/Resources/001_UserAccount.sql | 17 + .../Data/SQLiteNG/Resources/001_UserStore.sql | 39 + .../SQLiteNG/Resources/002_AssetStore.sql | 10 + .../Data/SQLiteNG/Resources/002_AuthStore.sql | 5 + .../SQLiteNG/Resources/002_FriendsStore.sql | 5 + .../SQLiteNG/Resources/002_InventoryStore.sql | 8 + .../SQLiteNG/Resources/002_RegionStore.sql | 10 + .../SQLiteNG/Resources/002_UserAccount.sql | 5 + .../Data/SQLiteNG/Resources/002_UserStore.sql | 5 + .../SQLiteNG/Resources/003_AssetStore.sql | 1 + .../SQLiteNG/Resources/003_InventoryStore.sql | 5 + .../SQLiteNG/Resources/003_RegionStore.sql | 5 + .../Data/SQLiteNG/Resources/003_UserStore.sql | 6 + .../SQLiteNG/Resources/004_AssetStore.sql | 7 + .../SQLiteNG/Resources/004_InventoryStore.sql | 36 + .../SQLiteNG/Resources/004_RegionStore.sql | 38 + .../Data/SQLiteNG/Resources/004_UserStore.sql | 6 + .../SQLiteNG/Resources/005_RegionStore.sql | 5 + .../Data/SQLiteNG/Resources/005_UserStore.sql | 5 + .../SQLiteNG/Resources/006_RegionStore.sql | 102 + .../Data/SQLiteNG/Resources/006_UserStore.sql | 20 + .../SQLiteNG/Resources/007_RegionStore.sql | 8 + .../Data/SQLiteNG/Resources/007_UserStore.sql | 7 + .../SQLiteNG/Resources/008_RegionStore.sql | 6 + .../Data/SQLiteNG/Resources/008_UserStore.sql | 5 + .../SQLiteNG/Resources/009_RegionStore.sql | 8 + .../Data/SQLiteNG/Resources/009_UserStore.sql | 11 + .../SQLiteNG/Resources/010_RegionStore.sql | 5 + .../Data/SQLiteNG/Resources/010_UserStore.sql | 37 + .../SQLiteNG/Resources/011_RegionStore.sql | 28 + .../SQLiteNG/Resources/012_RegionStore.sql | 5 + .../SQLiteNG/Resources/013_RegionStore.sql | 6 + .../SQLiteNG/Resources/014_RegionStore.sql | 8 + .../SQLiteNG/Resources/015_RegionStore.sql | 6 + .../SQLiteNG/Resources/016_RegionStore.sql | 5 + .../SQLiteNG/Resources/017_RegionStore.sql | 8 + .../SQLiteNG/Resources/018_RegionStore.sql | 79 + .../Resources/OpenSim.Data.SQLite.addin.xml | 20 + OpenSim/Data/SQLiteNG/SQLiteAssetData.cs | 343 +++ .../Data/SQLiteNG/SQLiteAuthenticationData.cs | 262 ++ OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs | 74 + OpenSim/Data/SQLiteNG/SQLiteEstateData.cs | 387 +++ OpenSim/Data/SQLiteNG/SQLiteFramework.cs | 91 + OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs | 70 + .../SQLiteNG/SQLiteGenericTableHandler.cs | 268 ++ OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs | 898 +++++++ OpenSim/Data/SQLiteNG/SQLiteRegionData.cs | 2264 +++++++++++++++++ .../Data/SQLiteNG/SQLiteUserAccountData.cs | 81 + OpenSim/Data/SQLiteNG/SQLiteUtils.cs | 307 +++ OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs | 155 ++ .../Data/SQLiteNG/Tests/SQLiteAssetTest.cs | 64 + .../Data/SQLiteNG/Tests/SQLiteEstateTest.cs | 65 + .../SQLiteNG/Tests/SQLiteInventoryTest.cs | 66 + .../Data/SQLiteNG/Tests/SQLiteRegionTest.cs | 64 + prebuild.xml | 37 + 62 files changed, 6378 insertions(+) create mode 100644 OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql create mode 100644 OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAssetData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteEstateData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteFramework.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteRegionData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteUtils.cs create mode 100644 OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs create mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs 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 6b2579248e..9db30fffbd 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2510,6 +2510,43 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + From 7ce0ec874a31d2567bee43afa0cdec24e002dc1d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 23 Apr 2010 18:56:50 +0100 Subject: [PATCH 02/34] Change SQLiteNG to work with mono 2.6 and above using the Mono.Data.Sqlite.dll Include the library so that Windows builds correctly It appears that Windows is okay with either SQLite or SQLiteNG Incorporate the latest fixes made by Diva to OpenSim.Data.SQLite --- OpenSim/Data/SQLiteNG/SQLiteAssetData.cs | 6 +- .../Data/SQLiteNG/SQLiteAuthenticationData.cs | 23 +- OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs | 8 +- OpenSim/Data/SQLiteNG/SQLiteEstateData.cs | 48 +-- OpenSim/Data/SQLiteNG/SQLiteFramework.cs | 14 +- OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs | 8 +- .../SQLiteNG/SQLiteGenericTableHandler.cs | 18 +- OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs | 13 +- OpenSim/Data/SQLiteNG/SQLiteRegionData.cs | 276 +++++++++++------- .../Data/SQLiteNG/SQLiteUserAccountData.cs | 4 +- OpenSim/Data/SQLiteNG/SQLiteUtils.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs | 4 +- .../Data/SQLiteNG/Tests/SQLiteAssetTest.cs | 64 ---- .../Data/SQLiteNG/Tests/SQLiteEstateTest.cs | 65 ----- .../SQLiteNG/Tests/SQLiteInventoryTest.cs | 66 ----- .../Data/SQLiteNG/Tests/SQLiteRegionTest.cs | 64 ---- prebuild.xml | 3 +- 17 files changed, 246 insertions(+), 440 deletions(-) delete mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs delete mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs delete mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs delete mode 100644 OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs index a032670588..636bf8645b 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs @@ -30,7 +30,7 @@ using System.Data; using System.Reflection; using System.Collections.Generic; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; @@ -137,7 +137,7 @@ namespace OpenSim.Data.SQLite 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(); } } @@ -340,4 +340,4 @@ namespace OpenSim.Data.SQLite #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs index aa10734d50..086ac0a972 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -56,13 +56,8 @@ namespace OpenSim.Data.SQLite 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(); - } + Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore"); + m.Update(); m_initialized = true; } @@ -113,7 +108,7 @@ namespace OpenSim.Data.SQLite } finally { - CloseCommand(cmd); + //CloseCommand(cmd); } return null; @@ -156,14 +151,14 @@ namespace OpenSim.Data.SQLite { if (ExecuteNonQuery(cmd, m_Connection) < 1) { - CloseCommand(cmd); + //CloseCommand(cmd); return false; } } catch (Exception e) { Console.WriteLine(e.ToString()); - CloseCommand(cmd); + //CloseCommand(cmd); return false; } } @@ -184,19 +179,19 @@ namespace OpenSim.Data.SQLite { if (ExecuteNonQuery(cmd, m_Connection) < 1) { - CloseCommand(cmd); + //CloseCommand(cmd); return false; } } catch (Exception e) { Console.WriteLine(e.ToString()); - CloseCommand(cmd); + //CloseCommand(cmd); return false; } } - CloseCommand(cmd); + //CloseCommand(cmd); return true; } diff --git a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs index b3f4a4c077..c093884db4 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs @@ -33,7 +33,7 @@ using System.Threading; using log4net; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -55,8 +55,8 @@ namespace OpenSim.Data.SQLite 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); + cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue(":Name", name); try { @@ -67,7 +67,7 @@ namespace OpenSim.Data.SQLite } finally { - CloseCommand(cmd); + //CloseCommand(cmd); } } } diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs index bd6b776f80..9dd4a2e69b 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -62,8 +62,8 @@ namespace OpenSim.Data.SQLite Migration m = new Migration(m_connection, assem, "EstateStore"); m.Update(); - m_connection.Close(); - m_connection.Open(); + //m_connection.Close(); + // m_connection.Open(); Type t = typeof(EstateSettings); m_Fields = t.GetFields(BindingFlags.NonPublic | @@ -87,7 +87,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.Add(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); return DoLoad(cmd, regionID, create); } @@ -143,13 +143,13 @@ namespace OpenSim.Data.SQLite if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.Add(":"+name, "1"); + cmd.Parameters.AddWithValue(":"+name, "1"); else - cmd.Parameters.Add(":"+name, "0"); + cmd.Parameters.AddWithValue(":"+name, "0"); } else { - cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -167,8 +167,8 @@ namespace OpenSim.Data.SQLite r.Close(); cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; - cmd.Parameters.Add(":RegionID", regionID.ToString()); - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); // This will throw on dupe key try @@ -211,13 +211,13 @@ namespace OpenSim.Data.SQLite if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.Add(":"+name, "1"); + cmd.Parameters.AddWithValue(":"+name, "1"); else - cmd.Parameters.Add(":"+name, "0"); + cmd.Parameters.AddWithValue(":"+name, "0"); } else { - cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -236,7 +236,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", es.EstateID); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID); IDataReader r = cmd.ExecuteReader(); @@ -260,7 +260,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from estateban where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -270,8 +270,8 @@ namespace OpenSim.Data.SQLite foreach (EstateBan b in es.EstateBans) { - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); - cmd.Parameters.Add(":bannedUUID", b.BannedUserID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -283,7 +283,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -293,8 +293,8 @@ namespace OpenSim.Data.SQLite foreach (UUID uuid in data) { - cmd.Parameters.Add(":EstateID", EstateID.ToString()); - cmd.Parameters.Add(":uuid", uuid.ToString()); + cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -308,7 +308,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", EstateID); + cmd.Parameters.AddWithValue(":EstateID", EstateID); IDataReader r = cmd.ExecuteReader(); @@ -333,7 +333,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.Add(":EstateID", estateID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); return DoLoad(cmd, UUID.Zero, false); } @@ -347,7 +347,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.Add(":EstateName", search); + cmd.Parameters.AddWithValue(":EstateName", search); IDataReader r = cmd.ExecuteReader(); @@ -365,8 +365,8 @@ namespace OpenSim.Data.SQLite 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()); + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); if (cmd.ExecuteNonQuery() == 0) return false; diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs index 20b508515a..cf114d1a07 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -55,11 +55,14 @@ namespace OpenSim.Data.SQLite { lock (connection) { +/* SqliteConnection newConnection = (SqliteConnection)((ICloneable)connection).Clone(); newConnection.Open(); cmd.Connection = newConnection; +*/ + cmd.Connection = connection; //Console.WriteLine("XXX " + cmd.CommandText); return cmd.ExecuteNonQuery(); @@ -70,11 +73,12 @@ namespace OpenSim.Data.SQLite { lock (connection) { - SqliteConnection newConnection = - (SqliteConnection)((ICloneable)connection).Clone(); - newConnection.Open(); + //SqliteConnection newConnection = + // (SqliteConnection)((ICloneable)connection).Clone(); + //newConnection.Open(); - cmd.Connection = newConnection; + //cmd.Connection = newConnection; + cmd.Connection = connection; //Console.WriteLine("XXX " + cmd.CommandText); return cmd.ExecuteReader(); diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs index 0b121826d6..b06853ce68 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite 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()); + cmd.Parameters.AddWithValue(":PrincipalID", userID.ToString()); return DoQuery(cmd); @@ -58,8 +58,8 @@ namespace OpenSim.Data.SQLite 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); + cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue(":Friend", friend); ExecuteNonQuery(cmd, cmd.Connection); diff --git a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs index b39bb19fb7..3c70aeffc4 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -59,19 +59,21 @@ namespace OpenSim.Data.SQLite if (!m_initialized) { m_Connection = new SqliteConnection(connectionString); + Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString)); m_Connection.Open(); if (storeName != String.Empty) { Assembly assem = GetType().Assembly; - SqliteConnection newConnection = - (SqliteConnection)((ICloneable)m_Connection).Clone(); - newConnection.Open(); + //SqliteConnection newConnection = + // (SqliteConnection)((ICloneable)m_Connection).Clone(); + //newConnection.Open(); - Migration m = new Migration(newConnection, assem, storeName); + //Migration m = new Migration(newConnection, assem, storeName); + Migration m = new Migration(m_Connection, assem, storeName); m.Update(); - newConnection.Close(); - newConnection.Dispose(); + //newConnection.Close(); + //newConnection.Dispose(); } m_initialized = true; @@ -197,7 +199,7 @@ namespace OpenSim.Data.SQLite result.Add(row); } - CloseCommand(cmd); + //CloseCommand(cmd); return result.ToArray(); } diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs index a5e051726e..ece2495c2b 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; @@ -98,11 +98,13 @@ namespace OpenSim.Data.SQLite ds.Tables.Add(createInventoryFoldersTable()); invFoldersDa.Fill(ds.Tables["inventoryfolders"]); setupFoldersCommands(invFoldersDa, conn); + CreateDataSetMapping(invFoldersDa, "inventoryfolders"); m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); ds.Tables.Add(createInventoryItemsTable()); invItemsDa.Fill(ds.Tables["inventoryitems"]); setupItemsCommands(invItemsDa, conn); + CreateDataSetMapping(invItemsDa, "inventoryitems"); m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); ds.AcceptChanges(); @@ -728,6 +730,15 @@ namespace OpenSim.Data.SQLite * **********************************************************************/ + protected void CreateDataSetMapping(IDataAdapter da, string tableName) + { + ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); + foreach (DataColumn col in ds.Tables[tableName].Columns) + { + dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + } + /// /// Create the "inventoryitems" table /// diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs index d2ba9ae298..bad8adc425 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs @@ -32,7 +32,7 @@ using System.Drawing; using System.IO; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -87,119 +87,139 @@ namespace OpenSim.Data.SQLite /// 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) + try { - ds.Tables.Add(createPrimTable()); - setupPrimCommands(primDa, m_conn); - primDa.Fill(ds.Tables["prims"]); + m_connectionString = connectionString; - ds.Tables.Add(createShapeTable()); - setupShapeCommands(shapeDa, m_conn); + ds = new DataSet("Region"); - ds.Tables.Add(createItemsTable()); - setupItemsCommands(itemsDa, m_conn); - itemsDa.Fill(ds.Tables["primitems"]); + m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString); + m_conn = new SqliteConnection(m_connectionString); + m_conn.Open(); - ds.Tables.Add(createTerrainTable()); - setupTerrainCommands(terrainDa, m_conn); + SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); + //SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); + //primDa = new SqliteDataAdapter(primSelectCmd); + primDa = new SqliteDataAdapter(primSelect, m_connectionString); + // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); - ds.Tables.Add(createLandTable()); - setupLandCommands(landDa, m_conn); + SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); + shapeDa = new SqliteDataAdapter(shapeSelectCmd); + // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); - ds.Tables.Add(createLandAccessListTable()); - setupLandAccessCommands(landAccessListDa, m_conn); + SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn); + itemsDa = new SqliteDataAdapter(itemsSelectCmd); - ds.Tables.Add(createRegionSettingsTable()); - - setupRegionSettingsCommands(regionSettingsDa, m_conn); + SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn); + terrainDa = new SqliteDataAdapter(terrainSelectCmd); - // 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 + 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) { - shapeDa.Fill(ds.Tables["primshapes"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on primshapes table"); - } + //ds.Tables.Add(createPrimTable()); + //setupPrimCommands(primDa, m_conn); + //primDa.Fill(ds.Tables["prims"]); + primDa.Fill(ds, "prims"); - try - { - terrainDa.Fill(ds.Tables["terrain"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on terrain table"); - } + ds.Tables.Add(createShapeTable()); + setupShapeCommands(shapeDa, m_conn); - try - { - landDa.Fill(ds.Tables["land"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on land table"); - } + ds.Tables.Add(createItemsTable()); + setupItemsCommands(itemsDa, m_conn); + itemsDa.Fill(ds.Tables["primitems"]); - try - { - landAccessListDa.Fill(ds.Tables["landaccesslist"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on landaccesslist table"); - } + ds.Tables.Add(createTerrainTable()); + setupTerrainCommands(terrainDa, m_conn); - try - { - regionSettingsDa.Fill(ds.Tables["regionsettings"]); + 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"); + } + + // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! + // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409 + CreateDataSetMapping(primDa, "prims"); + CreateDataSetMapping(shapeDa, "primshapes"); + CreateDataSetMapping(itemsDa, "primitems"); + CreateDataSetMapping(terrainDa, "terrain"); + CreateDataSetMapping(landDa, "land"); + CreateDataSetMapping(landAccessListDa, "landaccesslist"); + CreateDataSetMapping(regionSettingsDa, "regionsettings"); } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on regionsettings table"); - } - return; } + catch (Exception e) + { + m_log.Error(e); + Environment.Exit(23); + } + + return; } public void Dispose() @@ -603,7 +623,7 @@ namespace OpenSim.Data.SQLite } } } - rev = (int) row["Revision"]; + rev = Convert.ToInt32(row["Revision"]); } else { @@ -755,6 +775,7 @@ namespace OpenSim.Data.SQLite /// public void Commit() { + m_log.Debug("[SQLITE]: Starting commit"); lock (ds) { primDa.Update(ds, "prims"); @@ -769,18 +790,11 @@ namespace OpenSim.Data.SQLite { regionSettingsDa.Update(ds, "regionsettings"); } - catch (SqliteExecutionException SqlEx) + catch (SqliteException 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; - } + 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); } ds.AcceptChanges(); } @@ -802,6 +816,15 @@ namespace OpenSim.Data.SQLite * **********************************************************************/ + protected void CreateDataSetMapping(IDataAdapter da, string tableName) + { + ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); + foreach (DataColumn col in ds.Tables[tableName].Columns) + { + dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + } + /// /// /// @@ -1964,6 +1987,7 @@ namespace OpenSim.Data.SQLite sql += ") values (:"; sql += String.Join(", :", cols); sql += ")"; + m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); SqliteCommand cmd = new SqliteCommand(sql); // this provides the binding for all our parameters, so @@ -2259,6 +2283,36 @@ namespace OpenSim.Data.SQLite return DbType.String; } } + + static void PrintDataSet(DataSet ds) + { + // Print out any name and extended properties. + Console.WriteLine("DataSet is named: {0}", ds.DataSetName); + foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties) + { + Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); + } + Console.WriteLine(); + foreach (DataTable dt in ds.Tables) + { + Console.WriteLine("=> {0} Table:", dt.TableName); + // Print out the column names. + for (int curCol = 0; curCol < dt.Columns.Count; curCol++) + { + Console.Write(dt.Columns[curCol].ColumnName + "\t"); + } + Console.WriteLine("\n----------------------------------"); + // Print the DataTable. + for (int curRow = 0; curRow < dt.Rows.Count; curRow++) + { + for (int curCol = 0; curCol < dt.Columns.Count; curCol++) + { + Console.Write(dt.Rows[curRow][curCol].ToString() + "\t"); + } + Console.WriteLine(); + } + } + } } } diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs index 67cf7165b1..893f105604 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -66,7 +66,7 @@ namespace OpenSim.Data.SQLite 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}%')", + 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 diff --git a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs index 4a835ce52f..07c6b69a3b 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs @@ -27,7 +27,7 @@ using System; using System.Data; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs index a66e0c6fe0..be1d0412fd 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs @@ -29,7 +29,7 @@ using System; using System.Data; using System.Reflection; using System.Collections.Generic; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using log4net; using OpenMetaverse; using OpenSim.Framework; @@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLite } reader.Close(); - CloseCommand(cmd); + //CloseCommand(cmd); return perms; } diff --git a/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs b/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs deleted file mode 100644 index 0c2f5dfefc..0000000000 --- a/OpenSim/Data/SQLiteNG/Tests/SQLiteAssetTest.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 deleted file mode 100644 index 30f66414a9..0000000000 --- a/OpenSim/Data/SQLiteNG/Tests/SQLiteEstateTest.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 deleted file mode 100644 index 98458a30ec..0000000000 --- a/OpenSim/Data/SQLiteNG/Tests/SQLiteInventoryTest.cs +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 deleted file mode 100644 index abb97cfa4f..0000000000 --- a/OpenSim/Data/SQLiteNG/Tests/SQLiteRegionTest.cs +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 9db30fffbd..7c7e3c7f27 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2526,7 +2526,6 @@ - @@ -2534,7 +2533,7 @@ - + From 362007e5d352d3eafcc260a2270fa8833d2bbf05 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 23 Apr 2010 19:14:43 +0100 Subject: [PATCH 03/34] minor: correct the assembly information for SQLiteNG --- OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs index d45ab5092a..4aeb67b375 100644 --- a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs @@ -32,11 +32,11 @@ using System.Runtime.InteropServices; // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly : AssemblyTitle("OpenSim.Data.SQLite")] +[assembly : AssemblyTitle("OpenSim.Data.SQLiteNG")] [assembly : AssemblyDescription("")] [assembly : AssemblyConfiguration("")] [assembly : AssemblyCompany("http://opensimulator.org")] -[assembly : AssemblyProduct("OpenSim.Data.SQLite")] +[assembly : AssemblyProduct("OpenSim.Data.SQLiteNG")] [assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] [assembly : AssemblyTrademark("")] [assembly : AssemblyCulture("")] From a90054aa16c8e968a6866cf850d16fde0b20957d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey Date: Fri, 23 Apr 2010 19:40:15 +0100 Subject: [PATCH 04/34] put SQLiteNG classes in their own namespace to avoid confusion --- OpenSim/Data/SQLiteNG/SQLiteAssetData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteEstateData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteFramework.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteRegionData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteUtils.cs | 2 +- OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs index 636bf8645b..9b34a21592 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs @@ -34,7 +34,7 @@ using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// An asset storage interface for the SQLite database system diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs index 086ac0a972..4a5dc2eeba 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData { diff --git a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs index c093884db4..d0fd49c5ae 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs @@ -35,7 +35,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// A SQLite Interface for Avatar Data diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs index 9dd4a2e69b..2e2d717cc9 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs @@ -35,7 +35,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { public class SQLiteEstateStore : IEstateDataStore { diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs index cf114d1a07..f0ddc597bd 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteFramework.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// A database interface class to a user profile storage system diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs index b06853ce68..702a1d8643 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { public class SQLiteFriendsData : SQLiteGenericTableHandler, IFriendsData { diff --git a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs index 3c70aeffc4..632c5bf8c9 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs @@ -35,7 +35,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { public class SQLiteGenericTableHandler : SQLiteFramework where T: class, new() { diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs index ece2495c2b..9207ca3cc4 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs @@ -34,7 +34,7 @@ using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// An Inventory Interface to the SQLite database diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs index bad8adc425..ee454db5e3 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs @@ -38,7 +38,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// A RegionData Interface to the SQLite database diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs index 893f105604..f77159c772 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { public class SQLiteUserAccountData : SQLiteGenericTableHandler, IUserAccountData { diff --git a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs index 07c6b69a3b..82a2e37993 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteUtils.cs @@ -29,7 +29,7 @@ using System; using System.Data; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// A base class for methods needed by all SQLite database classes diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs index be1d0412fd..a0c17f8fd9 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs @@ -34,7 +34,7 @@ using log4net; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLite +namespace OpenSim.Data.SQLiteNG { /// /// A MySQL Interface for the Asset Server From b46380e373d9757174738ea3bb7dc2be6dbcb68b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 23 Apr 2010 20:08:24 +0100 Subject: [PATCH 05/34] dispose of the DbCommand used to execute migrations after we've finished with it rather than within the loop disposing of it within the loop causes Mono.Data.Sqlite.dll to get upset, and it's the wrong behaviour anyway --- OpenSim/Data/Migration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index e51dc22d94..2878fd09d3 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -149,8 +149,9 @@ namespace OpenSim.Data UpdateVersion(_type, newversion); } version = newversion; - cmd.Dispose(); } + + cmd.Dispose(); } // private int MaxVersion() From 705b675d281aa9e93e2ad9929783822a4fe234fc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 23 Apr 2010 20:56:24 +0100 Subject: [PATCH 06/34] get region prim saving working properly in SQLiteNG it wasn't working because of debug work that I'd forgotton to take out --- OpenSim/Data/SQLiteNG/SQLiteRegionData.cs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs index ee454db5e3..289d626543 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs @@ -98,10 +98,7 @@ namespace OpenSim.Data.SQLiteNG m_conn.Open(); SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); - //SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); - //primDa = new SqliteDataAdapter(primSelectCmd); - primDa = new SqliteDataAdapter(primSelect, m_connectionString); - // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); + primDa = new SqliteDataAdapter(primSelectCmd); SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); shapeDa = new SqliteDataAdapter(shapeSelectCmd); @@ -128,17 +125,14 @@ namespace OpenSim.Data.SQLiteNG lock (ds) { - //ds.Tables.Add(createPrimTable()); - //setupPrimCommands(primDa, m_conn); - //primDa.Fill(ds.Tables["prims"]); - primDa.Fill(ds, "prims"); + ds.Tables.Add(createPrimTable()); + setupPrimCommands(primDa, m_conn); 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); @@ -150,13 +144,21 @@ namespace OpenSim.Data.SQLiteNG 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 + { + primDa.Fill(ds.Tables["prims"]); + } + catch (Exception) + { + m_log.Info("[REGION DB]: Caught fill error on prims table"); + } + try { shapeDa.Fill(ds.Tables["primshapes"]); @@ -204,6 +206,7 @@ namespace OpenSim.Data.SQLiteNG // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409 + // Possibly because we manually set up our own DataTables before connecting to the database CreateDataSetMapping(primDa, "prims"); CreateDataSetMapping(shapeDa, "primshapes"); CreateDataSetMapping(itemsDa, "primitems"); From 955db6e4bee8973def97340018316825fb46abb3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 19:12:47 +0100 Subject: [PATCH 07/34] add Mono.Data.Sqlite.dll --- bin/Mono.Data.Sqlite.dll | Bin 0 -> 169984 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 bin/Mono.Data.Sqlite.dll diff --git a/bin/Mono.Data.Sqlite.dll b/bin/Mono.Data.Sqlite.dll new file mode 100644 index 0000000000000000000000000000000000000000..4f69e0d4af194f53d9460b56f5c492b6b24cc452 GIT binary patch literal 169984 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 Date: Fri, 30 Apr 2010 17:45:00 +0100 Subject: [PATCH 08/34] rename SQLiteNG to SQLite and SQLite to SQLiteLegacy this seems the least evil way forward since mono 2.6 and later will see increasing usage, and this only works with what was SQLiteNG MAC USERS WILL NEED TO CHANGE REFERENCES TO "OpenSim.Data.SQLite.dll" to "OpenSim.Data.SQLiteLegacy.dll" in OpenSim.ini and config-include/StandaloneCommon.ini (if using standalone) See the OpenSim.ini.example and StandaloneCommon.ini.example files for more details This commit also temporarily changes unsigned ParentEstateID values in the OpenSim.Data.Tests to signed temporarily, since the new plugin enforces creation of signed fields in the database (which is what the SQL actually specifies). And change data columns in sqlite is a pita. --- OpenSim/Data/SQLite/SQLiteAssetData.cs | 4 +- .../SQLiteAuthenticationData.cs | 2 +- OpenSim/Data/SQLite/SQLiteEstateData.cs | 101 ++++-- OpenSim/Data/SQLite/SQLiteFramework.cs | 29 +- .../{SQLiteNG => SQLite}/SQLiteFriendsData.cs | 2 +- .../Data/SQLite/SQLiteGenericTableHandler.cs | 26 +- OpenSim/Data/SQLite/SQLiteInventoryStore.cs | 25 +- OpenSim/Data/SQLite/SQLiteRegionData.cs | 279 ++++++++++------- .../SQLiteUserAccountData.cs | 2 +- OpenSim/Data/SQLite/SQLiteUtils.cs | 2 +- OpenSim/Data/SQLite/SQLiteXInventoryData.cs | 6 +- .../Properties/AssemblyInfo.cs | 4 +- .../Resources/001_AssetStore.sql | 0 .../Resources/001_AuthStore.sql | 0 .../Resources/001_Avatar.sql | 0 .../Resources/001_FriendsStore.sql | 0 .../Resources/001_InventoryStore.sql | 0 .../Resources/001_RegionStore.sql | 0 .../Resources/001_UserAccount.sql | 0 .../Resources/001_UserStore.sql | 0 .../Resources/002_AssetStore.sql | 0 .../Resources/002_AuthStore.sql | 0 .../Resources/002_FriendsStore.sql | 0 .../Resources/002_InventoryStore.sql | 0 .../Resources/002_RegionStore.sql | 0 .../Resources/002_UserAccount.sql | 0 .../Resources/002_UserStore.sql | 0 .../Resources/003_AssetStore.sql | 0 .../Resources/003_InventoryStore.sql | 0 .../Resources/003_RegionStore.sql | 0 .../Resources/003_UserStore.sql | 0 .../Resources/004_AssetStore.sql | 0 .../Resources/004_InventoryStore.sql | 0 .../Resources/004_RegionStore.sql | 0 .../Resources/004_UserStore.sql | 0 .../Resources/005_RegionStore.sql | 0 .../Resources/005_UserStore.sql | 0 .../Resources/006_RegionStore.sql | 0 .../Resources/006_UserStore.sql | 0 .../Resources/007_RegionStore.sql | 0 .../Resources/007_UserStore.sql | 0 .../Resources/008_RegionStore.sql | 0 .../Resources/008_UserStore.sql | 0 .../Resources/009_RegionStore.sql | 0 .../Resources/009_UserStore.sql | 0 .../Resources/010_RegionStore.sql | 0 .../Resources/010_UserStore.sql | 0 .../Resources/011_RegionStore.sql | 0 .../Resources/012_RegionStore.sql | 0 .../Resources/013_RegionStore.sql | 0 .../Resources/014_RegionStore.sql | 0 .../Resources/015_RegionStore.sql | 0 .../Resources/016_RegionStore.sql | 0 .../Resources/017_RegionStore.sql | 0 .../Resources/018_RegionStore.sql | 0 .../Resources/OpenSim.Data.SQLite.addin.xml | 0 .../SQLiteAssetData.cs | 8 +- .../SQLiteLegacy/SQLiteAuthenticationData.cs | 262 ++++++++++++++++ .../SQLiteAvatarData.cs | 10 +- .../SQLiteEstateData.cs | 50 +-- .../SQLiteFramework.cs | 16 +- .../Data/SQLiteLegacy/SQLiteFriendsData.cs | 70 +++++ .../SQLiteGenericTableHandler.cs | 20 +- .../SQLiteInventoryStore.cs | 15 +- .../SQLiteRegionData.cs | 289 +++++++----------- .../SQLiteLegacy/SQLiteUserAccountData.cs | 81 +++++ .../{SQLiteNG => SQLiteLegacy}/SQLiteUtils.cs | 4 +- .../SQLiteXInventoryData.cs | 6 +- OpenSim/Data/Tests/DataTestUtil.cs | 3 +- bin/OpenSim.ini.example | 10 +- .../StandaloneCommon.ini.example | 12 +- prebuild.xml | 4 +- 72 files changed, 946 insertions(+), 396 deletions(-) rename OpenSim/Data/{SQLiteNG => SQLite}/SQLiteAuthenticationData.cs (99%) rename OpenSim/Data/{SQLiteNG => SQLite}/SQLiteFriendsData.cs (98%) rename OpenSim/Data/{SQLiteNG => SQLite}/SQLiteUserAccountData.cs (99%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Properties/AssemblyInfo.cs (96%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_AssetStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_AuthStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_Avatar.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_FriendsStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_InventoryStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_UserAccount.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/001_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_AssetStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_AuthStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_FriendsStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_InventoryStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_UserAccount.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/002_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/003_AssetStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/003_InventoryStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/003_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/003_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/004_AssetStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/004_InventoryStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/004_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/004_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/005_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/005_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/006_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/006_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/007_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/007_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/008_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/008_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/009_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/009_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/010_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/010_UserStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/011_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/012_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/013_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/014_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/015_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/016_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/017_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/018_RegionStore.sql (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/Resources/OpenSim.Data.SQLite.addin.xml (100%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteAssetData.cs (99%) create mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteAuthenticationData.cs rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteAvatarData.cs (92%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteEstateData.cs (87%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteFramework.cs (89%) create mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteGenericTableHandler.cs (93%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteInventoryStore.cs (98%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteRegionData.cs (91%) create mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteUtils.cs (99%) rename OpenSim/Data/{SQLiteNG => SQLiteLegacy}/SQLiteXInventoryData.cs (98%) diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index c52f60b2c0..373c903b8c 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -30,7 +30,7 @@ using System.Data; using System.Reflection; using System.Collections.Generic; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; @@ -339,4 +339,4 @@ namespace OpenSim.Data.SQLite #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs similarity index 99% rename from OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs rename to OpenSim/Data/SQLite/SQLiteAuthenticationData.cs index 4a5dc2eeba..086ac0a972 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAuthenticationData.cs +++ b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLite { public class SQLiteAuthenticationData : SQLiteFramework, IAuthenticationData { diff --git a/OpenSim/Data/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs index 1be99eedab..ad4e2a26aa 100644 --- a/OpenSim/Data/SQLite/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -62,8 +62,8 @@ namespace OpenSim.Data.SQLite Migration m = new Migration(m_connection, assem, "EstateStore"); m.Update(); - m_connection.Close(); - m_connection.Open(); + //m_connection.Close(); + // m_connection.Open(); Type t = typeof(EstateSettings); m_Fields = t.GetFields(BindingFlags.NonPublic | @@ -90,7 +90,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.Add(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); IDataReader r = cmd.ExecuteReader(); @@ -140,13 +140,13 @@ namespace OpenSim.Data.SQLite if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.Add(":"+name, "1"); + cmd.Parameters.AddWithValue(":"+name, "1"); else - cmd.Parameters.Add(":"+name, "0"); + cmd.Parameters.AddWithValue(":"+name, "0"); } else { - cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -164,8 +164,8 @@ namespace OpenSim.Data.SQLite r.Close(); cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; - cmd.Parameters.Add(":RegionID", regionID.ToString()); - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); // This will throw on dupe key try @@ -222,13 +222,13 @@ namespace OpenSim.Data.SQLite if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.Add(":"+name, "1"); + cmd.Parameters.AddWithValue(":"+name, "1"); else - cmd.Parameters.Add(":"+name, "0"); + cmd.Parameters.AddWithValue(":"+name, "0"); } else { - cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -247,7 +247,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", es.EstateID); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID); IDataReader r = cmd.ExecuteReader(); @@ -271,7 +271,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from estateban where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -281,8 +281,8 @@ namespace OpenSim.Data.SQLite foreach (EstateBan b in es.EstateBans) { - cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); - cmd.Parameters.Add(":bannedUUID", b.BannedUserID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); + cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -294,7 +294,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -304,8 +304,8 @@ namespace OpenSim.Data.SQLite foreach (UUID uuid in data) { - cmd.Parameters.Add(":EstateID", EstateID.ToString()); - cmd.Parameters.Add(":uuid", uuid.ToString()); + cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); + cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -319,7 +319,7 @@ namespace OpenSim.Data.SQLite SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; - cmd.Parameters.Add(":EstateID", EstateID); + cmd.Parameters.AddWithValue(":EstateID", EstateID); IDataReader r = cmd.ExecuteReader(); @@ -336,5 +336,66 @@ namespace OpenSim.Data.SQLite return uuids.ToArray(); } +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteEstateData.cs +======= + + 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.AddWithValue(":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.AddWithValue(":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.AddWithValue(":RegionID", regionID.ToString()); + cmd.Parameters.AddWithValue(":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; + } +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteEstateData.cs } } diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs index 12b2750d2d..79eaab3ce1 100644 --- a/OpenSim/Data/SQLite/SQLiteFramework.cs +++ b/OpenSim/Data/SQLite/SQLiteFramework.cs @@ -31,7 +31,7 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { @@ -57,7 +57,19 @@ namespace OpenSim.Data.SQLite { lock (m_Connection) { +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteFramework.cs cmd.Connection = m_Connection; +======= +/* + SqliteConnection newConnection = + (SqliteConnection)((ICloneable)connection).Clone(); + newConnection.Open(); + + cmd.Connection = newConnection; +*/ + cmd.Connection = connection; + //Console.WriteLine("XXX " + cmd.CommandText); +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteFramework.cs return cmd.ExecuteNonQuery(); } @@ -65,12 +77,27 @@ namespace OpenSim.Data.SQLite protected IDataReader ExecuteReader(SqliteCommand cmd) { +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteFramework.cs SqliteConnection newConnection = (SqliteConnection)((ICloneable)m_Connection).Clone(); newConnection.Open(); cmd.Connection = newConnection; return cmd.ExecuteReader(); +======= + lock (connection) + { + //SqliteConnection newConnection = + // (SqliteConnection)((ICloneable)connection).Clone(); + //newConnection.Open(); + + //cmd.Connection = newConnection; + cmd.Connection = connection; + //Console.WriteLine("XXX " + cmd.CommandText); + + return cmd.ExecuteReader(); + } +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteFramework.cs } protected void CloseReaderCommand(SqliteCommand cmd) diff --git a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs similarity index 98% rename from OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs rename to OpenSim/Data/SQLite/SQLiteFriendsData.cs index 702a1d8643..b06853ce68 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFriendsData.cs +++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLite { public class SQLiteFriendsData : SQLiteGenericTableHandler, IFriendsData { diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 8e916936aa..918cb3d8a8 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -54,7 +54,27 @@ namespace OpenSim.Data.SQLite m_Realm = realm; if (storeName != String.Empty) { +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs Assembly assem = GetType().Assembly; +======= + m_Connection = new SqliteConnection(connectionString); + Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, 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); + Migration m = new Migration(m_Connection, assem, storeName); + m.Update(); + //newConnection.Close(); + //newConnection.Dispose(); + } +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs Migration m = new Migration(m_Connection, assem, storeName); m.Update(); @@ -180,7 +200,11 @@ namespace OpenSim.Data.SQLite result.Add(row); } +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs CloseReaderCommand(cmd); +======= + //CloseCommand(cmd); +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs return result.ToArray(); } diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs index 64591fd6f6..0149838422 100644 --- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; @@ -89,6 +89,7 @@ namespace OpenSim.Data.SQLite ds = new DataSet(); +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteInventoryStore.cs ds.Tables.Add(createInventoryFoldersTable()); invFoldersDa.Fill(ds.Tables["inventoryfolders"]); setupFoldersCommands(invFoldersDa, conn); @@ -98,6 +99,19 @@ namespace OpenSim.Data.SQLite invItemsDa.Fill(ds.Tables["inventoryitems"]); setupItemsCommands(invItemsDa, conn); m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); +======= + ds.Tables.Add(createInventoryFoldersTable()); + invFoldersDa.Fill(ds.Tables["inventoryfolders"]); + setupFoldersCommands(invFoldersDa, conn); + CreateDataSetMapping(invFoldersDa, "inventoryfolders"); + m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); + + ds.Tables.Add(createInventoryItemsTable()); + invItemsDa.Fill(ds.Tables["inventoryitems"]); + setupItemsCommands(invItemsDa, conn); + CreateDataSetMapping(invItemsDa, "inventoryitems"); + m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteInventoryStore.cs ds.AcceptChanges(); } @@ -721,6 +735,15 @@ namespace OpenSim.Data.SQLite * **********************************************************************/ + protected void CreateDataSetMapping(IDataAdapter da, string tableName) + { + ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); + foreach (DataColumn col in ds.Tables[tableName].Columns) + { + dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + } + /// /// Create the "inventoryitems" table /// diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 5a4ee2ab72..85368ab82f 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -32,7 +32,7 @@ using System.Drawing; using System.IO; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -87,119 +87,142 @@ namespace OpenSim.Data.SQLite /// 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) + try { - ds.Tables.Add(createPrimTable()); - setupPrimCommands(primDa, m_conn); - primDa.Fill(ds.Tables["prims"]); + m_connectionString = connectionString; - ds.Tables.Add(createShapeTable()); - setupShapeCommands(shapeDa, m_conn); + ds = new DataSet("Region"); - ds.Tables.Add(createItemsTable()); - setupItemsCommands(itemsDa, m_conn); - itemsDa.Fill(ds.Tables["primitems"]); + m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString); + m_conn = new SqliteConnection(m_connectionString); + m_conn.Open(); - ds.Tables.Add(createTerrainTable()); - setupTerrainCommands(terrainDa, m_conn); + SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); + primDa = new SqliteDataAdapter(primSelectCmd); - ds.Tables.Add(createLandTable()); - setupLandCommands(landDa, m_conn); + SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); + shapeDa = new SqliteDataAdapter(shapeSelectCmd); + // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); - ds.Tables.Add(createLandAccessListTable()); - setupLandAccessCommands(landAccessListDa, m_conn); + SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn); + itemsDa = new SqliteDataAdapter(itemsSelectCmd); - ds.Tables.Add(createRegionSettingsTable()); - - setupRegionSettingsCommands(regionSettingsDa, m_conn); + SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn); + terrainDa = new SqliteDataAdapter(terrainSelectCmd); - // 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 + 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) { - shapeDa.Fill(ds.Tables["primshapes"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on primshapes table"); - } + ds.Tables.Add(createPrimTable()); + setupPrimCommands(primDa, m_conn); - try - { - terrainDa.Fill(ds.Tables["terrain"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on terrain table"); - } + ds.Tables.Add(createShapeTable()); + setupShapeCommands(shapeDa, m_conn); - try - { - landDa.Fill(ds.Tables["land"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on land table"); - } + ds.Tables.Add(createItemsTable()); + setupItemsCommands(itemsDa, m_conn); - try - { - landAccessListDa.Fill(ds.Tables["landaccesslist"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on landaccesslist table"); - } + ds.Tables.Add(createTerrainTable()); + setupTerrainCommands(terrainDa, m_conn); - try - { - regionSettingsDa.Fill(ds.Tables["regionsettings"]); + 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 + { + primDa.Fill(ds.Tables["prims"]); + } + catch (Exception) + { + m_log.Info("[REGION DB]: Caught fill error on prims table"); + } + + 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"); + } + + // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! + // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409 + // Possibly because we manually set up our own DataTables before connecting to the database + CreateDataSetMapping(primDa, "prims"); + CreateDataSetMapping(shapeDa, "primshapes"); + CreateDataSetMapping(itemsDa, "primitems"); + CreateDataSetMapping(terrainDa, "terrain"); + CreateDataSetMapping(landDa, "land"); + CreateDataSetMapping(landAccessListDa, "landaccesslist"); + CreateDataSetMapping(regionSettingsDa, "regionsettings"); } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on regionsettings table"); - } - return; } + catch (Exception e) + { + m_log.Error(e); + Environment.Exit(23); + } + + return; } public void Dispose() @@ -594,7 +617,7 @@ namespace OpenSim.Data.SQLite } } } - rev = (int) row["Revision"]; + rev = Convert.ToInt32(row["Revision"]); } else { @@ -746,6 +769,7 @@ namespace OpenSim.Data.SQLite /// public void Commit() { + m_log.Debug("[SQLITE]: Starting commit"); lock (ds) { primDa.Update(ds, "prims"); @@ -760,18 +784,11 @@ namespace OpenSim.Data.SQLite { regionSettingsDa.Update(ds, "regionsettings"); } - catch (SqliteExecutionException SqlEx) + catch (SqliteException 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; - } + 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); } ds.AcceptChanges(); } @@ -793,6 +810,15 @@ namespace OpenSim.Data.SQLite * **********************************************************************/ + protected void CreateDataSetMapping(IDataAdapter da, string tableName) + { + ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); + foreach (DataColumn col in ds.Tables[tableName].Columns) + { + dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + } + /// /// /// @@ -1955,6 +1981,7 @@ namespace OpenSim.Data.SQLite sql += ") values (:"; sql += String.Join(", :", cols); sql += ")"; + m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); SqliteCommand cmd = new SqliteCommand(sql); // this provides the binding for all our parameters, so @@ -2250,6 +2277,36 @@ namespace OpenSim.Data.SQLite return DbType.String; } } + + static void PrintDataSet(DataSet ds) + { + // Print out any name and extended properties. + Console.WriteLine("DataSet is named: {0}", ds.DataSetName); + foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties) + { + Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); + } + Console.WriteLine(); + foreach (DataTable dt in ds.Tables) + { + Console.WriteLine("=> {0} Table:", dt.TableName); + // Print out the column names. + for (int curCol = 0; curCol < dt.Columns.Count; curCol++) + { + Console.Write(dt.Columns[curCol].ColumnName + "\t"); + } + Console.WriteLine("\n----------------------------------"); + // Print the DataTable. + for (int curRow = 0; curRow < dt.Rows.Count; curRow++) + { + for (int curCol = 0; curCol < dt.Columns.Count; curCol++) + { + Console.Write(dt.Rows[curRow][curCol].ToString() + "\t"); + } + Console.WriteLine(); + } + } + } } } diff --git a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs similarity index 99% rename from OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs rename to OpenSim/Data/SQLite/SQLiteUserAccountData.cs index f77159c772..893f105604 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUserAccountData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs @@ -33,7 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using Mono.Data.Sqlite; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLite { public class SQLiteUserAccountData : SQLiteGenericTableHandler, IUserAccountData { diff --git a/OpenSim/Data/SQLite/SQLiteUtils.cs b/OpenSim/Data/SQLite/SQLiteUtils.cs index 4a835ce52f..07c6b69a3b 100644 --- a/OpenSim/Data/SQLite/SQLiteUtils.cs +++ b/OpenSim/Data/SQLite/SQLiteUtils.cs @@ -27,7 +27,7 @@ using System; using System.Data; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; namespace OpenSim.Data.SQLite { diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 5c93f88f70..0650a864f8 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -29,7 +29,7 @@ using System; using System.Data; using System.Reflection; using System.Collections.Generic; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using log4net; using OpenMetaverse; using OpenSim.Framework; @@ -147,7 +147,11 @@ namespace OpenSim.Data.SQLite } reader.Close(); +<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteXInventoryData.cs CloseReaderCommand(cmd); +======= + //CloseCommand(cmd); +>>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteXInventoryData.cs return perms; } diff --git a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLiteLegacy/Properties/AssemblyInfo.cs similarity index 96% rename from OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs rename to OpenSim/Data/SQLiteLegacy/Properties/AssemblyInfo.cs index 4aeb67b375..609a024b73 100644 --- a/OpenSim/Data/SQLiteNG/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/SQLiteLegacy/Properties/AssemblyInfo.cs @@ -32,11 +32,11 @@ using System.Runtime.InteropServices; // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly : AssemblyTitle("OpenSim.Data.SQLiteNG")] +[assembly : AssemblyTitle("OpenSim.Data.SQLiteLegacy")] [assembly : AssemblyDescription("")] [assembly : AssemblyConfiguration("")] [assembly : AssemblyCompany("http://opensimulator.org")] -[assembly : AssemblyProduct("OpenSim.Data.SQLiteNG")] +[assembly : AssemblyProduct("OpenSim.Data.SQLiteLegacy")] [assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] [assembly : AssemblyTrademark("")] [assembly : AssemblyCulture("")] diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_AssetStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_AssetStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_AssetStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_AuthStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_Avatar.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_Avatar.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_Avatar.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_FriendsStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_FriendsStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_FriendsStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_InventoryStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_InventoryStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_InventoryStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_UserAccount.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_UserAccount.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_UserAccount.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/001_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/001_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_AssetStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_AssetStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_AssetStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_AuthStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_AuthStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_AuthStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_FriendsStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_FriendsStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_FriendsStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_InventoryStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_InventoryStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_InventoryStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_UserAccount.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/002_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/002_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/003_AssetStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/003_AssetStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/003_AssetStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/003_InventoryStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/003_InventoryStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/003_InventoryStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/003_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/003_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/003_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/003_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/003_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/003_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/004_AssetStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/004_AssetStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/004_AssetStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/004_InventoryStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/004_InventoryStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/004_InventoryStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/004_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/004_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/004_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/004_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/004_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/004_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/005_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/005_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/005_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/005_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/005_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/005_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/006_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/006_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/006_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/006_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/006_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/006_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/007_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/007_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/007_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/007_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/007_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/007_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/008_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/008_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/008_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/008_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/008_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/008_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/009_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/009_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/009_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/009_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/009_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/009_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/010_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/010_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/010_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/010_UserStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/010_UserStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/010_UserStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/011_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/011_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/011_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/012_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/012_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/012_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/013_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/013_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/013_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/014_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/014_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/014_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/015_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/015_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/015_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/016_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/016_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/016_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/017_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/017_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/017_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/018_RegionStore.sql similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/018_RegionStore.sql rename to OpenSim/Data/SQLiteLegacy/Resources/018_RegionStore.sql diff --git a/OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml b/OpenSim/Data/SQLiteLegacy/Resources/OpenSim.Data.SQLite.addin.xml similarity index 100% rename from OpenSim/Data/SQLiteNG/Resources/OpenSim.Data.SQLite.addin.xml rename to OpenSim/Data/SQLiteLegacy/Resources/OpenSim.Data.SQLite.addin.xml diff --git a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs similarity index 99% rename from OpenSim/Data/SQLiteNG/SQLiteAssetData.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs index 9b34a21592..0d63deacd8 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs @@ -30,11 +30,11 @@ using System.Data; using System.Reflection; using System.Collections.Generic; using log4net; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// An asset storage interface for the SQLite database system @@ -137,7 +137,7 @@ namespace OpenSim.Data.SQLiteNG 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(); } } @@ -340,4 +340,4 @@ namespace OpenSim.Data.SQLiteNG #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAuthenticationData.cs new file mode 100644 index 0000000000..c64830a455 --- /dev/null +++ b/OpenSim/Data/SQLiteLegacy/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.SQLiteLegacy +{ + 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/SQLiteLegacy/SQLiteAvatarData.cs similarity index 92% rename from OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs index d0fd49c5ae..660632ca07 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteAvatarData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs @@ -33,9 +33,9 @@ using System.Threading; using log4net; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// A SQLite Interface for Avatar Data @@ -55,8 +55,8 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = new SqliteCommand(); cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = :PrincipalID and `Name` = :Name", m_Realm); - cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString()); - cmd.Parameters.AddWithValue(":Name", name); + cmd.Parameters.Add(":PrincipalID", principalID.ToString()); + cmd.Parameters.Add(":Name", name); try { @@ -67,7 +67,7 @@ namespace OpenSim.Data.SQLiteNG } finally { - //CloseCommand(cmd); + CloseCommand(cmd); } } } diff --git a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs similarity index 87% rename from OpenSim/Data/SQLiteNG/SQLiteEstateData.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs index 2e2d717cc9..e135eaa524 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs @@ -30,12 +30,12 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { public class SQLiteEstateStore : IEstateDataStore { @@ -62,8 +62,8 @@ namespace OpenSim.Data.SQLiteNG Migration m = new Migration(m_connection, assem, "EstateStore"); m.Update(); - //m_connection.Close(); - // m_connection.Open(); + m_connection.Close(); + m_connection.Open(); Type t = typeof(EstateSettings); m_Fields = t.GetFields(BindingFlags.NonPublic | @@ -87,7 +87,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); + cmd.Parameters.Add(":RegionID", regionID.ToString()); return DoLoad(cmd, regionID, create); } @@ -143,13 +143,13 @@ namespace OpenSim.Data.SQLiteNG if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue(":"+name, "1"); + cmd.Parameters.Add(":"+name, "1"); else - cmd.Parameters.AddWithValue(":"+name, "0"); + cmd.Parameters.Add(":"+name, "0"); } else { - cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -167,8 +167,8 @@ namespace OpenSim.Data.SQLiteNG r.Close(); cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; - cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); - cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); + cmd.Parameters.Add(":RegionID", regionID.ToString()); + cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); // This will throw on dupe key try @@ -211,13 +211,13 @@ namespace OpenSim.Data.SQLiteNG if (m_FieldMap[name].GetValue(es) is bool) { if ((bool)m_FieldMap[name].GetValue(es)) - cmd.Parameters.AddWithValue(":"+name, "1"); + cmd.Parameters.Add(":"+name, "1"); else - cmd.Parameters.AddWithValue(":"+name, "0"); + cmd.Parameters.Add(":"+name, "0"); } else { - cmd.Parameters.AddWithValue(":"+name, m_FieldMap[name].GetValue(es).ToString()); + cmd.Parameters.Add(":"+name, m_FieldMap[name].GetValue(es).ToString()); } } @@ -236,7 +236,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select bannedUUID from estateban where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", es.EstateID); + cmd.Parameters.Add(":EstateID", es.EstateID); IDataReader r = cmd.ExecuteReader(); @@ -260,7 +260,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from estateban where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); + cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -270,8 +270,8 @@ namespace OpenSim.Data.SQLiteNG foreach (EstateBan b in es.EstateBans) { - cmd.Parameters.AddWithValue(":EstateID", es.EstateID.ToString()); - cmd.Parameters.AddWithValue(":bannedUUID", b.BannedUserID.ToString()); + cmd.Parameters.Add(":EstateID", es.EstateID.ToString()); + cmd.Parameters.Add(":bannedUUID", b.BannedUserID.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -283,7 +283,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "delete from "+table+" where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); + cmd.Parameters.Add(":EstateID", EstateID.ToString()); cmd.ExecuteNonQuery(); @@ -293,8 +293,8 @@ namespace OpenSim.Data.SQLiteNG foreach (UUID uuid in data) { - cmd.Parameters.AddWithValue(":EstateID", EstateID.ToString()); - cmd.Parameters.AddWithValue(":uuid", uuid.ToString()); + cmd.Parameters.Add(":EstateID", EstateID.ToString()); + cmd.Parameters.Add(":uuid", uuid.ToString()); cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); @@ -308,7 +308,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "select uuid from "+table+" where EstateID = :EstateID"; - cmd.Parameters.AddWithValue(":EstateID", EstateID); + cmd.Parameters.Add(":EstateID", EstateID); IDataReader r = cmd.ExecuteReader(); @@ -333,7 +333,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); + cmd.Parameters.Add(":EstateID", estateID.ToString()); return DoLoad(cmd, UUID.Zero, false); } @@ -347,7 +347,7 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = sql; - cmd.Parameters.AddWithValue(":EstateName", search); + cmd.Parameters.Add(":EstateName", search); IDataReader r = cmd.ExecuteReader(); @@ -365,8 +365,8 @@ namespace OpenSim.Data.SQLiteNG SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand(); cmd.CommandText = "insert into estate_map values (:RegionID, :EstateID)"; - cmd.Parameters.AddWithValue(":RegionID", regionID.ToString()); - cmd.Parameters.AddWithValue(":EstateID", estateID.ToString()); + cmd.Parameters.Add(":RegionID", regionID.ToString()); + cmd.Parameters.Add(":EstateID", estateID.ToString()); if (cmd.ExecuteNonQuery() == 0) return false; diff --git a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs b/OpenSim/Data/SQLiteLegacy/SQLiteFramework.cs similarity index 89% rename from OpenSim/Data/SQLiteNG/SQLiteFramework.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteFramework.cs index f0ddc597bd..606478ea7e 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteFramework.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteFramework.cs @@ -31,9 +31,9 @@ using System.Collections.Generic; using System.Data; using OpenMetaverse; using OpenSim.Framework; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// A database interface class to a user profile storage system @@ -55,14 +55,11 @@ namespace OpenSim.Data.SQLiteNG { lock (connection) { -/* SqliteConnection newConnection = (SqliteConnection)((ICloneable)connection).Clone(); newConnection.Open(); cmd.Connection = newConnection; -*/ - cmd.Connection = connection; //Console.WriteLine("XXX " + cmd.CommandText); return cmd.ExecuteNonQuery(); @@ -73,12 +70,11 @@ namespace OpenSim.Data.SQLiteNG { lock (connection) { - //SqliteConnection newConnection = - // (SqliteConnection)((ICloneable)connection).Clone(); - //newConnection.Open(); + SqliteConnection newConnection = + (SqliteConnection)((ICloneable)connection).Clone(); + newConnection.Open(); - //cmd.Connection = newConnection; - cmd.Connection = connection; + cmd.Connection = newConnection; //Console.WriteLine("XXX " + cmd.CommandText); return cmd.ExecuteReader(); diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs new file mode 100644 index 0000000000..d529d4d8ab --- /dev/null +++ b/OpenSim/Data/SQLiteLegacy/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.SQLiteLegacy +{ + 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/SQLiteLegacy/SQLiteGenericTableHandler.cs similarity index 93% rename from OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteGenericTableHandler.cs index 632c5bf8c9..1c1fe8cc0f 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteGenericTableHandler.cs @@ -30,12 +30,12 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { public class SQLiteGenericTableHandler : SQLiteFramework where T: class, new() { @@ -59,21 +59,19 @@ namespace OpenSim.Data.SQLiteNG if (!m_initialized) { m_Connection = new SqliteConnection(connectionString); - Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString)); m_Connection.Open(); if (storeName != String.Empty) { Assembly assem = GetType().Assembly; - //SqliteConnection newConnection = - // (SqliteConnection)((ICloneable)m_Connection).Clone(); - //newConnection.Open(); + SqliteConnection newConnection = + (SqliteConnection)((ICloneable)m_Connection).Clone(); + newConnection.Open(); - //Migration m = new Migration(newConnection, assem, storeName); - Migration m = new Migration(m_Connection, assem, storeName); + Migration m = new Migration(newConnection, assem, storeName); m.Update(); - //newConnection.Close(); - //newConnection.Dispose(); + newConnection.Close(); + newConnection.Dispose(); } m_initialized = true; @@ -199,7 +197,7 @@ namespace OpenSim.Data.SQLiteNG result.Add(row); } - //CloseCommand(cmd); + CloseCommand(cmd); return result.ToArray(); } diff --git a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs b/OpenSim/Data/SQLiteLegacy/SQLiteInventoryStore.cs similarity index 98% rename from OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteInventoryStore.cs index 9207ca3cc4..726703b79d 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteInventoryStore.cs @@ -30,11 +30,11 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// An Inventory Interface to the SQLite database @@ -98,13 +98,11 @@ namespace OpenSim.Data.SQLiteNG ds.Tables.Add(createInventoryFoldersTable()); invFoldersDa.Fill(ds.Tables["inventoryfolders"]); setupFoldersCommands(invFoldersDa, conn); - CreateDataSetMapping(invFoldersDa, "inventoryfolders"); m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); ds.Tables.Add(createInventoryItemsTable()); invItemsDa.Fill(ds.Tables["inventoryitems"]); setupItemsCommands(invItemsDa, conn); - CreateDataSetMapping(invItemsDa, "inventoryitems"); m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); ds.AcceptChanges(); @@ -730,15 +728,6 @@ namespace OpenSim.Data.SQLiteNG * **********************************************************************/ - protected void CreateDataSetMapping(IDataAdapter da, string tableName) - { - ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); - foreach (DataColumn col in ds.Tables[tableName].Columns) - { - dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); - } - } - /// /// Create the "inventoryitems" table /// diff --git a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs similarity index 91% rename from OpenSim/Data/SQLiteNG/SQLiteRegionData.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs index 289d626543..eb78037bb1 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs @@ -32,13 +32,13 @@ using System.Drawing; using System.IO; using System.Reflection; using log4net; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// A RegionData Interface to the SQLite database @@ -87,142 +87,119 @@ namespace OpenSim.Data.SQLiteNG /// the connection string public void Initialise(string connectionString) { - try + 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) { - m_connectionString = connectionString; + ds.Tables.Add(createPrimTable()); + setupPrimCommands(primDa, m_conn); + primDa.Fill(ds.Tables["prims"]); - ds = new DataSet("Region"); + ds.Tables.Add(createShapeTable()); + setupShapeCommands(shapeDa, m_conn); - m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString); - m_conn = new SqliteConnection(m_connectionString); - m_conn.Open(); + ds.Tables.Add(createItemsTable()); + setupItemsCommands(itemsDa, m_conn); + itemsDa.Fill(ds.Tables["primitems"]); - SqliteCommand primSelectCmd = new SqliteCommand(primSelect, m_conn); - primDa = new SqliteDataAdapter(primSelectCmd); + ds.Tables.Add(createTerrainTable()); + setupTerrainCommands(terrainDa, m_conn); - SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, m_conn); - shapeDa = new SqliteDataAdapter(shapeSelectCmd); - // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); + ds.Tables.Add(createLandTable()); + setupLandCommands(landDa, m_conn); - SqliteCommand itemsSelectCmd = new SqliteCommand(itemsSelect, m_conn); - itemsDa = new SqliteDataAdapter(itemsSelectCmd); + ds.Tables.Add(createLandAccessListTable()); + setupLandAccessCommands(landAccessListDa, m_conn); - SqliteCommand terrainSelectCmd = new SqliteCommand(terrainSelect, m_conn); - terrainDa = new SqliteDataAdapter(terrainSelectCmd); + ds.Tables.Add(createRegionSettingsTable()); + + setupRegionSettingsCommands(regionSettingsDa, m_conn); - 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) + // 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 { - ds.Tables.Add(createPrimTable()); - setupPrimCommands(primDa, m_conn); - - ds.Tables.Add(createShapeTable()); - setupShapeCommands(shapeDa, m_conn); - - ds.Tables.Add(createItemsTable()); - setupItemsCommands(itemsDa, m_conn); - - 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 - { - primDa.Fill(ds.Tables["prims"]); - } - catch (Exception) - { - m_log.Info("[REGION DB]: Caught fill error on prims table"); - } - - 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"); - } - - // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! - // Not sure exactly why this is - this kind of thing was not necessary before - justincc 20100409 - // Possibly because we manually set up our own DataTables before connecting to the database - CreateDataSetMapping(primDa, "prims"); - CreateDataSetMapping(shapeDa, "primshapes"); - CreateDataSetMapping(itemsDa, "primitems"); - CreateDataSetMapping(terrainDa, "terrain"); - CreateDataSetMapping(landDa, "land"); - CreateDataSetMapping(landAccessListDa, "landaccesslist"); - CreateDataSetMapping(regionSettingsDa, "regionsettings"); + shapeDa.Fill(ds.Tables["primshapes"]); + } + catch (Exception) + { + m_log.Info("[REGION DB]: Caught fill error on primshapes table"); } - } - catch (Exception e) - { - m_log.Error(e); - Environment.Exit(23); - } - return; + 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() @@ -626,7 +603,7 @@ namespace OpenSim.Data.SQLiteNG } } } - rev = Convert.ToInt32(row["Revision"]); + rev = (int) row["Revision"]; } else { @@ -778,7 +755,6 @@ namespace OpenSim.Data.SQLiteNG /// public void Commit() { - m_log.Debug("[SQLITE]: Starting commit"); lock (ds) { primDa.Update(ds, "prims"); @@ -793,11 +769,18 @@ namespace OpenSim.Data.SQLiteNG { regionSettingsDa.Update(ds, "regionsettings"); } - catch (SqliteException SqlEx) + catch (SqliteExecutionException SqlEx) { - 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); + 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(); } @@ -819,15 +802,6 @@ namespace OpenSim.Data.SQLiteNG * **********************************************************************/ - protected void CreateDataSetMapping(IDataAdapter da, string tableName) - { - ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); - foreach (DataColumn col in ds.Tables[tableName].Columns) - { - dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); - } - } - /// /// /// @@ -1990,7 +1964,6 @@ namespace OpenSim.Data.SQLiteNG sql += ") values (:"; sql += String.Join(", :", cols); sql += ")"; - m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); SqliteCommand cmd = new SqliteCommand(sql); // this provides the binding for all our parameters, so @@ -2286,36 +2259,6 @@ namespace OpenSim.Data.SQLiteNG return DbType.String; } } - - static void PrintDataSet(DataSet ds) - { - // Print out any name and extended properties. - Console.WriteLine("DataSet is named: {0}", ds.DataSetName); - foreach (System.Collections.DictionaryEntry de in ds.ExtendedProperties) - { - Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value); - } - Console.WriteLine(); - foreach (DataTable dt in ds.Tables) - { - Console.WriteLine("=> {0} Table:", dt.TableName); - // Print out the column names. - for (int curCol = 0; curCol < dt.Columns.Count; curCol++) - { - Console.Write(dt.Columns[curCol].ColumnName + "\t"); - } - Console.WriteLine("\n----------------------------------"); - // Print the DataTable. - for (int curRow = 0; curRow < dt.Rows.Count; curRow++) - { - for (int curCol = 0; curCol < dt.Columns.Count; curCol++) - { - Console.Write(dt.Rows[curRow][curCol].ToString() + "\t"); - } - Console.WriteLine(); - } - } - } } } diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs new file mode 100644 index 0000000000..27553c61eb --- /dev/null +++ b/OpenSim/Data/SQLiteLegacy/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.SQLiteLegacy +{ + 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/SQLiteLegacy/SQLiteUtils.cs similarity index 99% rename from OpenSim/Data/SQLiteNG/SQLiteUtils.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteUtils.cs index 82a2e37993..095a26251f 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteUtils.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteUtils.cs @@ -27,9 +27,9 @@ using System; using System.Data; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// A base class for methods needed by all SQLite database classes diff --git a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteXInventoryData.cs similarity index 98% rename from OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs rename to OpenSim/Data/SQLiteLegacy/SQLiteXInventoryData.cs index a0c17f8fd9..5422cbf6ad 100644 --- a/OpenSim/Data/SQLiteNG/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteXInventoryData.cs @@ -29,12 +29,12 @@ using System; using System.Data; using System.Reflection; using System.Collections.Generic; -using Mono.Data.Sqlite; +using Mono.Data.SqliteClient; using log4net; using OpenMetaverse; using OpenSim.Framework; -namespace OpenSim.Data.SQLiteNG +namespace OpenSim.Data.SQLiteLegacy { /// /// A MySQL Interface for the Asset Server @@ -147,7 +147,7 @@ namespace OpenSim.Data.SQLiteNG } reader.Close(); - //CloseCommand(cmd); + CloseCommand(cmd); return perms; } diff --git a/OpenSim/Data/Tests/DataTestUtil.cs b/OpenSim/Data/Tests/DataTestUtil.cs index d211ab3b40..5393529592 100644 --- a/OpenSim/Data/Tests/DataTestUtil.cs +++ b/OpenSim/Data/Tests/DataTestUtil.cs @@ -39,7 +39,8 @@ namespace OpenSim.Data.Tests public class DataTestUtil { public const uint UNSIGNED_INTEGER_MIN = uint.MinValue; - public const uint UNSIGNED_INTEGER_MAX = uint.MaxValue; + //public const uint UNSIGNED_INTEGER_MAX = uint.MaxValue; + public const uint UNSIGNED_INTEGER_MAX = INTEGER_MAX; public const int INTEGER_MIN = int.MinValue + 1; // Postgresql requires +1 to .NET int.MinValue public const int INTEGER_MAX = int.MaxValue; diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 5214718ec9..3e9d376fd6 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -126,9 +126,15 @@ ;storage_plugin = "OpenSim.Data.Null.dll" ; --- To use sqlite as region storage: - ; NOTE: SQLite and OpenSim are not functioning properly with Mono 2.4.3 or greater. - ; If you are using Mono you probably should be using MySQL + ; + ; PLEASE NOTE: Unfortunately, the current SQLite database plugin (necessary to use SQLite with Mono on Linux) is + ; not compatible with the sqlite3 library installed on Mac OSX. If you're using Mono 2.4 you can still use the old sqlite + ; library by uncommenting the SQLiteLegacy.dll storage plugin (and commenting out SQLite.dll). Unfortunately, the older library + ; will not work with Mono 2.6 on Mac OSX so you will either need to replace the OSX sqlite3 system library or use MySQL instead + ; + ; You will also need to do the same thing in config-include/StandaloneCommon.ini if you are running in standalone mode storage_plugin = "OpenSim.Data.SQLite.dll" + ;storage_plugin = "OpenSim.Data.SQLiteLegacy.dll" storage_connection_string="URI=file:OpenSim.db,version=3"; ; --- To use MySQL storage, supply your own connection string (this is only an example): diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 1679f93777..40ef228245 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -4,7 +4,15 @@ ; ;--- For SQLite StorageProvider = "OpenSim.Data.SQLite.dll" - ;--- For MySql + + ; Unfortunately the current SQLite database plugin is not compatible with Mac OSX. You can still use the older + ; legacy sqlite library if you are using Mono 2.4. Please see the notes in OpenSim.ini (search for sqlite) + ; for more details + ;StorageProvider = "OpenSim.Data.SQLiteLegacy.dll"; + + ; MySql + ; Uncomment these lines if you want to use mysql storage + ; Change the connection string to your db details ;StorageProvider = "OpenSim.Data.MySQL.dll" ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" @@ -42,4 +50,4 @@ [LibraryModule] ; Set this if you want to change the name of the OpenSim Library - ;LibraryName = "My World's Library" \ No newline at end of file + ;LibraryName = "My World's Library" diff --git a/prebuild.xml b/prebuild.xml index 7c7e3c7f27..908855f280 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2473,7 +2473,7 @@ - + ../../../bin/ @@ -2510,7 +2510,7 @@ - + ../../../bin/ From d8b604b550c76610187d929087bce3b08e7018c5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 18:18:21 +0100 Subject: [PATCH 09/34] take out some debug logging in the sqlite db adaptor --- OpenSim/Data/SQLite/SQLiteRegionData.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 85368ab82f..fe6e919b54 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -769,7 +769,7 @@ namespace OpenSim.Data.SQLite /// public void Commit() { - m_log.Debug("[SQLITE]: Starting commit"); + //m_log.Debug("[SQLITE]: Starting commit"); lock (ds) { primDa.Update(ds, "prims"); @@ -1914,7 +1914,7 @@ namespace OpenSim.Data.SQLite /// public void StorePrimInventory(UUID primID, ICollection items) { - m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID); + //m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID); DataTable dbItems = ds.Tables["primitems"]; @@ -1981,7 +1981,7 @@ namespace OpenSim.Data.SQLite sql += ") values (:"; sql += String.Join(", :", cols); sql += ")"; - m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); + //m_log.DebugFormat("[SQLITE]: Created insert command {0}", sql); SqliteCommand cmd = new SqliteCommand(sql); // this provides the binding for all our parameters, so From 0b8b302aa0f2ee25be5cbdfefe232459e6e5b778 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 20:05:57 +0100 Subject: [PATCH 10/34] Fix a bunch of issues that crop up after the naive porting of the new sqlite db from master to 0.6.9 --- .../Data/SQLite/SQLiteAuthenticationData.cs | 257 ------------------ OpenSim/Data/SQLite/SQLiteEstateData.cs | 65 +---- OpenSim/Data/SQLite/SQLiteFramework.cs | 27 +- OpenSim/Data/SQLite/SQLiteFriendsData.cs | 70 ----- .../Data/SQLite/SQLiteGenericTableHandler.cs | 13 +- OpenSim/Data/SQLite/SQLiteInventoryStore.cs | 18 +- OpenSim/Data/SQLite/SQLiteManager.cs | 8 +- OpenSim/Data/SQLite/SQLiteUserAccountData.cs | 81 ------ OpenSim/Data/SQLite/SQLiteUserData.cs | 2 +- OpenSim/Data/SQLite/SQLiteXInventoryData.cs | 6 +- OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs | 3 +- OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs | 74 ----- OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs | 12 +- .../Data/SQLiteLegacy/SQLiteFriendsData.cs | 70 ----- OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs | 11 +- .../SQLiteLegacy/SQLiteUserAccountData.cs | 81 ------ 16 files changed, 24 insertions(+), 774 deletions(-) delete mode 100644 OpenSim/Data/SQLite/SQLiteAuthenticationData.cs delete mode 100644 OpenSim/Data/SQLite/SQLiteFriendsData.cs delete mode 100644 OpenSim/Data/SQLite/SQLiteUserAccountData.cs delete mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs delete mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs delete mode 100644 OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs diff --git a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs b/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs deleted file mode 100644 index 086ac0a972..0000000000 --- a/OpenSim/Data/SQLite/SQLiteAuthenticationData.cs +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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.Sqlite; - -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(); - - Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore"); - m.Update(); - - 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/SQLite/SQLiteEstateData.cs b/OpenSim/Data/SQLite/SQLiteEstateData.cs index ad4e2a26aa..643e55da41 100644 --- a/OpenSim/Data/SQLite/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLite/SQLiteEstateData.cs @@ -180,7 +180,7 @@ namespace OpenSim.Data.SQLite // cmd.Parameters.Clear(); cmd.CommandText = "insert into estateban select "+es.EstateID.ToString()+", bannedUUID, bannedIp, bannedIpHostMask, '' from regionban where regionban.regionUUID = :UUID"; - cmd.Parameters.Add(":UUID", regionID.ToString()); + cmd.Parameters.AddWithValue(":UUID", regionID.ToString()); try { @@ -336,66 +336,5 @@ namespace OpenSim.Data.SQLite return uuids.ToArray(); } -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteEstateData.cs -======= - - 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.AddWithValue(":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.AddWithValue(":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.AddWithValue(":RegionID", regionID.ToString()); - cmd.Parameters.AddWithValue(":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; - } ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteEstateData.cs } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteFramework.cs b/OpenSim/Data/SQLite/SQLiteFramework.cs index 79eaab3ce1..9567727bdd 100644 --- a/OpenSim/Data/SQLite/SQLiteFramework.cs +++ b/OpenSim/Data/SQLite/SQLiteFramework.cs @@ -57,19 +57,7 @@ namespace OpenSim.Data.SQLite { lock (m_Connection) { -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteFramework.cs cmd.Connection = m_Connection; -======= -/* - SqliteConnection newConnection = - (SqliteConnection)((ICloneable)connection).Clone(); - newConnection.Open(); - - cmd.Connection = newConnection; -*/ - cmd.Connection = connection; - //Console.WriteLine("XXX " + cmd.CommandText); ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteFramework.cs return cmd.ExecuteNonQuery(); } @@ -77,27 +65,18 @@ namespace OpenSim.Data.SQLite protected IDataReader ExecuteReader(SqliteCommand cmd) { -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteFramework.cs - SqliteConnection newConnection = - (SqliteConnection)((ICloneable)m_Connection).Clone(); - newConnection.Open(); - - cmd.Connection = newConnection; - return cmd.ExecuteReader(); -======= - lock (connection) + lock (m_Connection) { //SqliteConnection newConnection = // (SqliteConnection)((ICloneable)connection).Clone(); //newConnection.Open(); //cmd.Connection = newConnection; - cmd.Connection = connection; + cmd.Connection = m_Connection; //Console.WriteLine("XXX " + cmd.CommandText); return cmd.ExecuteReader(); } ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteFramework.cs } protected void CloseReaderCommand(SqliteCommand cmd) @@ -107,4 +86,4 @@ namespace OpenSim.Data.SQLite cmd.Dispose(); } } -} +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs deleted file mode 100644 index b06853ce68..0000000000 --- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.Sqlite; - -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.AddWithValue(":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.AddWithValue(":PrincipalID", principalID.ToString()); - cmd.Parameters.AddWithValue(":Friend", friend); - - ExecuteNonQuery(cmd, cmd.Connection); - - return true; - } - - } -} diff --git a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs index 918cb3d8a8..86eaca18cb 100644 --- a/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs +++ b/OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs @@ -54,11 +54,8 @@ namespace OpenSim.Data.SQLite m_Realm = realm; if (storeName != String.Empty) { -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs - Assembly assem = GetType().Assembly; -======= m_Connection = new SqliteConnection(connectionString); - Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString)); + //Console.WriteLine(string.Format("OPENING CONNECTION FOR {0} USING {1}", storeName, connectionString)); m_Connection.Open(); if (storeName != String.Empty) @@ -74,10 +71,6 @@ namespace OpenSim.Data.SQLite //newConnection.Close(); //newConnection.Dispose(); } ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs - - Migration m = new Migration(m_Connection, assem, storeName); - m.Update(); } Type t = typeof(T); @@ -200,11 +193,7 @@ namespace OpenSim.Data.SQLite result.Add(row); } -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs - CloseReaderCommand(cmd); -======= //CloseCommand(cmd); ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteGenericTableHandler.cs return result.ToArray(); } diff --git a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs index 0149838422..9ce21b1c59 100644 --- a/OpenSim/Data/SQLite/SQLiteInventoryStore.cs +++ b/OpenSim/Data/SQLite/SQLiteInventoryStore.cs @@ -88,30 +88,18 @@ namespace OpenSim.Data.SQLite invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); ds = new DataSet(); - -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteInventoryStore.cs + ds.Tables.Add(createInventoryFoldersTable()); invFoldersDa.Fill(ds.Tables["inventoryfolders"]); setupFoldersCommands(invFoldersDa, conn); + CreateDataSetMapping(invFoldersDa, "inventoryfolders"); m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); ds.Tables.Add(createInventoryItemsTable()); invItemsDa.Fill(ds.Tables["inventoryitems"]); setupItemsCommands(invItemsDa, conn); + CreateDataSetMapping(invItemsDa, "inventoryitems"); m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); -======= - ds.Tables.Add(createInventoryFoldersTable()); - invFoldersDa.Fill(ds.Tables["inventoryfolders"]); - setupFoldersCommands(invFoldersDa, conn); - CreateDataSetMapping(invFoldersDa, "inventoryfolders"); - m_log.Info("[INVENTORY DB]: Populated Inventory Folders Definitions"); - - ds.Tables.Add(createInventoryItemsTable()); - invItemsDa.Fill(ds.Tables["inventoryitems"]); - setupItemsCommands(invItemsDa, conn); - CreateDataSetMapping(invItemsDa, "inventoryitems"); - m_log.Info("[INVENTORY DB]: Populated Inventory Items Definitions"); ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteInventoryStore.cs ds.AcceptChanges(); } diff --git a/OpenSim/Data/SQLite/SQLiteManager.cs b/OpenSim/Data/SQLite/SQLiteManager.cs index b6d4a1cc8c..7dcd323485 100644 --- a/OpenSim/Data/SQLite/SQLiteManager.cs +++ b/OpenSim/Data/SQLite/SQLiteManager.cs @@ -28,9 +28,9 @@ using System; using System.Collections.Generic; using System.Data; -using System.Data.SQLite; using System.Reflection; using log4net; +using Mono.Data.Sqlite; using OpenMetaverse; namespace OpenSim.Data.SQLite @@ -66,7 +66,7 @@ namespace OpenSim.Data.SQLite connectionString = "URI=file:GridServerSqlite.db;"; } - dbcon = new SQLiteConnection(connectionString); + dbcon = new SqliteConnection(connectionString); dbcon.Open(); } @@ -93,11 +93,11 @@ namespace OpenSim.Data.SQLite /// A SQLite DB Command public IDbCommand Query(string sql, Dictionary parameters) { - SQLiteCommand dbcommand = (SQLiteCommand) dbcon.CreateCommand(); + SqliteCommand dbcommand = (SqliteCommand) dbcon.CreateCommand(); dbcommand.CommandText = sql; foreach (KeyValuePair param in parameters) { - SQLiteParameter paramx = new SQLiteParameter(param.Key, param.Value); + SqliteParameter paramx = new SqliteParameter(param.Key, param.Value); dbcommand.Parameters.Add(paramx); } diff --git a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs b/OpenSim/Data/SQLite/SQLiteUserAccountData.cs deleted file mode 100644 index 893f105604..0000000000 --- a/OpenSim/Data/SQLite/SQLiteUserAccountData.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.Sqlite; - -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/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs index caddcf8538..12db40322d 100644 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserData.cs @@ -30,7 +30,7 @@ using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; -using Mono.Data.SqliteClient; +using Mono.Data.Sqlite; using OpenMetaverse; using OpenSim.Framework; diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 0650a864f8..0d211b6ce7 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -147,12 +147,8 @@ namespace OpenSim.Data.SQLite } reader.Close(); -<<<<<<< HEAD:OpenSim/Data/SQLite/SQLiteXInventoryData.cs - CloseReaderCommand(cmd); -======= + //CloseCommand(cmd); ->>>>>>> cc67de5... rename SQLiteNG to SQLite and SQLite to SQLiteLegacy:OpenSim/Data/SQLite/SQLiteXInventoryData.cs - return perms; } } diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs index 0d63deacd8..23cdfd4c6f 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs @@ -234,8 +234,7 @@ namespace OpenSim.Data.SQLiteLegacy AssetBase asset = new AssetBase( new UUID((String)row["UUID"]), (String)row["Name"], - Convert.ToSByte(row["Type"]), - UUID.Zero.ToString() + Convert.ToSByte(row["Type"]) ); asset.Description = (String) row["Description"]; diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs deleted file mode 100644 index 660632ca07..0000000000 --- a/OpenSim/Data/SQLiteLegacy/SQLiteAvatarData.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.SQLiteLegacy -{ - /// - /// 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/SQLiteLegacy/SQLiteEstateData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs index e135eaa524..5a7fbd7549 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteEstateData.cs @@ -80,7 +80,7 @@ namespace OpenSim.Data.SQLiteLegacy get { return new List(m_FieldMap.Keys).ToArray(); } } - public EstateSettings LoadEstateSettings(UUID regionID, bool create) + public EstateSettings LoadEstateSettings(UUID regionID) { 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"; @@ -89,10 +89,10 @@ namespace OpenSim.Data.SQLiteLegacy cmd.CommandText = sql; cmd.Parameters.Add(":RegionID", regionID.ToString()); - return DoLoad(cmd, regionID, create); + return DoLoad(cmd, regionID); } - private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID, bool create) + private EstateSettings DoLoad(SqliteCommand cmd, UUID regionID) { EstateSettings es = new EstateSettings(); es.OnSave += StoreEstateSettings; @@ -125,8 +125,10 @@ namespace OpenSim.Data.SQLiteLegacy } r.Close(); } - else if (create) + else { + // Migration case + // r.Close(); List names = new List(FieldList); @@ -335,7 +337,7 @@ namespace OpenSim.Data.SQLiteLegacy cmd.CommandText = sql; cmd.Parameters.Add(":EstateID", estateID.ToString()); - return DoLoad(cmd, UUID.Zero, false); + return DoLoad(cmd, UUID.Zero); } public List GetEstates(string search) diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs deleted file mode 100644 index d529d4d8ab..0000000000 --- a/OpenSim/Data/SQLiteLegacy/SQLiteFriendsData.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.SQLiteLegacy -{ - 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/SQLiteLegacy/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs index eb78037bb1..f8660c7dc9 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs @@ -272,16 +272,7 @@ namespace OpenSim.Data.SQLiteLegacy 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) diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs deleted file mode 100644 index 27553c61eb..0000000000 --- a/OpenSim/Data/SQLiteLegacy/SQLiteUserAccountData.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.SQLiteLegacy -{ - 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); - } - } -} From 8966ed9c82c8199bf0da61815d04d485d67aa34a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 21:37:31 +0100 Subject: [PATCH 11/34] fix an issue with user appearance where the new sqlite db adapter expects directly specification of byte[] type rather than base64 strings --- OpenSim/Data/SQLite/SQLiteUserData.cs | 37 +++++++++++++------ .../SQLiteLegacy/Resources/001_AuthStore.sql | 18 --------- .../SQLiteLegacy/Resources/001_Avatar.sql | 9 ----- .../Resources/001_FriendsStore.sql | 10 ----- .../Resources/001_UserAccount.sql | 17 --------- .../SQLiteLegacy/Resources/002_AuthStore.sql | 5 --- .../Resources/002_FriendsStore.sql | 5 --- .../Resources/002_UserAccount.sql | 5 --- 8 files changed, 25 insertions(+), 81 deletions(-) delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/001_Avatar.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/001_FriendsStore.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/001_UserAccount.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/002_AuthStore.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/002_FriendsStore.sql delete mode 100644 OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs index 12db40322d..bffc0d0ab3 100644 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserData.cs @@ -108,22 +108,32 @@ namespace OpenSim.Data.SQLite lock (ds) { + Console.WriteLine("Here1"); ds.Tables.Add(createUsersTable()); ds.Tables.Add(createUserAgentsTable()); ds.Tables.Add(createUserFriendsTable()); ds.Tables.Add(createAvatarAppearanceTable()); + Console.WriteLine("Here2"); setupUserCommands(da, conn); da.Fill(ds.Tables["users"]); + CreateDataSetMapping(da, "users"); + Console.WriteLine("Here3"); setupAgentCommands(dua, conn); dua.Fill(ds.Tables["useragents"]); + CreateDataSetMapping(dua, "useragents"); + Console.WriteLine("Here4"); setupUserFriendsCommands(daf, conn); daf.Fill(ds.Tables["userfriends"]); + CreateDataSetMapping(daf, "userfriends"); + Console.WriteLine("Here5"); setupAvatarAppearanceCommands(daa, conn); daa.Fill(ds.Tables["avatarappearance"]); + CreateDataSetMapping(daa, "avatarappearance"); + Console.WriteLine("Here6"); } return; @@ -706,15 +716,10 @@ namespace OpenSim.Data.SQLite aa.SkirtItem = new UUID((String)row["SkirtItem"]); aa.SkirtAsset = new UUID((String)row["SkirtAsset"]); - // Ewe Loon - // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) - - String str = (String)row["Texture"]; - byte[] texture = Convert.FromBase64String(str); + byte[] texture = (byte[])row["Texture"]; aa.Texture = new Primitive.TextureEntry(texture, 0, texture.Length); - str = (String)row["VisualParams"]; - byte[] VisualParams = Convert.FromBase64String(str); + byte[] VisualParams = (byte[])row["VisualParams"]; aa.VisualParams = VisualParams; aa.Serial = Convert.ToInt32(row["Serial"]); @@ -793,6 +798,15 @@ namespace OpenSim.Data.SQLite * **********************************************************************/ + protected void CreateDataSetMapping(IDataAdapter da, string tableName) + { + ITableMapping dbMapping = da.TableMappings.Add(tableName, tableName); + foreach (DataColumn col in ds.Tables[tableName].Columns) + { + dbMapping.ColumnMappings.Add(col.ColumnName, col.ColumnName); + } + } + /// /// Create the "users" table /// @@ -924,9 +938,8 @@ namespace OpenSim.Data.SQLite SQLiteUtil.createCol(aa, "SkirtItem", typeof(String)); SQLiteUtil.createCol(aa, "SkirtAsset", typeof(String)); - // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) - SQLiteUtil.createCol(aa, "Texture", typeof (String)); - SQLiteUtil.createCol(aa, "VisualParams", typeof (String)); + SQLiteUtil.createCol(aa, "Texture", typeof (Byte[])); + SQLiteUtil.createCol(aa, "VisualParams", typeof (Byte[])); SQLiteUtil.createCol(aa, "Serial", typeof(Int32)); SQLiteUtil.createCol(aa, "AvatarHeight", typeof(Double)); @@ -1090,8 +1103,8 @@ namespace OpenSim.Data.SQLite row["SkirtAsset"] = appearance.SkirtAsset.ToString(); // Used Base64String because for some reason it wont accept using Byte[] (which works in Region date) - row["Texture"] = Convert.ToBase64String(appearance.Texture.GetBytes()); - row["VisualParams"] = Convert.ToBase64String(appearance.VisualParams); + row["Texture"] = appearance.Texture.GetBytes(); + row["VisualParams"] = appearance.VisualParams; row["Serial"] = appearance.Serial; row["AvatarHeight"] = appearance.AvatarHeight; diff --git a/OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql deleted file mode 100644 index 468567dcc2..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/001_AuthStore.sql +++ /dev/null @@ -1,18 +0,0 @@ -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/SQLiteLegacy/Resources/001_Avatar.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_Avatar.sql deleted file mode 100644 index 7ec906b48a..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/001_Avatar.sql +++ /dev/null @@ -1,9 +0,0 @@ -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/SQLiteLegacy/Resources/001_FriendsStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_FriendsStore.sql deleted file mode 100644 index f1b9ab9902..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/001_FriendsStore.sql +++ /dev/null @@ -1,10 +0,0 @@ -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/SQLiteLegacy/Resources/001_UserAccount.sql b/OpenSim/Data/SQLiteLegacy/Resources/001_UserAccount.sql deleted file mode 100644 index c38d9a762f..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/001_UserAccount.sql +++ /dev/null @@ -1,17 +0,0 @@ -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/SQLiteLegacy/Resources/002_AuthStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_AuthStore.sql deleted file mode 100644 index 3237b68fd6..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/002_AuthStore.sql +++ /dev/null @@ -1,5 +0,0 @@ -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/SQLiteLegacy/Resources/002_FriendsStore.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_FriendsStore.sql deleted file mode 100644 index 6733502224..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/002_FriendsStore.sql +++ /dev/null @@ -1,5 +0,0 @@ -BEGIN TRANSACTION; - -INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userfriends`; - -COMMIT; diff --git a/OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql b/OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql deleted file mode 100644 index c7a62932ac..0000000000 --- a/OpenSim/Data/SQLiteLegacy/Resources/002_UserAccount.sql +++ /dev/null @@ -1,5 +0,0 @@ -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; From 139f425f4cf4c720681a10e9cd5399fe0ed3b86c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 22:08:57 +0100 Subject: [PATCH 12/34] take out some more sqlite db console debug lines --- OpenSim/Data/SQLite/SQLiteUserData.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/OpenSim/Data/SQLite/SQLiteUserData.cs b/OpenSim/Data/SQLite/SQLiteUserData.cs index bffc0d0ab3..ea755b0f28 100644 --- a/OpenSim/Data/SQLite/SQLiteUserData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserData.cs @@ -108,32 +108,26 @@ namespace OpenSim.Data.SQLite lock (ds) { - Console.WriteLine("Here1"); ds.Tables.Add(createUsersTable()); ds.Tables.Add(createUserAgentsTable()); ds.Tables.Add(createUserFriendsTable()); ds.Tables.Add(createAvatarAppearanceTable()); - Console.WriteLine("Here2"); setupUserCommands(da, conn); da.Fill(ds.Tables["users"]); CreateDataSetMapping(da, "users"); - Console.WriteLine("Here3"); setupAgentCommands(dua, conn); dua.Fill(ds.Tables["useragents"]); CreateDataSetMapping(dua, "useragents"); - Console.WriteLine("Here4"); setupUserFriendsCommands(daf, conn); daf.Fill(ds.Tables["userfriends"]); CreateDataSetMapping(daf, "userfriends"); - Console.WriteLine("Here5"); setupAvatarAppearanceCommands(daa, conn); daa.Fill(ds.Tables["avatarappearance"]); CreateDataSetMapping(daa, "avatarappearance"); - Console.WriteLine("Here6"); } return; From 8938fac4fdd5ca949da8415f681b54872f330e57 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Apr 2010 22:36:26 +0100 Subject: [PATCH 13/34] add operation to "nant distbin" to copy StandaloneCommon.ini.example -> StandaloneCommon.ini --- .nant/local.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nant/local.include b/.nant/local.include index 1e8bedc64e..f71e5d8ff8 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -7,8 +7,8 @@ + - From a69cb5e3901eb9aa7ebfa65a5787e023136a2b19 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 3 May 2010 21:34:38 +0100 Subject: [PATCH 14/34] Address symptom of Mantis 4588 (though not the cause) by moving the avatar dereference inside the exception catch --- OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 1a6cd6c7da..4bcfaac724 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -146,10 +146,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule } private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID) - { - ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + { try { + ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) { avatar.Invulnerable = false; From 547e0278990208e52a35ac92add22f756d8674f2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Apr 2010 22:35:07 +0200 Subject: [PATCH 15/34] Fix linking issue introduced in my earlier commit --- .../Framework/Scenes/Scene.Inventory.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8716e0afc1..4f2b4469ae 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2594,8 +2594,17 @@ namespace OpenSim.Region.Framework.Scenes List children = new List(); SceneObjectPart root = GetSceneObjectPart(parentPrimId); - if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + if (root == null) + { + m_log.DebugFormat("[LINK]: Can't find linkset root prim {0{", parentPrimId); return; + } + + if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); + return; + } foreach (uint localID in childPrimIds) { @@ -2614,7 +2623,16 @@ namespace OpenSim.Region.Framework.Scenes // Must be all one owner // if (owners.Count > 1) + { + m_log.DebugFormat("[LINK]: Refusing link. Too many owners"); return; + } + + if (children.Count == 0) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children"); + return; + } m_sceneGraph.LinkObjects(root, children); } From 2f6bb013701b45421b906625560d8b417ad78689 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey Date: Fri, 14 May 2010 21:22:53 +0100 Subject: [PATCH 16/34] Apply patch from http://opensimulator.org/mantis/bug_view_page.php?bug_id=4671 Fixes a bug where the viewer didn't recieve the uuid of a chat broadcasting object Thanks crystalsgalicia! --- OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 6dacbba0df..02f0968c40 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -264,6 +264,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat fromName = avatar.Name; sourceType = ChatSourceType.Agent; } + else if (c.SenderUUID != UUID.Zero) + { + fromID = c.SenderUUID; + } // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); From e79eac238ed54d1e0d41ad1ff970473226cede50 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 14 May 2010 21:30:53 +0100 Subject: [PATCH 17/34] switch 0.6.9 flavour to release --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index f8ed5ae376..1ae493d96d 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -30,7 +30,7 @@ namespace OpenSim public class VersionInfo { private const string VERSION_NUMBER = "0.6.9"; - private const Flavour VERSION_FLAVOUR = Flavour.RC1; + private const Flavour VERSION_FLAVOUR = Flavour.Release; public enum Flavour { From 5074d290e4aeb583560272cadc8ba09aa8337210 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 27 May 2010 21:35:17 +0100 Subject: [PATCH 18/34] commit code which stops full updates being fired multiple times when attachments cross standalone region boundaries lots of messy debug code here too which would need to be removed --- .../Interregion/LocalInterregionComms.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 5 +++ .../Framework/Scenes/Scene.PacketHandlers.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 43 ++++++++++++++++--- .../Scenes/SceneCommunicationService.cs | 2 + OpenSim/Region/Framework/Scenes/SceneGraph.cs | 34 ++++++++++++++- .../Framework/Scenes/SceneObjectGroup.cs | 15 +++++-- .../Framework/Scenes/SceneObjectPart.cs | 34 +++++++++++---- .../Region/Framework/Scenes/SceneViewer.cs | 8 +++- bin/OpenSim.exe.config | 2 +- 10 files changed, 123 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index d68c683143..4abc2158f9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { if (s.RegionInfo.RegionHandle == regionHandle) { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); + m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); if (isLocalCall) { // We need to make a local copy of the object diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 42a748ff67..aa724c5952 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2449,6 +2449,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + m_log.DebugFormat("[SCENE INVENTORY]: {0} {1} IsAttachment={2}", att.Name, att.LocalId, att.IsAttachment); + Console.WriteLine("HERE X"); ScenePresence presence; if (TryGetAvatar(remoteClient.AgentId, out presence)) { @@ -2456,9 +2458,12 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); + Console.WriteLine("HERE Y"); if (m_AvatarFactory != null) m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + + Console.WriteLine("HERE Z"); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index ac04dc795b..d8e604ff9b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -124,6 +124,7 @@ namespace OpenSim.Region.Framework.Scenes { if (((SceneObjectGroup)ent).LocalId == primLocalID) { + m_log.DebugFormat("[SCENE]: Received full update request for {0} from {1}", primLocalID, remoteClient.Name); ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 637ebffd3f..dd2d2cc4d2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1833,6 +1833,28 @@ namespace OpenSim.Region.Framework.Scenes return sceneObject; } + /// + /// Add an object into the scene that has come from storage + /// + /// + /// + /// + /// If true, changes to the object will be reflected in its persisted data + /// If false, the persisted data will not be changed even if the object in the scene is changed + /// + /// + /// If true, we won't persist this object until it changes + /// If false, we'll persist this object immediately + /// + /// + /// true if the object was added, false if an object with the same uuid was already in the scene + /// + public bool AddRestoredSceneObject( + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) + { + return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); + } + /// /// Add an object into the scene that has come from storage /// @@ -1852,7 +1874,7 @@ namespace OpenSim.Region.Framework.Scenes public bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { - return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted); + return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); } /// @@ -2461,7 +2483,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IncomingCreateObject(ISceneObject sog) { - //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); + m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); SceneObjectGroup newObject; try { @@ -2533,10 +2555,12 @@ namespace OpenSim.Region.Framework.Scenes if (sceneObject.IsAttachmentCheckFull()) // Attachment { + m_log.DebugFormat("[SCENE]: Adding attachment {0} {1}", sceneObject.Name, sceneObject.LocalId); + sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); - AddRestoredSceneObject(sceneObject, false, false); + AddRestoredSceneObject(sceneObject, false, false, false); // Handle attachment special case SceneObjectPart RootPrim = sceneObject.RootPart; @@ -2544,6 +2568,8 @@ namespace OpenSim.Region.Framework.Scenes // Fix up attachment Parent Local ID ScenePresence sp = GetScenePresence(sceneObject.OwnerID); + Console.WriteLine("AAAA"); + //uint parentLocalID = 0; if (sp != null) { @@ -2562,20 +2588,25 @@ namespace OpenSim.Region.Framework.Scenes //grp.SetFromAssetID(grp.RootPart.LastOwnerID); m_log.DebugFormat( "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); - + + RootPrim.RemFlag(PrimFlags.TemporaryOnRez); AttachObject( sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); - RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - grp.SendGroupFullUpdate(); + + //grp.SendGroupFullUpdate(); } else { RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } + + Console.WriteLine("BBBB"); } else { + m_log.DebugFormat("[SCENE]: Adding ordinary object {0} {1}", sceneObject.Name, sceneObject.LocalId); + AddRestoredSceneObject(sceneObject, true, false); if (!Permissions.CanObjectEntry(sceneObject.UUID, diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 2f6a0dbb98..50feb17cc4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -1383,7 +1383,9 @@ namespace OpenSim.Region.Framework.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendInitialFullUpdateToAllClients(); + Console.WriteLine("SCS 1"); agent.CrossAttachmentsIntoNewRegion(neighbourHandle, true); + Console.WriteLine("SCS 2"); // m_scene.SendKillObject(m_localId); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 59a2f41218..fa3c5eb5f1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -216,11 +216,15 @@ namespace OpenSim.Region.Framework.Scenes /// If true, we won't persist this object until it changes /// If false, we'll persist this object immediately /// + /// + /// If true, we send updates to the client to tell it about this object + /// If false, we leave it up to the caller to do this + /// /// /// true if the object was added, false if an object with the same uuid was already in the scene /// protected internal bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { if (!alreadyPersisted) { @@ -228,8 +232,29 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.HasGroupChanged = true; } - return AddSceneObject(sceneObject, attachToBackup, true); + return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } + +// /// +// /// Add an object into the scene that has come from storage +// /// +// /// +// /// +// /// If true, changes to the object will be reflected in its persisted data +// /// If false, the persisted data will not be changed even if the object in the scene is changed +// /// +// /// +// /// If true, we won't persist this object until it changes +// /// If false, we'll persist this object immediately +// /// +// /// +// /// true if the object was added, false if an object with the same uuid was already in the scene +// /// +// protected internal bool AddRestoredSceneObject( +// SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) +// { +// AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); +// } /// /// Add a newly created object to the scene. This will both update the scene, and send information about the @@ -611,11 +636,13 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { + Console.WriteLine("HERE A"); SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { + Console.WriteLine("HERE -1"); // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -654,9 +681,12 @@ namespace OpenSim.Region.Framework.Scenes itemId = group.GetFromItemID(); } + Console.WriteLine("HERE 0"); m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); + Console.WriteLine("HERE 1"); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); + Console.WriteLine("HERE 2"); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 602b811fe9..ba3fde7d92 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1494,6 +1494,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToClient(IClientAPI remoteClient) { + if (IsAttachment) + m_log.DebugFormat( + "[SOG]: Sending full update to client {0} for {1} {2}", remoteClient.Name, Name, LocalId); + SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); lock (m_parts) @@ -1513,8 +1517,9 @@ namespace OpenSim.Region.Framework.Scenes /// internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) { -// m_log.DebugFormat( -// "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); + if (IsAttachment) + m_log.DebugFormat( + "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); if (m_rootPart.UUID == part.UUID) { @@ -1994,7 +1999,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { -// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + if (IsAttachment) + m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); RootPart.AddFullUpdateToAvatar(presence); @@ -2026,7 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { -// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); + if (IsAttachment) + m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); checkAtTargets(); RootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a85a4b3179..ffbb4274b1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1259,16 +1259,17 @@ namespace OpenSim.Region.Framework.Scenes /// Tell all scene presences that they should send updates for this part to their clients /// public void AddFullUpdateToAllAvatars() - { + { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - { - avatars[i].SceneViewer.QueuePartForUpdate(this); - } + AddFullUpdateToAvatar(avatars[i]); } public void AddFullUpdateToAvatar(ScenePresence presence) { + if (IsAttachment) + m_log.DebugFormat("AddFullUpdateToAllAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); + presence.SceneViewer.QueuePartForUpdate(this); } @@ -1287,13 +1288,14 @@ namespace OpenSim.Region.Framework.Scenes { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - { - avatars[i].SceneViewer.QueuePartForUpdate(this); - } + AddTerseUpdateToAvatar(avatars[i]); } public void AddTerseUpdateToAvatar(ScenePresence presence) { + if (IsAttachment) + m_log.DebugFormat("AddTerseUpdateToAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); + presence.SceneViewer.QueuePartForUpdate(this); } @@ -2727,7 +2729,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleFullUpdate() { -// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); + if (IsAttachment) + m_log.DebugFormat("[SOP]: Scheduling full update for {0} {1}", Name, LocalId); if (m_parentGroup != null) { @@ -2840,6 +2843,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending part full update to {0} for {1} {2}", remoteClient.Name, Name, LocalId); + m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); } @@ -2848,6 +2855,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClients() { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending full update for {0} {1} for all clients", Name, LocalId); + ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2859,6 +2870,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToAllClientsExcept(UUID agentID) { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending full update for {0} {1} to all clients except {2}", Name, LocalId, agentID); + ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2965,6 +2980,9 @@ namespace OpenSim.Region.Framework.Scenes { if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes { + if (IsAttachment) + m_log.DebugFormat("[SOP]: Sending scheduled full update for {0} {1}", Name, LocalId); + AddFullUpdateToAllAvatars(); ClearUpdateSchedule(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index e4296ef66c..6f2bef982e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -39,6 +40,8 @@ namespace OpenSim.Region.Framework.Scenes { public class SceneViewer : ISceneViewer { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected ScenePresence m_presence; protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); protected Queue m_pendingObjects; @@ -60,6 +63,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void QueuePartForUpdate(SceneObjectPart part) { + if (part.IsAttachment) + m_log.DebugFormat("[SCENE VIEWER]: Queueing part {0} {1} for update", part.Name, part.LocalId); + lock (m_partsUpdateQueue) { m_partsUpdateQueue.Enqueue(part); @@ -134,7 +140,7 @@ namespace OpenSim.Region.Framework.Scenes } else if (update.LastTerseUpdateTime <= part.TimeStampTerse) { -// m_log.DebugFormat( +// m_log.DebugFormat(AddFullUpdateToAvatar // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampTerse); diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 3c7adf5419..4e7ef51bd8 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,7 @@ - + From c7d812802fcb2531c49f0fe4f4971571f332183d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 28 May 2010 18:49:32 +0100 Subject: [PATCH 19/34] Adjust Scene.DeleteAllSceneObjects() to not delete objects attached to avatars. This is going to be the right behaviour in all cases, I should think. This means that avatars in region when an oar is loaded do not lose their attachments --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dd2d2cc4d2..f8ca0479ef 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1908,7 +1908,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Delete every object from the scene + /// Delete every object from the scene. This does not include attachments worn by avatars. /// public void DeleteAllSceneObjects() { @@ -1919,7 +1919,11 @@ namespace OpenSim.Region.Framework.Scenes foreach (EntityBase e in entities) { if (e is SceneObjectGroup) - DeleteSceneObject((SceneObjectGroup)e, false); + { + SceneObjectGroup sog = (SceneObjectGroup)e; + if (!sog.IsAttachment) + DeleteSceneObject((SceneObjectGroup)e, false); + } } } } From 992efdc28325fb87776c9bac777342a0379ebe8d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 31 May 2010 01:02:04 +0200 Subject: [PATCH 20/34] Fix a nullref in EventManager caused by RegionReady not setting the scene --- .../Scripting/RegionReadyModule/RegionReadyModule.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c653e98401..672109b773 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -146,6 +146,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); c.Sender = null; c.SenderUUID = UUID.Zero; + c.Scene = m_scene; m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); From f5ca70127347b20f9bfbb81fe777b9a602bfef0d Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 1 Jun 2010 14:19:26 +0100 Subject: [PATCH 21/34] Comment and remove JScript support. Mono 2.7Dev and 2.8 no longer include the needed libraries --- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 38 +++++++++---------- prebuild.xml | 7 ---- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index d8c0ba57a5..959164b8fd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -32,7 +32,7 @@ using System.Globalization; using System.Reflection; using System.IO; using Microsoft.CSharp; -using Microsoft.JScript; +//using Microsoft.JScript; using Microsoft.VisualBasic; using log4net; using OpenSim.Region.Framework.Interfaces; @@ -82,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); - private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider(); +// private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider(); private static CSharpCodeProvider YPcodeProvider = new CSharpCodeProvider(); // YP is translated into CSharp private static YP2CSConverter YP_Converter = new YP2CSConverter(); @@ -395,9 +395,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools case enumCompileType.vb: compileScript = CreateVBCompilerScript(compileScript); break; - case enumCompileType.js: - compileScript = CreateJSCompilerScript(compileScript); - break; +// case enumCompileType.js: +// compileScript = CreateJSCompilerScript(compileScript); +// break; case enumCompileType.yp: compileScript = CreateYPCompilerScript(compileScript); break; @@ -420,16 +420,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } } - private static string CreateJSCompilerScript(string compileScript) - { - compileScript = String.Empty + - "import OpenSim.Region.ScriptEngine.Shared; import System.Collections.Generic;\r\n" + - "package SecondLife {\r\n" + - "class Script extends OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + - compileScript + - "} }\r\n"; - return compileScript; - } +// private static string CreateJSCompilerScript(string compileScript) +// { +// compileScript = String.Empty + +// "import OpenSim.Region.ScriptEngine.Shared; import System.Collections.Generic;\r\n" + +// "package SecondLife {\r\n" + +// "class Script extends OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass { \r\n" + +// compileScript + +// "} }\r\n"; +// return compileScript; +// } private static string CreateCSCompilerScript(string compileScript) { @@ -580,10 +580,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } } while (!complete); break; - case enumCompileType.js: - results = JScodeProvider.CompileAssemblyFromSource( - parameters, Script); - break; +// case enumCompileType.js: +// results = JScodeProvider.CompileAssemblyFromSource( +// parameters, Script); +// break; case enumCompileType.yp: results = YPcodeProvider.CompileAssemblyFromSource( parameters, Script); diff --git a/prebuild.xml b/prebuild.xml index 6b2579248e..66ab532f71 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -765,7 +765,6 @@ - @@ -1619,7 +1618,6 @@ - @@ -1702,7 +1700,6 @@ - @@ -2671,7 +2668,6 @@ ../../../../../bin/ - @@ -2808,7 +2804,6 @@ - @@ -3270,7 +3265,6 @@ - @@ -3334,7 +3328,6 @@ - From 241ed5734ee3c5b1417484dfa22af6cf6ae60b82 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 17:14:37 +0100 Subject: [PATCH 22/34] After aborting a thread, wait for it to actually finish. EXPERIMENTAL for OSG testing. DO NOT UPDATE TO THIS UNLESS YOU KNOW WHAT YOU'RE DOING! --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index d30d2dcacc..f5b187f802 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -536,6 +536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (!m_InSelfDelete) result.Abort(); + result.Wait(TimeSpan.FromSeconds(10)); lock (m_EventQueue) { m_CurrentResult = null; From c5cfae7bac9273d32c78409fe5080a202043b277 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 17:39:58 +0100 Subject: [PATCH 23/34] Revert "After aborting a thread, wait for it to actually finish. EXPERIMENTAL for OSG" This reverts commit 241ed5734ee3c5b1417484dfa22af6cf6ae60b82. --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index f5b187f802..d30d2dcacc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -536,7 +536,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (!m_InSelfDelete) result.Abort(); - result.Wait(TimeSpan.FromSeconds(10)); lock (m_EventQueue) { m_CurrentResult = null; From 698066d7e3a59281b6b1caa499ad32ff389c8bb6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 17:41:28 +0100 Subject: [PATCH 24/34] Next OSG TEST RELEASE. Join aborted threads. --- ThirdParty/SmartThreadPool/WorkItem.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ThirdParty/SmartThreadPool/WorkItem.cs b/ThirdParty/SmartThreadPool/WorkItem.cs index d0c0524d10..12668b03e2 100644 --- a/ThirdParty/SmartThreadPool/WorkItem.cs +++ b/ThirdParty/SmartThreadPool/WorkItem.cs @@ -1027,7 +1027,10 @@ namespace Amib.Threading.Internal lock (this) { if(currentThread != null) + { currentThread.Abort(); + currentThread.Join(); + } } } } From c38f7c96e78436cbefcbbe1d8820e28488f6d2dd Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 18:00:44 +0100 Subject: [PATCH 25/34] Revert "Next OSG TEST RELEASE. Join aborted threads." This reverts commit 698066d7e3a59281b6b1caa499ad32ff389c8bb6. --- ThirdParty/SmartThreadPool/WorkItem.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/ThirdParty/SmartThreadPool/WorkItem.cs b/ThirdParty/SmartThreadPool/WorkItem.cs index 12668b03e2..d0c0524d10 100644 --- a/ThirdParty/SmartThreadPool/WorkItem.cs +++ b/ThirdParty/SmartThreadPool/WorkItem.cs @@ -1027,10 +1027,7 @@ namespace Amib.Threading.Internal lock (this) { if(currentThread != null) - { currentThread.Abort(); - currentThread.Join(); - } } } } From 20e6b7a320df97c69c9f23b2081c376951c39bed Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 18:05:58 +0100 Subject: [PATCH 26/34] Next OSG test. Cowardly refuse to save the state of badly behaved scripts, instead of forcing the issue. --- .../Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index d30d2dcacc..18351ad4a0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -541,7 +541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_CurrentResult = null; } - return true; + return false; } public void SetState(string state) @@ -991,7 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public string GetXMLState() { bool run = Running; - Stop(100); + bool stopped = Stop(100); Running = run; // We should not be doing this, but since we are about to @@ -1002,6 +1002,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // Force an update of the in-memory plugin data // + if (!stopped) + return String.Empty; + PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); return ScriptSerializer.Serialize(this); From f831a1778baa766b4810e352f3ae2ab6736e4620 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 19:57:03 +0100 Subject: [PATCH 27/34] Next OSG test. Don't remove app domains if they contain running threads. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 98e77c0b92..46d674d869 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -277,7 +277,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Clear the event queue and abort the instance thread // instance.ClearQueue(); - instance.Stop(0); + bool stopped = instance.Stop(0); // Release events, timer, etc // @@ -287,7 +287,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Must be done explicitly because they have infinite // lifetime // - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (stopped) + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); if (m_DomainScripts[instance.AppDomain].Count == 0) { m_DomainScripts.Remove(instance.AppDomain); @@ -804,7 +805,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts.Remove(itemID); instance.ClearQueue(); - instance.Stop(0); + bool stopped = instance.Stop(0); // bool objectRemoved = false; @@ -829,7 +830,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.RemoveState(); instance.DestroyScriptInstance(); - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (stopped) + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); if (m_DomainScripts[instance.AppDomain].Count == 0) { m_DomainScripts.Remove(instance.AppDomain); From 82d0d1c092d309ab5c498e279155fc1ceb5738c8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 2 Jun 2010 21:02:53 +0100 Subject: [PATCH 28/34] Revert "Next OSG test. Don't remove app domains if they contain running threads." This reverts commit f831a1778baa766b4810e352f3ae2ab6736e4620. With this, post-fixes is back to normal. --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 46d674d869..98e77c0b92 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -277,7 +277,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Clear the event queue and abort the instance thread // instance.ClearQueue(); - bool stopped = instance.Stop(0); + instance.Stop(0); // Release events, timer, etc // @@ -287,8 +287,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine // Must be done explicitly because they have infinite // lifetime // - if (stopped) - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); if (m_DomainScripts[instance.AppDomain].Count == 0) { m_DomainScripts.Remove(instance.AppDomain); @@ -805,7 +804,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts.Remove(itemID); instance.ClearQueue(); - bool stopped = instance.Stop(0); + instance.Stop(0); // bool objectRemoved = false; @@ -830,8 +829,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.RemoveState(); instance.DestroyScriptInstance(); - if (stopped) - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); if (m_DomainScripts[instance.AppDomain].Count == 0) { m_DomainScripts.Remove(instance.AppDomain); From 8eb70f9719585f26f4dc610b383d546bda091655 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 4 Jun 2010 17:14:12 +0100 Subject: [PATCH 29/34] Fix bug where prim items were not loaded in the new sqlite database handler This addresses mantis http://opensimulator.org/mantis/view.php?id=4739 --- OpenSim/Data/SQLite/SQLiteRegionData.cs | 66 +++++++++++++++---------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index fe6e919b54..4313db89d7 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -93,7 +93,7 @@ namespace OpenSim.Data.SQLite ds = new DataSet("Region"); - m_log.Info("[REGION DB]: Sqlite - connecting: " + connectionString); + m_log.Info("[SQLITE REGION DB]: Sqlite - connecting: " + connectionString); m_conn = new SqliteConnection(m_connectionString); m_conn.Open(); @@ -156,7 +156,7 @@ namespace OpenSim.Data.SQLite } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on prims table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on prims table"); } try @@ -165,16 +165,25 @@ namespace OpenSim.Data.SQLite } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on primshapes table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on primshapes table"); } + try + { + itemsDa.Fill(ds.Tables["primitems"]); + } + catch (Exception) + { + m_log.Info("[SQLITE REGION DB]: Caught fill error on primitems table"); + } + try { terrainDa.Fill(ds.Tables["terrain"]); } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on terrain table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on terrain table"); } try @@ -183,7 +192,7 @@ namespace OpenSim.Data.SQLite } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on land table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on land table"); } try @@ -192,7 +201,7 @@ namespace OpenSim.Data.SQLite } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on landaccesslist table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on landaccesslist table"); } try @@ -201,7 +210,7 @@ namespace OpenSim.Data.SQLite } catch (Exception) { - m_log.Info("[REGION DB]: Caught fill error on regionsettings table"); + m_log.Info("[SQLITE REGION DB]: Caught fill error on regionsettings table"); } // We have to create a data set mapping for every table, otherwise the IDataAdaptor.Update() will not populate rows with values! @@ -425,7 +434,7 @@ namespace OpenSim.Data.SQLite lock (ds) { DataRow[] primsForRegion = prims.Select(byRegion); - m_log.Info("[REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); +// m_log.Info("[SQLITE REGION DB]: Loaded " + primsForRegion.Length + " prims for region: " + regionUUID); // First, create all groups foreach (DataRow primRow in primsForRegion) @@ -447,8 +456,8 @@ namespace OpenSim.Data.SQLite } else { - m_log.Info( - "[REGION DB]: No shape found for prim in storage, so setting default box shape"); + m_log.Warn( + "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape"); prim.Shape = PrimitiveBaseShape.Default; } @@ -460,11 +469,11 @@ namespace OpenSim.Data.SQLite } 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()); + m_log.Error("[SQLITE REGION DB]: Failed create prim object in new group, exception and data follows"); + m_log.Error("[SQLITE REGION DB]: ", e); foreach (DataColumn col in prims.Columns) { - m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); + m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); } } } @@ -489,7 +498,7 @@ namespace OpenSim.Data.SQLite else { m_log.Warn( - "[REGION DB]: No shape found for prim in storage, so setting default box shape"); + "[SQLITE REGION DB]: No shape found for prim in storage, so setting default box shape"); prim.Shape = PrimitiveBaseShape.Default; } @@ -499,11 +508,11 @@ namespace OpenSim.Data.SQLite } 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()); + m_log.Error("[SQLITE REGION DB]: Failed create prim object in group, exception and data follows"); + m_log.Error("[SQLITE REGION DB]: ", e); foreach (DataColumn col in prims.Columns) { - m_log.Info("[REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); + m_log.Error("[SQLITE REGION DB]: Col: " + col.ColumnName + " => " + primRow[col]); } } } @@ -516,20 +525,23 @@ namespace OpenSim.Data.SQLite /// /// the prim private void LoadItems(SceneObjectPart prim) - { - //m_log.DebugFormat("[DATASTORE]: Loading inventory for {0}, {1}", prim.Name, prim.UUID); - + { +// m_log.DebugFormat("[SQLITE REGION DB]: Loading inventory for {0} {1}", prim.Name, prim.UUID); + DataTable dbItems = ds.Tables["primitems"]; - String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); + String sql = String.Format("primID = '{0}'", prim.UUID.ToString()); DataRow[] dbItemRows = dbItems.Select(sql); IList inventory = new List(); +// m_log.DebugFormat( +// "[SQLITE REGION DB]: Found {0} items for {1} {2}", dbItemRows.Length, prim.Name, prim.UUID); + foreach (DataRow row in dbItemRows) { TaskInventoryItem item = buildItem(row); inventory.Add(item); - //m_log.DebugFormat("[DATASTORE]: Restored item {0}, {1}", item.Name, item.ItemID); +// m_log.DebugFormat("[SQLITE REGION DB]: Restored item {0} {1}", item.Name, item.ItemID); } prim.Inventory.RestoreInventoryItems(inventory); @@ -565,7 +577,7 @@ namespace OpenSim.Data.SQLite // 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()); + m_log.Debug("[SQLITE REGION DB]: Storing terrain revision r" + revision.ToString()); String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" + " values(:RegionUUID, :Revision, :Heightfield)"; @@ -621,11 +633,11 @@ namespace OpenSim.Data.SQLite } else { - m_log.Info("[REGION DB]: No terrain found for region"); + m_log.Warn("[SQLITE REGION DB]: No terrain found for region"); return null; } - m_log.Info("[REGION DB]: Loaded terrain revision r" + rev.ToString()); + m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString()); } } return terret; @@ -1407,7 +1419,7 @@ namespace OpenSim.Data.SQLite } catch (InvalidCastException) { - m_log.ErrorFormat("[PARCEL]: unable to get parcel telehub settings for {1}", newData.Name); + m_log.ErrorFormat("[SQLITE REGION DB]: unable to get parcel telehub settings for {1}", newData.Name); newData.UserLocation = Vector3.Zero; newData.UserLookAt = Vector3.Zero; } @@ -1914,7 +1926,7 @@ namespace OpenSim.Data.SQLite /// public void StorePrimInventory(UUID primID, ICollection items) { - //m_log.InfoFormat("[REGION DB]: Entered StorePrimInventory with prim ID {0}", primID); +// m_log.DebugFormat("[SQLITE REGION DB]: Entered StorePrimInventory with prim ID {0}", primID); DataTable dbItems = ds.Tables["primitems"]; From bdeda18b52f7ab37501f1751573e26e85656a4e4 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 4 Jun 2010 18:54:48 +0100 Subject: [PATCH 30/34] Revert "commit code which stops full updates being fired multiple times when attachments cross standalone region boundaries" This reverts commit 5074d290e4aeb583560272cadc8ba09aa8337210. This gets rid of the massive amount of scene object log spam - sorry about that, folks --- .../Interregion/LocalInterregionComms.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 5 --- .../Framework/Scenes/Scene.PacketHandlers.cs | 1 - OpenSim/Region/Framework/Scenes/Scene.cs | 43 +++---------------- .../Scenes/SceneCommunicationService.cs | 2 - OpenSim/Region/Framework/Scenes/SceneGraph.cs | 34 +-------------- .../Framework/Scenes/SceneObjectGroup.cs | 15 ++----- .../Framework/Scenes/SceneObjectPart.cs | 34 ++++----------- .../Region/Framework/Scenes/SceneViewer.cs | 8 +--- bin/OpenSim.exe.config | 2 +- 10 files changed, 23 insertions(+), 123 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index 4abc2158f9..d68c683143 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { if (s.RegionInfo.RegionHandle == regionHandle) { - m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); + //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); if (isLocalCall) { // We need to make a local copy of the object diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index f556b35ac7..a2634f7bec 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2449,8 +2449,6 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_log.DebugFormat("[SCENE INVENTORY]: {0} {1} IsAttachment={2}", att.Name, att.LocalId, att.IsAttachment); - Console.WriteLine("HERE X"); ScenePresence presence; if (TryGetAvatar(remoteClient.AgentId, out presence)) { @@ -2458,12 +2456,9 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); - Console.WriteLine("HERE Y"); if (m_AvatarFactory != null) m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - - Console.WriteLine("HERE Z"); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index d8e604ff9b..ac04dc795b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -124,7 +124,6 @@ namespace OpenSim.Region.Framework.Scenes { if (((SceneObjectGroup)ent).LocalId == primLocalID) { - m_log.DebugFormat("[SCENE]: Received full update request for {0} from {1}", primLocalID, remoteClient.Name); ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f8ca0479ef..e8c49786ca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1833,28 +1833,6 @@ namespace OpenSim.Region.Framework.Scenes return sceneObject; } - /// - /// Add an object into the scene that has come from storage - /// - /// - /// - /// - /// If true, changes to the object will be reflected in its persisted data - /// If false, the persisted data will not be changed even if the object in the scene is changed - /// - /// - /// If true, we won't persist this object until it changes - /// If false, we'll persist this object immediately - /// - /// - /// true if the object was added, false if an object with the same uuid was already in the scene - /// - public bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) - { - return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); - } - /// /// Add an object into the scene that has come from storage /// @@ -1874,7 +1852,7 @@ namespace OpenSim.Region.Framework.Scenes public bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { - return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); + return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted); } /// @@ -2487,7 +2465,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IncomingCreateObject(ISceneObject sog) { - m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); + //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); SceneObjectGroup newObject; try { @@ -2559,12 +2537,10 @@ namespace OpenSim.Region.Framework.Scenes if (sceneObject.IsAttachmentCheckFull()) // Attachment { - m_log.DebugFormat("[SCENE]: Adding attachment {0} {1}", sceneObject.Name, sceneObject.LocalId); - sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); - AddRestoredSceneObject(sceneObject, false, false, false); + AddRestoredSceneObject(sceneObject, false, false); // Handle attachment special case SceneObjectPart RootPrim = sceneObject.RootPart; @@ -2572,8 +2548,6 @@ namespace OpenSim.Region.Framework.Scenes // Fix up attachment Parent Local ID ScenePresence sp = GetScenePresence(sceneObject.OwnerID); - Console.WriteLine("AAAA"); - //uint parentLocalID = 0; if (sp != null) { @@ -2592,25 +2566,20 @@ namespace OpenSim.Region.Framework.Scenes //grp.SetFromAssetID(grp.RootPart.LastOwnerID); m_log.DebugFormat( "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); - - RootPrim.RemFlag(PrimFlags.TemporaryOnRez); + AttachObject( sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); - - //grp.SendGroupFullUpdate(); + RootPrim.RemFlag(PrimFlags.TemporaryOnRez); + grp.SendGroupFullUpdate(); } else { RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } - - Console.WriteLine("BBBB"); } else { - m_log.DebugFormat("[SCENE]: Adding ordinary object {0} {1}", sceneObject.Name, sceneObject.LocalId); - AddRestoredSceneObject(sceneObject, true, false); if (!Permissions.CanObjectEntry(sceneObject.UUID, diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 50feb17cc4..2f6a0dbb98 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -1383,9 +1383,7 @@ namespace OpenSim.Region.Framework.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendInitialFullUpdateToAllClients(); - Console.WriteLine("SCS 1"); agent.CrossAttachmentsIntoNewRegion(neighbourHandle, true); - Console.WriteLine("SCS 2"); // m_scene.SendKillObject(m_localId); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index fa3c5eb5f1..59a2f41218 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -216,15 +216,11 @@ namespace OpenSim.Region.Framework.Scenes /// If true, we won't persist this object until it changes /// If false, we'll persist this object immediately /// - /// - /// If true, we send updates to the client to tell it about this object - /// If false, we leave it up to the caller to do this - /// /// /// true if the object was added, false if an object with the same uuid was already in the scene /// protected internal bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { if (!alreadyPersisted) { @@ -232,29 +228,8 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.HasGroupChanged = true; } - return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); + return AddSceneObject(sceneObject, attachToBackup, true); } - -// /// -// /// Add an object into the scene that has come from storage -// /// -// /// -// /// -// /// If true, changes to the object will be reflected in its persisted data -// /// If false, the persisted data will not be changed even if the object in the scene is changed -// /// -// /// -// /// If true, we won't persist this object until it changes -// /// If false, we'll persist this object immediately -// /// -// /// -// /// true if the object was added, false if an object with the same uuid was already in the scene -// /// -// protected internal bool AddRestoredSceneObject( -// SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) -// { -// AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); -// } /// /// Add a newly created object to the scene. This will both update the scene, and send information about the @@ -636,13 +611,11 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { - Console.WriteLine("HERE A"); SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { - Console.WriteLine("HERE -1"); // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -681,12 +654,9 @@ namespace OpenSim.Region.Framework.Scenes itemId = group.GetFromItemID(); } - Console.WriteLine("HERE 0"); m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); - Console.WriteLine("HERE 1"); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); - Console.WriteLine("HERE 2"); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ba3fde7d92..602b811fe9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1494,10 +1494,6 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToClient(IClientAPI remoteClient) { - if (IsAttachment) - m_log.DebugFormat( - "[SOG]: Sending full update to client {0} for {1} {2}", remoteClient.Name, Name, LocalId); - SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); lock (m_parts) @@ -1517,9 +1513,8 @@ namespace OpenSim.Region.Framework.Scenes /// internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) { - if (IsAttachment) - m_log.DebugFormat( - "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); +// m_log.DebugFormat( +// "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); if (m_rootPart.UUID == part.UUID) { @@ -1999,8 +1994,7 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); RootPart.AddFullUpdateToAvatar(presence); @@ -2032,8 +2026,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { - if (IsAttachment) - m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); checkAtTargets(); RootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ffbb4274b1..a85a4b3179 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1259,17 +1259,16 @@ namespace OpenSim.Region.Framework.Scenes /// Tell all scene presences that they should send updates for this part to their clients /// public void AddFullUpdateToAllAvatars() - { + { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - AddFullUpdateToAvatar(avatars[i]); + { + avatars[i].SceneViewer.QueuePartForUpdate(this); + } } public void AddFullUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("AddFullUpdateToAllAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); - presence.SceneViewer.QueuePartForUpdate(this); } @@ -1288,14 +1287,13 @@ namespace OpenSim.Region.Framework.Scenes { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - AddTerseUpdateToAvatar(avatars[i]); + { + avatars[i].SceneViewer.QueuePartForUpdate(this); + } } public void AddTerseUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("AddTerseUpdateToAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); - presence.SceneViewer.QueuePartForUpdate(this); } @@ -2729,8 +2727,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleFullUpdate() { - if (IsAttachment) - m_log.DebugFormat("[SOP]: Scheduling full update for {0} {1}", Name, LocalId); +// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); if (m_parentGroup != null) { @@ -2843,10 +2840,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending part full update to {0} for {1} {2}", remoteClient.Name, Name, LocalId); - m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); } @@ -2855,10 +2848,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClients() { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending full update for {0} {1} for all clients", Name, LocalId); - ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2870,10 +2859,6 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToAllClientsExcept(UUID agentID) { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending full update for {0} {1} to all clients except {2}", Name, LocalId, agentID); - ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2980,9 +2965,6 @@ namespace OpenSim.Region.Framework.Scenes { if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes { - if (IsAttachment) - m_log.DebugFormat("[SOP]: Sending scheduled full update for {0} {1}", Name, LocalId); - AddFullUpdateToAllAvatars(); ClearUpdateSchedule(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 6f2bef982e..e4296ef66c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; -using System.Reflection; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -40,8 +39,6 @@ namespace OpenSim.Region.Framework.Scenes { public class SceneViewer : ISceneViewer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - protected ScenePresence m_presence; protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); protected Queue m_pendingObjects; @@ -63,9 +60,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void QueuePartForUpdate(SceneObjectPart part) { - if (part.IsAttachment) - m_log.DebugFormat("[SCENE VIEWER]: Queueing part {0} {1} for update", part.Name, part.LocalId); - lock (m_partsUpdateQueue) { m_partsUpdateQueue.Enqueue(part); @@ -140,7 +134,7 @@ namespace OpenSim.Region.Framework.Scenes } else if (update.LastTerseUpdateTime <= part.TimeStampTerse) { -// m_log.DebugFormat(AddFullUpdateToAvatar +// m_log.DebugFormat( // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampTerse); diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 4e7ef51bd8..3c7adf5419 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,7 @@ - + From 50ddb20204e8eb513212fe80d80b1308280fd47f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 27 May 2010 21:35:17 +0100 Subject: [PATCH 31/34] commit code which stops full updates being fired multiple times when attachments cross standalone region boundaries lots of messy debug code here too which would need to be removed --- .../Interregion/LocalInterregionComms.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 5 +++ .../Framework/Scenes/Scene.PacketHandlers.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 43 ++++++++++++++++--- .../Scenes/SceneCommunicationService.cs | 2 + OpenSim/Region/Framework/Scenes/SceneGraph.cs | 34 ++++++++++++++- .../Framework/Scenes/SceneObjectGroup.cs | 15 +++++-- .../Framework/Scenes/SceneObjectPart.cs | 34 +++++++++++---- .../Region/Framework/Scenes/SceneViewer.cs | 8 +++- bin/OpenSim.exe.config | 2 +- 10 files changed, 123 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index d68c683143..4abc2158f9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { if (s.RegionInfo.RegionHandle == regionHandle) { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); + m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); if (isLocalCall) { // We need to make a local copy of the object diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a2634f7bec..f556b35ac7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2449,6 +2449,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + m_log.DebugFormat("[SCENE INVENTORY]: {0} {1} IsAttachment={2}", att.Name, att.LocalId, att.IsAttachment); + Console.WriteLine("HERE X"); ScenePresence presence; if (TryGetAvatar(remoteClient.AgentId, out presence)) { @@ -2456,9 +2458,12 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); + Console.WriteLine("HERE Y"); if (m_AvatarFactory != null) m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + + Console.WriteLine("HERE Z"); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index ac04dc795b..d8e604ff9b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -124,6 +124,7 @@ namespace OpenSim.Region.Framework.Scenes { if (((SceneObjectGroup)ent).LocalId == primLocalID) { + m_log.DebugFormat("[SCENE]: Received full update request for {0} from {1}", primLocalID, remoteClient.Name); ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e8c49786ca..f8ca0479ef 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1833,6 +1833,28 @@ namespace OpenSim.Region.Framework.Scenes return sceneObject; } + /// + /// Add an object into the scene that has come from storage + /// + /// + /// + /// + /// If true, changes to the object will be reflected in its persisted data + /// If false, the persisted data will not be changed even if the object in the scene is changed + /// + /// + /// If true, we won't persist this object until it changes + /// If false, we'll persist this object immediately + /// + /// + /// true if the object was added, false if an object with the same uuid was already in the scene + /// + public bool AddRestoredSceneObject( + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) + { + return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); + } + /// /// Add an object into the scene that has come from storage /// @@ -1852,7 +1874,7 @@ namespace OpenSim.Region.Framework.Scenes public bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { - return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted); + return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); } /// @@ -2465,7 +2487,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IncomingCreateObject(ISceneObject sog) { - //m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); + m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); SceneObjectGroup newObject; try { @@ -2537,10 +2559,12 @@ namespace OpenSim.Region.Framework.Scenes if (sceneObject.IsAttachmentCheckFull()) // Attachment { + m_log.DebugFormat("[SCENE]: Adding attachment {0} {1}", sceneObject.Name, sceneObject.LocalId); + sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); - AddRestoredSceneObject(sceneObject, false, false); + AddRestoredSceneObject(sceneObject, false, false, false); // Handle attachment special case SceneObjectPart RootPrim = sceneObject.RootPart; @@ -2548,6 +2572,8 @@ namespace OpenSim.Region.Framework.Scenes // Fix up attachment Parent Local ID ScenePresence sp = GetScenePresence(sceneObject.OwnerID); + Console.WriteLine("AAAA"); + //uint parentLocalID = 0; if (sp != null) { @@ -2566,20 +2592,25 @@ namespace OpenSim.Region.Framework.Scenes //grp.SetFromAssetID(grp.RootPart.LastOwnerID); m_log.DebugFormat( "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); - + + RootPrim.RemFlag(PrimFlags.TemporaryOnRez); AttachObject( sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); - RootPrim.RemFlag(PrimFlags.TemporaryOnRez); - grp.SendGroupFullUpdate(); + + //grp.SendGroupFullUpdate(); } else { RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } + + Console.WriteLine("BBBB"); } else { + m_log.DebugFormat("[SCENE]: Adding ordinary object {0} {1}", sceneObject.Name, sceneObject.LocalId); + AddRestoredSceneObject(sceneObject, true, false); if (!Permissions.CanObjectEntry(sceneObject.UUID, diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 2f6a0dbb98..50feb17cc4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -1383,7 +1383,9 @@ namespace OpenSim.Region.Framework.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendInitialFullUpdateToAllClients(); + Console.WriteLine("SCS 1"); agent.CrossAttachmentsIntoNewRegion(neighbourHandle, true); + Console.WriteLine("SCS 2"); // m_scene.SendKillObject(m_localId); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 59a2f41218..fa3c5eb5f1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -216,11 +216,15 @@ namespace OpenSim.Region.Framework.Scenes /// If true, we won't persist this object until it changes /// If false, we'll persist this object immediately /// + /// + /// If true, we send updates to the client to tell it about this object + /// If false, we leave it up to the caller to do this + /// /// /// true if the object was added, false if an object with the same uuid was already in the scene /// protected internal bool AddRestoredSceneObject( - SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) + SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { if (!alreadyPersisted) { @@ -228,8 +232,29 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.HasGroupChanged = true; } - return AddSceneObject(sceneObject, attachToBackup, true); + return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } + +// /// +// /// Add an object into the scene that has come from storage +// /// +// /// +// /// +// /// If true, changes to the object will be reflected in its persisted data +// /// If false, the persisted data will not be changed even if the object in the scene is changed +// /// +// /// +// /// If true, we won't persist this object until it changes +// /// If false, we'll persist this object immediately +// /// +// /// +// /// true if the object was added, false if an object with the same uuid was already in the scene +// /// +// protected internal bool AddRestoredSceneObject( +// SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) +// { +// AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); +// } /// /// Add a newly created object to the scene. This will both update the scene, and send information about the @@ -611,11 +636,13 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { + Console.WriteLine("HERE A"); SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { + Console.WriteLine("HERE -1"); // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -654,9 +681,12 @@ namespace OpenSim.Region.Framework.Scenes itemId = group.GetFromItemID(); } + Console.WriteLine("HERE 0"); m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); + Console.WriteLine("HERE 1"); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); + Console.WriteLine("HERE 2"); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 602b811fe9..ba3fde7d92 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1494,6 +1494,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToClient(IClientAPI remoteClient) { + if (IsAttachment) + m_log.DebugFormat( + "[SOG]: Sending full update to client {0} for {1} {2}", remoteClient.Name, Name, LocalId); + SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); lock (m_parts) @@ -1513,8 +1517,9 @@ namespace OpenSim.Region.Framework.Scenes /// internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) { -// m_log.DebugFormat( -// "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); + if (IsAttachment) + m_log.DebugFormat( + "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); if (m_rootPart.UUID == part.UUID) { @@ -1994,7 +1999,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { -// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + if (IsAttachment) + m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); RootPart.AddFullUpdateToAvatar(presence); @@ -2026,7 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { -// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); + if (IsAttachment) + m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); checkAtTargets(); RootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a85a4b3179..ffbb4274b1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1259,16 +1259,17 @@ namespace OpenSim.Region.Framework.Scenes /// Tell all scene presences that they should send updates for this part to their clients /// public void AddFullUpdateToAllAvatars() - { + { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - { - avatars[i].SceneViewer.QueuePartForUpdate(this); - } + AddFullUpdateToAvatar(avatars[i]); } public void AddFullUpdateToAvatar(ScenePresence presence) { + if (IsAttachment) + m_log.DebugFormat("AddFullUpdateToAllAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); + presence.SceneViewer.QueuePartForUpdate(this); } @@ -1287,13 +1288,14 @@ namespace OpenSim.Region.Framework.Scenes { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) - { - avatars[i].SceneViewer.QueuePartForUpdate(this); - } + AddTerseUpdateToAvatar(avatars[i]); } public void AddTerseUpdateToAvatar(ScenePresence presence) { + if (IsAttachment) + m_log.DebugFormat("AddTerseUpdateToAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); + presence.SceneViewer.QueuePartForUpdate(this); } @@ -2727,7 +2729,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleFullUpdate() { -// m_log.DebugFormat("[SCENE OBJECT PART]: Scheduling full update for {0} {1}", Name, LocalId); + if (IsAttachment) + m_log.DebugFormat("[SOP]: Scheduling full update for {0} {1}", Name, LocalId); if (m_parentGroup != null) { @@ -2840,6 +2843,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending part full update to {0} for {1} {2}", remoteClient.Name, Name, LocalId); + m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); } @@ -2848,6 +2855,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClients() { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending full update for {0} {1} for all clients", Name, LocalId); + ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2859,6 +2870,10 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToAllClientsExcept(UUID agentID) { + if (IsAttachment) + m_log.DebugFormat( + "[SCENE OBJECT PART]: Sending full update for {0} {1} to all clients except {2}", Name, LocalId, agentID); + ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) { @@ -2965,6 +2980,9 @@ namespace OpenSim.Region.Framework.Scenes { if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes { + if (IsAttachment) + m_log.DebugFormat("[SOP]: Sending scheduled full update for {0} {1}", Name, LocalId); + AddFullUpdateToAllAvatars(); ClearUpdateSchedule(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index e4296ef66c..6f2bef982e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -39,6 +40,8 @@ namespace OpenSim.Region.Framework.Scenes { public class SceneViewer : ISceneViewer { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + protected ScenePresence m_presence; protected UpdateQueue m_partsUpdateQueue = new UpdateQueue(); protected Queue m_pendingObjects; @@ -60,6 +63,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void QueuePartForUpdate(SceneObjectPart part) { + if (part.IsAttachment) + m_log.DebugFormat("[SCENE VIEWER]: Queueing part {0} {1} for update", part.Name, part.LocalId); + lock (m_partsUpdateQueue) { m_partsUpdateQueue.Enqueue(part); @@ -134,7 +140,7 @@ namespace OpenSim.Region.Framework.Scenes } else if (update.LastTerseUpdateTime <= part.TimeStampTerse) { -// m_log.DebugFormat( +// m_log.DebugFormat(AddFullUpdateToAvatar // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", // part.Name, part.UUID, part.TimeStampTerse); diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 3c7adf5419..4e7ef51bd8 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,7 @@ - + From 693b5d08381a7672b3ebeb693ee50a82e8e59125 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 7 Jun 2010 16:07:43 +0100 Subject: [PATCH 32/34] reapply fix for double sending of attachment update on standalone region crossing --- .../Interregion/LocalInterregionComms.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 8 ++--- .../Framework/Scenes/Scene.PacketHandlers.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +++--- .../Scenes/SceneCommunicationService.cs | 4 +-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 10 +++--- .../Framework/Scenes/SceneObjectGroup.cs | 20 +++++------ .../Framework/Scenes/SceneObjectPart.cs | 34 +++++++++---------- .../Region/Framework/Scenes/SceneViewer.cs | 6 ++-- 9 files changed, 48 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index 4abc2158f9..0730f8b3ee 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -260,7 +260,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { if (s.RegionInfo.RegionHandle == regionHandle) { - m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); +// m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); if (isLocalCall) { // We need to make a local copy of the object diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index f556b35ac7..a11b1f1c3c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2449,8 +2449,8 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_log.DebugFormat("[SCENE INVENTORY]: {0} {1} IsAttachment={2}", att.Name, att.LocalId, att.IsAttachment); - Console.WriteLine("HERE X"); +// m_log.DebugFormat("[SCENE INVENTORY]: {0} {1} IsAttachment={2}", att.Name, att.LocalId, att.IsAttachment); +// Console.WriteLine("HERE X"); ScenePresence presence; if (TryGetAvatar(remoteClient.AgentId, out presence)) { @@ -2458,12 +2458,12 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); - Console.WriteLine("HERE Y"); +// Console.WriteLine("HERE Y"); if (m_AvatarFactory != null) m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - Console.WriteLine("HERE Z"); +// Console.WriteLine("HERE Z"); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index d8e604ff9b..adc9496db0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -124,7 +124,7 @@ namespace OpenSim.Region.Framework.Scenes { if (((SceneObjectGroup)ent).LocalId == primLocalID) { - m_log.DebugFormat("[SCENE]: Received full update request for {0} from {1}", primLocalID, remoteClient.Name); +// m_log.DebugFormat("[SCENE]: Received full update request for {0} from {1}", primLocalID, remoteClient.Name); ((SceneObjectGroup)ent).SendFullUpdateToClient(remoteClient); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f8ca0479ef..7089368ee4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2487,7 +2487,7 @@ namespace OpenSim.Region.Framework.Scenes /// public bool IncomingCreateObject(ISceneObject sog) { - m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); +// m_log.Debug(" >>> IncomingCreateObject(sog) <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); SceneObjectGroup newObject; try { @@ -2559,7 +2559,7 @@ namespace OpenSim.Region.Framework.Scenes if (sceneObject.IsAttachmentCheckFull()) // Attachment { - m_log.DebugFormat("[SCENE]: Adding attachment {0} {1}", sceneObject.Name, sceneObject.LocalId); +// m_log.DebugFormat("[SCENE]: Adding attachment {0} {1}", sceneObject.Name, sceneObject.LocalId); sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); sceneObject.RootPart.AddFlag(PrimFlags.Phantom); @@ -2572,7 +2572,7 @@ namespace OpenSim.Region.Framework.Scenes // Fix up attachment Parent Local ID ScenePresence sp = GetScenePresence(sceneObject.OwnerID); - Console.WriteLine("AAAA"); +// Console.WriteLine("AAAA"); //uint parentLocalID = 0; if (sp != null) @@ -2605,11 +2605,11 @@ namespace OpenSim.Region.Framework.Scenes RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } - Console.WriteLine("BBBB"); +// Console.WriteLine("BBBB"); } else { - m_log.DebugFormat("[SCENE]: Adding ordinary object {0} {1}", sceneObject.Name, sceneObject.LocalId); +// m_log.DebugFormat("[SCENE]: Adding ordinary object {0} {1}", sceneObject.Name, sceneObject.LocalId); AddRestoredSceneObject(sceneObject, true, false); diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 50feb17cc4..67fa13d680 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -1383,9 +1383,9 @@ namespace OpenSim.Region.Framework.Scenes // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendInitialFullUpdateToAllClients(); - Console.WriteLine("SCS 1"); +// Console.WriteLine("SCS 1"); agent.CrossAttachmentsIntoNewRegion(neighbourHandle, true); - Console.WriteLine("SCS 2"); +// Console.WriteLine("SCS 2"); // m_scene.SendKillObject(m_localId); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index fa3c5eb5f1..bdab6966ca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -636,13 +636,13 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { - Console.WriteLine("HERE A"); +// Console.WriteLine("HERE A"); SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { - Console.WriteLine("HERE -1"); +// Console.WriteLine("HERE -1"); // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. @@ -681,12 +681,12 @@ namespace OpenSim.Region.Framework.Scenes itemId = group.GetFromItemID(); } - Console.WriteLine("HERE 0"); +// Console.WriteLine("HERE 0"); m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); - Console.WriteLine("HERE 1"); +// Console.WriteLine("HERE 1"); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); - Console.WriteLine("HERE 2"); +// Console.WriteLine("HERE 2"); // In case it is later dropped again, don't let // it get cleaned up // diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ba3fde7d92..451c6f9f70 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1494,9 +1494,9 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToClient(IClientAPI remoteClient) { - if (IsAttachment) - m_log.DebugFormat( - "[SOG]: Sending full update to client {0} for {1} {2}", remoteClient.Name, Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat( +// "[SOG]: Sending full update to client {0} for {1} {2}", remoteClient.Name, Name, LocalId); SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); @@ -1517,9 +1517,9 @@ namespace OpenSim.Region.Framework.Scenes /// internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part, uint clientFlags) { - if (IsAttachment) - m_log.DebugFormat( - "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); +// if (IsAttachment) +// m_log.DebugFormat( +// "[SOG]: Sending part full update to {0} for {1} {2}", remoteClient.Name, part.Name, part.LocalId); if (m_rootPart.UUID == part.UUID) { @@ -1999,8 +1999,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); +// if (IsAttachment) +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); RootPart.AddFullUpdateToAvatar(presence); @@ -2032,8 +2032,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { - if (IsAttachment) - m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); +// if (IsAttachment) +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); checkAtTargets(); RootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ffbb4274b1..33624a2941 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1267,8 +1267,8 @@ namespace OpenSim.Region.Framework.Scenes public void AddFullUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("AddFullUpdateToAllAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat("AddFullUpdateToAllAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); presence.SceneViewer.QueuePartForUpdate(this); } @@ -1293,8 +1293,8 @@ namespace OpenSim.Region.Framework.Scenes public void AddTerseUpdateToAvatar(ScenePresence presence) { - if (IsAttachment) - m_log.DebugFormat("AddTerseUpdateToAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat("AddTerseUpdateToAvatar() {0} for {1} {2}", presence.Name, Name, LocalId); presence.SceneViewer.QueuePartForUpdate(this); } @@ -2729,8 +2729,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleFullUpdate() { - if (IsAttachment) - m_log.DebugFormat("[SOP]: Scheduling full update for {0} {1}", Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat("[SOP]: Scheduling full update for {0} {1}", Name, LocalId); if (m_parentGroup != null) { @@ -2843,9 +2843,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdate(IClientAPI remoteClient, uint clientFlags) { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending part full update to {0} for {1} {2}", remoteClient.Name, Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Sending part full update to {0} for {1} {2}", remoteClient.Name, Name, LocalId); m_parentGroup.SendPartFullUpdate(remoteClient, this, clientFlags); } @@ -2855,9 +2855,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendFullUpdateToAllClients() { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending full update for {0} {1} for all clients", Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Sending full update for {0} {1} for all clients", Name, LocalId); ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) @@ -2870,9 +2870,9 @@ namespace OpenSim.Region.Framework.Scenes public void SendFullUpdateToAllClientsExcept(UUID agentID) { - if (IsAttachment) - m_log.DebugFormat( - "[SCENE OBJECT PART]: Sending full update for {0} {1} to all clients except {2}", Name, LocalId, agentID); +// if (IsAttachment) +// m_log.DebugFormat( +// "[SCENE OBJECT PART]: Sending full update for {0} {1} to all clients except {2}", Name, LocalId, agentID); ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); for (int i = 0; i < avatars.Length; i++) @@ -2980,8 +2980,8 @@ namespace OpenSim.Region.Framework.Scenes { if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes { - if (IsAttachment) - m_log.DebugFormat("[SOP]: Sending scheduled full update for {0} {1}", Name, LocalId); +// if (IsAttachment) +// m_log.DebugFormat("[SOP]: Sending scheduled full update for {0} {1}", Name, LocalId); AddFullUpdateToAllAvatars(); ClearUpdateSchedule(); diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 6f2bef982e..23663dd58a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -63,8 +63,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void QueuePartForUpdate(SceneObjectPart part) { - if (part.IsAttachment) - m_log.DebugFormat("[SCENE VIEWER]: Queueing part {0} {1} for update", part.Name, part.LocalId); +// if (part.IsAttachment) +// m_log.DebugFormat("[SCENE VIEWER]: Queueing part {0} {1} for update", part.Name, part.LocalId); lock (m_partsUpdateQueue) { From 912f0c7fde1d3ec159b9f9b61136a2ac64e7d9dd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 7 Jun 2010 18:49:22 +0100 Subject: [PATCH 33/34] Stop some hud components disappearing on region crossings If viewers (or at least, Linden Viewer 1.23.5) receive child hud object updates before the root prim, then the children are not displayed. Updates were being queued in LLClientView in the right order (root first) but were being sent in a random order since they were all at the same prioritization This commit prioritizes the root prim of a hud to its highest level when queued. I'm not sure if the periodic reprioritization triggered via ScenePresence might reset this, but boosting priority appears to work so far. Also committed is a belt and braces mechanism in LLClientView to prevent child hud prim being sent out before their root, but since this doesn't appear to be needed it is currently commented out. --- .../ClientStack/LindenUDP/LLClientView.cs | 54 ++++++++++++++++--- .../Framework/Scenes/SceneObjectPart.cs | 31 +++++++++-- .../Region/Framework/Scenes/ScenePresence.cs | 4 +- bin/OpenSim.exe.config | 4 +- 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 724c8bc986..37929f2374 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -365,6 +365,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// protected HashSet m_killRecord; +// protected HashSet m_attachmentsQueued; +// protected HashSet m_attachmentsSent; + private int m_moneyBalance; private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; @@ -456,6 +459,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_primFullUpdates = new PriorityQueue(m_scene.Entities.Count); m_fullUpdateDataBlocksBuilder = new List(); m_killRecord = new HashSet(); +// m_attachmentsQueued = new HashSet(); +// m_attachmentsSent = new HashSet(); m_assetService = m_scene.RequestModuleInterface(); m_hyperAssets = m_scene.RequestModuleInterface(); @@ -3401,6 +3406,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); OutPacket(objupdate, ThrottleOutPacketType.Task); + + // We need to record the avatar local id since the root prim of an attachment points to this. +// m_attachmentsSent.Add(data.AvatarLocalID); } /// @@ -3523,6 +3531,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); + +// if (data.attachment) +// m_attachmentsQueued.Add(data.localID); lock (m_primFullUpdates.SyncRoot) m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); @@ -3549,15 +3560,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); if (!m_killRecord.Contains(block.ID)) - { + { +// if (m_attachmentsQueued.Contains(block.ID)) +// { +// string text = Util.FieldToString(block.Text); +// if (text.IndexOf("\n") >= 0) +// text = text.Remove(text.IndexOf("\n")); +// +// if (m_attachmentsSent.Contains(block.ParentID)) +// { +// m_log.DebugFormat( +// "[CLIENT]: Sending full info about attached prim {0} text {1}", +// block.ID, text); +// +// m_fullUpdateDataBlocksBuilder.Add(block); +// +// m_attachmentsSent.Add(block.ID); +// } +// else +// { +// m_log.DebugFormat( +// "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet", +// block.ID, text, block.ParentID); +// +// lock (m_primFullUpdates.SyncRoot) +// m_primFullUpdates.Enqueue(double.MaxValue, block, block.ID); +// } +// } +// else +// { m_fullUpdateDataBlocksBuilder.Add(block); - -// string text = Util.FieldToString(outPacket.ObjectData[i].Text); -// if (text.IndexOf("\n") >= 0) -// text = text.Remove(text.IndexOf("\n")); -// m_log.DebugFormat( -// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", -// outPacket.ObjectData[i].ID, text, Name); +// } } // else // { @@ -4506,6 +4539,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) { +// if (data.attachment) +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Creating prim update block for {0}, parent {1}, priority {2}", +// data.localID, data.parentID, data.priority); + byte[] objectData = new byte[60]; data.pos.ToBytes(objectData, 0); data.vel.ToBytes(objectData, 12); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 33624a2941..479ee4d516 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2929,10 +2929,33 @@ namespace OpenSim.Region.Framework.Scenes //isattachment = ParentGroup.RootPart.IsAttachment; byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; - remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, - lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, - m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, - AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); + + double priority = ParentGroup.GetUpdatePriority(remoteClient); + if (IsRoot && IsAttachment) + { + if (double.MinValue == priority) + { + m_log.WarnFormat( + "[SOP]: Couldn't raise update priority of root part for attachment {0} {1} because priority is already highest value", + Name, LocalId); + } + else + { + priority = double.MinValue; + } + } + + remoteClient.SendPrimitiveToClient( + new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, + lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, + m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, + AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, priority)); + +// if (IsRoot && IsAttachment) +// { +// ScenePresence sp = ParentGroup.Scene.GetScenePresence(remoteClient.AgentId); +// remoteClient.ReprioritizeUpdates(StateUpdateTypes.PrimitiveFull, sp.UpdatePriority); +// } } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 49736633d4..18f2fd29ec 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3871,8 +3871,10 @@ namespace OpenSim.Region.Framework.Scenes } } - private double UpdatePriority(UpdatePriorityData data) + internal double UpdatePriority(UpdatePriorityData data) { +// m_log.DebugFormat("[SCENE PRESENCE]: Reprioritizing updates to client {0} for {1}", Name, data.localID); + EntityBase entity; SceneObjectGroup group; diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 4e7ef51bd8..aa2162e9fd 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -12,7 +12,9 @@ - + + + From 255e05beb594001af971228cf9434d1cc2a63dbd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 7 Jun 2010 19:52:45 +0100 Subject: [PATCH 34/34] minor: remove some commented out code and return ScenePresence.UpdatePriority() to private --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 479ee4d516..19ff2886e3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2950,12 +2950,6 @@ namespace OpenSim.Region.Framework.Scenes lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, priority)); - -// if (IsRoot && IsAttachment) -// { -// ScenePresence sp = ParentGroup.Scene.GetScenePresence(remoteClient.AgentId); -// remoteClient.ReprioritizeUpdates(StateUpdateTypes.PrimitiveFull, sp.UpdatePriority); -// } } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 18f2fd29ec..51cdf1b8ee 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3871,7 +3871,7 @@ namespace OpenSim.Region.Framework.Scenes } } - internal double UpdatePriority(UpdatePriorityData data) + private double UpdatePriority(UpdatePriorityData data) { // m_log.DebugFormat("[SCENE PRESENCE]: Reprioritizing updates to client {0} for {1}", Name, data.localID);