<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content=text/html;charset=iso-8859-1>
<STYLE>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</STYLE>
<META content="MSHTML 6.00.6000.16587" name=GENERATOR></HEAD>
<BODY class=hmmessage id=MailContainerBody
style="PADDING-RIGHT: 10px; PADDING-LEFT: 10px; PADDING-TOP: 15px"
bgColor=#ffffff leftMargin=0 topMargin=0 CanvasTabStop="true"
name="Compose message area">
<DIV><FONT face=Arial>Hello Stefan,</FONT></DIV>
<DIV><FONT face=Arial></FONT> </DIV>
<DIV><FONT face=Arial>I had a quick look on your code : </FONT><FONT
face=Arial>it sounds rather elegant than the approach I suggested a few
times ago !</FONT></DIV>
<DIV><FONT face=Arial></FONT> </DIV>
<DIV><FONT face=Arial>Anyway, I have posted my code below, as another
sample of db abstraction for who wants : some part of it may be interresting.
There is some command caching features, that prevent a command object to be
re-generated each calls (see AssetData implementation). There is also an
implementation attempt </FONT><FONT face=Arial>of the prim storage engine
without using a data adapter.</FONT></DIV>
<DIV><FONT face=Arial></FONT> </DIV>
<DIV><FONT face=Arial><A
title="http://filebin.ca/nytues/DbEngine.zip
CTRL + Cliquez ici pour suivre le lien"
href="http://filebin.ca/nytues/DbEngine.zip">http://filebin.ca/nytues/DbEngine.zip</A></FONT></DIV>
<DIV><FONT face=Arial></FONT> </DIV>
<DIV><FONT face=Arial>Stefan, It would be motivating if you could provide a
sample about how the TribalMedia data framework should work. Could that be done
by implementing the very simple asset server as an example ? I propose we would
make it work, make tests, comment and try to improve it, then it may serve as a
baseline for the other db stuff ?</FONT></DIV>
<DIV><FONT face=Arial></FONT> </DIV>
<DIV><FONT face=Arial>Cheers,</FONT></DIV>
<DIV><FONT face=Arial>Laurent</FONT><BR></DIV>
<DIV style="FONT: 10pt Tahoma">
<DIV style="BACKGROUND: #f5f5f5">
<DIV style="font-color: black"><B>From:</B> <A
title="mailto:stefan@tribalmedia.se
CTRL + Cliquez ici pour suivre le lien"
href="mailto:stefan@tribalmedia.se">Stefan Andersson</A> </DIV>
<DIV><B>Sent:</B> Sunday, January 13, 2008 8:42 PM</DIV>
<DIV><B>To:</B> <A title=opensim-dev@lists.berlios.de
href="mailto:opensim-dev@lists.berlios.de">opensim-dev@lists.berlios.de</A>
</DIV>
<DIV><B>Subject:</B> Re: [Opensim-dev] further db thoughts</DIV></DIV></DIV>
<DIV><FONT face=Arial></FONT><FONT face=Arial></FONT><FONT
face=Arial></FONT><BR></DIV>Ok, I just committed
/OpenSim/ThirdParty/Tribal/TribalMedia.Framework.Data<BR> <BR>This should
be specialized into OpenSim.Framework.Data, which should do the following:<BR>*
Specialize the FieldMapper <FONT size=2>ExpandField, <FONT size=2>GetValue
and <FONT size=2>ConvertToDbType to accomodate LLVector3, LLQuaternion and
LLUUID</FONT></FONT></FONT><BR><FONT size=2><FONT size=2><FONT size=2>* Provide
a set of TableMappers for all supported object types (I will try to commit
primitivebaseshape, part and group soonish, but I'm a bit pressed for time at
the mo)</FONT></FONT></FONT><BR><FONT size=2><FONT size=2><FONT size=2>*
DatabaseProviders for all supported database engines, ie
OpenSim.Framework.Data.MySQL should subclass and extend the
DatabaseMapper</FONT></FONT></FONT><BR> <BR><FONT size=2><FONT size=2><FONT
size=2>Alas, the code as it is committed five minutes ago, is kinda forcefully
ripped out of its context, but I guess it's a work in
progress.<BR></FONT></FONT> <BR>(For example, the DatabaseMapper is
both connectionpool and querybuilder, which might not be
ideal.)<BR> <BR>Ideally, basing our db layer on something like this should
mean we never again should get out of synch on this or that
database.<BR> <BR>Eagerly awaiting peer review and
comments,<BR>/Stefan<BR></FONT><BR> <BR>
<HR id=stopSpelling>
<BR>> Date: Sat, 12 Jan 2008 09:39:20 -0500<BR>> From:
sean@dague.net<BR>> To: opensim-dev@lists.berlios.de<BR>> Subject: Re:
[Opensim-dev] further db thoughts<BR>> <BR>> On Fri, Jan 11, 2008 at
09:46:21PM +0100, Stefan Andersson wrote:<BR>> > Sean,<BR>> >
<BR>> > I know you're going to hate me for this, but before I post code, I
just wanted to explain whats here 'on my own hard-disk' to see if it's anything
like what you want to do:<BR>> > <BR>> > * I have a DbConnectionPool
that acts as a programmatic manager of connections (Subclassed into
MySqlDbConnectionPool)<BR>> > * this is passed to a TableMapper which
exposes it as a protected method WithConnection(delegate) for subclasses to
access; they never access the connectionpool directly; the delegate approach
lets the TableMapper lock, allocate, pre- and postprocess the connection
securely and encapsulated. (kind of like a using clause)<BR>> > * The
TableMapper is subclassed into a TableMapper<TRowMapper> that implements a
CRUD interface by creating dynamic sql queries (the param prefix is pulled from
the ConnectionPool) and populating them from a 'Schema'<BR>> > * A
'Schema' is a collection of FieldMapper<T><BR>> > *
FieldMapper<TField> is initialized with a field/param name (same for
laziness sake), TField is the RowMapper field value type, a get delegate and a
set delegate for the TField type object. It also does all the db/field type
casting as well as expands things like Vector and Quaternion into several db
fields.<BR>> > * The delegate approach keeps everything field related
together, as opposed to a FromReader/ToReader method approach, which helps dodge
inconsistencies.* The TRowMapper is mostly of type RowMapper<TRowObject>
which just creates a class that has a member of TRowObject; this lets you
subclass TRowMapper<TRowObject> and add db-specific extra-fields to it in
order to manage hierarchies.<BR>> > * Upon operations, you create your
rowmapper object (or just a plain object if there is no aux data) and either do
FillObject( Schema, rowObject) or extract stuff by overrifing the
FromReader(rowObject, DbReader) - the latter I use to populate a group from a
part table (the select on the key field returns multiple rows, so i just
PartMapper.FromReader() on each one to build the group.<BR>> > <BR>>
> - it does NOT auto-create tables, as I'm not interested in that approach as
you know, but you already have the code for it and the data in the 'Schema' so
it should be a piece of pie.<BR>> > <BR>> > All in all, everything
is explicit and compile-time; no cacheing, synchronization or double-buffering,
no reflected and emitted code, but it works, and is quite efficient. It takes a
while to get into the flow of how the various components work together, but
after that I feel it's very conveniens and trustworthy.<BR>> > <BR>>
> Of course, it needs more work to get it going on all different database
interfaces, but it's created from the start to be subclassed into differing
databases.<BR>> > <BR>> > If this sounds like something we'd want,
I'd be happy to make it<BR>> > available as a third-party BSD Licence lib
within the project, my only<BR>> > demand is that it is called
TribalMedia.Framework.Data and that the<BR>> > BSD header remains
intact.<BR>> <BR>> I think it is definitely a promissing approach. If you
wanted to check<BR>> it in under TribalMedia/Framework/Data I'll definitely
check it out. If<BR>> it turns out to not work out, we can just remove it
down the road.<BR>> <BR>> -Sean<BR>> <BR>> -- <BR>>
__________________________________________________________________<BR>>
<BR>> Sean Dague Mid-Hudson Valley<BR>> sean at dague dot net Linux Users
Group<BR>> http://dague.net http://mhvlug.org<BR>> <BR>> There is no
silver bullet. Plus, werewolves make better neighbors<BR>> than zombies, and
they tend to keep the vampire population down.<BR>>
__________________________________________________________________<BR><BR>
<P>
<HR>
<P></P>_______________________________________________<BR>Opensim-dev mailing
list<BR>Opensim-dev@lists.berlios.de<BR>https://lists.berlios.de/mailman/listinfo/opensim-dev<BR></BODY></HTML>