You are not logged in (login or register) Sitemap | Help!

More Experiments with MRM's

...help from outside.

Edited by: SP


Ziah continues her experiments with MRM or Mini Region Modules. Now it's time to hook up to a database using an external class library... can it be done? Let's find out

In my first two Articles about MRM's ( Mini Region Modules ) i explored how you can use them to go beyond some of LSL's restrictions and write scripts in a more elegant way. Reading one of Adam's Articles once again, I thought it was time to unleash the real Power of MRM's. ( MRM: Language Extensions and Libraries )

The ability, not only to write your own Libraries ( a Feature that every LSL Scripter is missing dreadfully ) but also use existing ones, opens almost unlimited possibilities to Scripters. The first thing that slipped into my Mind was direct Database access. So, let's try it. A look at the OpenSim Sourcecode showed me, what I would need to access a MySqlDatabase. So let' start with

//@DEPENDS:MySql.Data.dll

and

using MySql.Data.MySqlClient;

That should give us the necessary Libraries to access a Database. Now, i only need a crash course in c# with mysql. Connection to a MySQL Database. My MySql Database is located on the same Computer as my OpenSim Installation, so the Connection String should be

string s = "Server=localhost;Port=3306;Database=MRm1;User ID=mrm1;Password=mrm1;Pooling=false;";

Let's quick create a new Database and Table for this Experiment. Tha Table should my look like this :

--
-- Database: `MRM1`
--

-- --------------------------------------------------------

--
-- Table structure for table `w_objects`
--

CREATE TABLE IF NOT EXISTS `w_objects` (
  `id` smallint(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `desc` varchar(30) DEFAULT NULL,
  `key` varchar(36) DEFAULT NULL,
  `pos` varchar(13) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

And now, Open Sesame! Database..

dbcon = new MySqlConnection(s);


 try
 {  
   dbcon.Open();                        
 }     
 catch(Exception ex)
 {
     throw new Exception("Can't connect to Database ; " + ex.ToString());     
 } 
 Host.Object.Say("Connection to Database established..."); 

Aha, the Systems kindly calls my Attention to the fact, that i need to declare what i want to use in c#, and if i want to use the Class Exceptions, i need :

using System;

but now, let's try to connect to the Database,

12:05:24 - [CLIENT]: Client thread for Ziah Li bdc9ddcd-6b23-4750-b865-bc003d94a80e crashed.  Logging them out.
12:05:24 - System.Exception: Can't connect to Database ; MySql.Data.MySqlClient.MySqlException: Access denied for user 'mrm1'@'localhost' to database 'MRm1'
  at MySql.Data.MySqlClient.MySqlStream.OpenPacket () [0x00000]                                                                                                                                                
  at MySql.Data.MySqlClient.NativeDriver.Authenticate411 () [0x00000]                                                                                                                                          
  at MySql.Data.MySqlClient.NativeDriver.Authenticate () [0x00000]
  at MySql.Data.MySqlClient.NativeDriver.Open () [0x00000]
  at MySql.Data.MySqlClient.Driver.Create (MySql.Data.MySqlClient.MySqlConnectionStringBuilder settings) [0x00000]
  at MySql.Data.MySqlClient.MySqlConnection.Open () [0x00000]

ouch, i got disconnected from OpenSim, just because the access to the Database was denied...hmmm...Adam? Ok, what's wrong? ....database 'MRm1'?..oops. Can happen....let's change that to MRM1 and finally :

[3:12]  MRM TEST 7: Connection to Database established...

now let's do some stuff.... Just for fun, i would like to store then Name, Description, UUID and Position of every Object in My Sim into the Database Table.

foreach(IObject obj in World.Objects)
{ 
    string o_name = obj.Name;
      string o_uuid = obj.GlobalID.ToString();
      string o_desc = obj.Description;
      string o_pos = obj.WorldPosition.ToString();
                
                
      MySqlCommand cmd = new MySqlCommand("INSERT INTO `MRM1`.`w_objects` (`name`,`desc`,`key`,`pos`) VALUES(?name,?desc,?key,?pos);",dbcon);

               
       cmd.Parameters.AddWithValue("?name",o_name);
       cmd.Parameters.AddWithValue("?desc",o_desc);
       cmd.Parameters.AddWithValue("?key",o_uuid);
       cmd.Parameters.AddWithValue("?pos",o_pos);
       cmd.ExecuteNonQuery();                                                                                                                            cmd.Dispose();
                              
       Host.Object.Say(o_name + " stored.");                                                                     
}    

and close the Connection again

           dbcon.Close();
           Host.Object.Say("Connection to Database closed..."); 

save and click....

[10:27]  MRM TEST 7: Let's do it!
[10:27]  MRM TEST 7: Connection to Database established...
[10:27]  MRM TEST 7: Primitive stored.
[10:27]  MRM TEST 7: new Improved barrel stored.
[10:27]  MRM TEST 7: YoutubeRC stored.
[10:27]  MRM TEST 7: MRM  Tests DUMMY stored.
[10:27]  MRM TEST 7: PingStats stored.
[10:27]  MRM TEST 7: PingBox stored.
[10:27]  MRM TEST 7: p3 stored.
[10:27]  MRM TEST 7: SurfBoard stored.
[10:27]  MRM TEST 7: Segment stored.
[10:27]  MRM TEST 7: Segment stored.
[10:27]  MRM TEST 7: MRM Test 6 stored.
[10:27]  MRM TEST 7: Primitive stored.
[10:27]  MRM TEST 7: OpenSimInfo stored.
[10:27]  MRM TEST 7: Blimp stored.
...
[10:27]  MRM TEST 7: MRM TEST 7 stored.
[10:27]  MRM TEST 7: Connection to Database closed...

and yes, looking a the Database Table, the Data is there...

Untitled-1

 

I know, the code in this Example is a bit sloppy, but as a proof of concept, it should be ok. So, if we consider that MRM's also don't suffer from the limitations and restriction we know from LSL, this could remove the need for those PHP or Java, Ruby or whatever Back-ends we need to access with http request from LSL. Even if you don't want to rewrite existing scripts as MRM's, it should might well be possible to create a MRM-Back-end for Database-access.

Keep in Mind, that in this Example, i only used one external Library for the Database access. I'm sure there is a lot more outside worth to try. Just think about what you were always missing in LSL, throw it into Google, add ".NET" and maybe "Open Source" as Keywords, and here you go.

So, have fun and happy scripting..!

 

Appendix : The complete Script

//MRM:C#
//@DEPENDS:MySql.Data.dll
/*=============================================================
(c) all rights reserved
================================================================*/
using System;
using OpenSim.Region.OptionalModules.Scripting.Minimodule;
using OpenMetaverse;

using MySql.Data.MySqlClient;


namespace OpenSim{

    
//MRM:C#
//@DEPENDS:MySql.Data.dll
/*=============================================================
(c) all rights reserved
================================================================*/
using System;
using OpenSim.Region.OptionalModules.Scripting.Minimodule;
using OpenMetaverse;

using MySql.Data.MySqlClient;


namespace OpenSim{

    

   class MiniModule:MRMBase
   {
      

      private MySqlConnection dbcon;
         
      public override void Start()
        {
           
            Host.Object.Say("Starting up a useless script.(MRM)");                 
            Host.Object.OnTouch += OnTouched;
            
            string s = "Server=localhost;Port=3306;Database=MRM1;User ID=mrm1;Password=mrm1;Pooling=false;";
            dbcon = new MySqlConnection(s);
            
            dbcon.Close();
        }
   
   
      void OnTouched(IObject sender, TouchEventArgs e)
        {

            
           Host.Object.Say("Let's do it!");
           
           try
           {  
                dbcon.Open();                        
           }     
           catch(Exception ex)
           {
                throw new Exception("Can't connect to Database ; " + ex.ToString());     
           } 
           Host.Object.Say("Connection to Database established..."); 
        
        
           foreach(IObject obj in World.Objects)
           { 
               string o_name = obj.Name;
               string o_uuid = obj.GlobalID.ToString();
               string o_desc = obj.Description;
               string o_pos = obj.WorldPosition.ToString();
                
                
               MySqlCommand cmd = new MySqlCommand("INSERT INTO `MRM1`.`w_objects` (`name`,`desc`,`key`,`pos`) VALUES(?name,?desc,?key,?pos);",dbcon);

               
               cmd.Parameters.AddWithValue("?name",o_name);
               cmd.Parameters.AddWithValue("?desc",o_desc);
               cmd.Parameters.AddWithValue("?key",o_uuid);
               cmd.Parameters.AddWithValue("?pos",o_pos);
               cmd.ExecuteNonQuery();                                                                                                                        cmd.Dispose();
                              
               Host.Object.Say(o_name + " stored.");                                                                     
           }               
           dbcon.Close();
           Host.Object.Say("Connection to Database closed...");                                                                                            
        }

      public override void Stop()
        {
        
        dbcon = null;
        }   
   }
}

Article tagged: scripting | mrm


4 comment(s) for “More Experiments with MRM”


Gravatar of surangika surangika said on Friday, September 18, 2009 (10:24:29 AM)
Hi Ziah,
Did you try this code on the latest version of Opensim? I tried this in Opensim 0.6.6 and am getting the eror
'[MRM]: Error: System.Exception: Line (10,30): Error CS0012: The type'System.Data.Common.DbConnection' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'..'
It seems like the references that we can use are hardcoded into the compiler now and we cannot use them arbitrarily.
or is there any specific setting that we can change to refer additional assemblies?
Gravatar of Ziah Ziah said on Thursday, October 01, 2009 (7:32:36 AM)
Hi surangika,

by the Moment, none of my MRM's are working at all. I don't know what's happening there. You may can post a message on the osgrid boards. Maybe one of the Devs has an awnswer.

Gravatar of Ziah Ziah said on Thursday, October 01, 2009 (7:32:37 AM)
Hi surangika,

by the Moment, none of my MRM's are working at all. I don't know what's happening there. You may can post a message on the osgrid boards. Maybe one of the Devs has an awnswer.

Gravatar of Justin Halls Justin Halls said on Monday, October 19, 2009 (3:16:34 AM)
Hi Ziah
these examples of MRM are a godsend. I have had the same problem with this example as surangika, but solved it by adding System.Data.Dll and system.dll from the "Program Files\Mono-2.0\lib\mono\" folder to the OpenSim folder and adding @DEPENDS: statements for each of them.
I look forward to seeing more examples - possibly using Linq through dbLinq?
thanks again