logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Thoughts on multiple connections

 
Post new topic   Reply to topic    nwnx.org Forum Index -> Development
View previous topic :: View next topic  
Author Message
Grumalg



Joined: 04 Nov 2005
Posts: 70

PostPosted: Mon Dec 11, 2006 10:56    Post subject: Thoughts on multiple connections Reply with quote

Having comtemplated the multiple connection issue a bit more, I find some things I don't like about your proposed approach and I have some ideas for another approach. Now I may not be seeing your whole intended picture yet, so it's surely possible I'll wind up off base here...

< Danger Will Robinson... annoying lecture mode = ON Smile >

Papillon wrote:
The idea is that you could have a couple of plugins, say xp_mysql1.dll, xp_mysql2.dll, and xp_sqlite.dll and of course their ini files: xp_mysql1.ini, xp_mysql2.ini, and xp_sqlite.ini (the INI filenames are tied to the DLL filename, so you can just copy and rename them). Now you specify the class parameter in each ini file to be unique, say SQL, SQL2, and SQLITE.


There are two things I don't like here. First, this approach requires having multiple copies of a SQL plugin in memory to get multiple connections to the same DB engine. Not that the memory required is huge, it's just a principle thing. Second, requireing a lot of 'make work' renaming and editing ini's seems to go against the grain of making things simple for the end user in nwnx. My approach wouldn't require any of this, except for special case of talking to multiple DB engines.

Papillon wrote:
Within nwscript, you would reference those new classes, instead of just calling SQL. So, for example the SQLExecDirect function would exist in three variations:

1) SetLocalString(GetModule(), "NWNX!SQL!EXEC", sSQL);
2) SetLocalString(GetModule(), "NWNX!SQL2!EXEC", sSQL);
3) SetLocalString(GetModule(), "NWNX!SQLITE!EXEC", sSQL);

Each statement would go to the corresponding plugin and thus to it's own database connection. Since these are separate plugins, all resultsets are separate as well.

As I do not have the luxury of pointers in nwscript, the function class serves as a surrogate for them. sql_include could be modified in the future to support the function class with a new function parameter, for example. I have not decided on this yet.


This seems to imply useing something like a SQLExecDirectSQL, SQLExecDirectSQL2, and a SQLExecDirectSQLLite. That could be error prone for many users. If I'm understanding your adding a parameter comment correctly, useing something like SQLExecDirect("SQLITE", <command>) could break a lot of existing code.

Now where your approach does make sense to me is useing multiple database engines. Anyone needing/wanting that is already skilled enough to deal with a bunch of ini renaming/customizing and keeping sql_include issues straight. My approach makes the single DB engine case easier for the majority of end users, and can co-exist with your approach for multiple DB engines.

When I first sketched out my approach I suggested adding a parameter [SQLExecDirect(<connection>,<command>), SQLFetch(<connection>), and SQLGetData(<Connection>, <fieldindex>)]. Upon further thought, I'd move the <connection> parameter to the end of the param list so it can be defaulted to the first connection (same way as 'pwdata' is defaulted now) without impacting the existing code base out there. It doesn't scan at a glance as nicely this way, but it's more compatable.

Papillon wrote:
Why do you think you can override the function class of the SQL plugins in their ini file ?


Papillon wrote:
I have the additional responsibility to keep things similar with other database plugins, so the implementation may not become too MySQL specific. That is why I need to think (and experiment) more about this.


It seems to me that supporting a 'superset' of DB functionality at the SQL class level is preferable to limiting it to the lowest common denominator of DB plugins. That way a DB plugin can use whatever 'subset' it can support without restricting more capable DB engine plugins. For example, a plugin that doesn't or can't support multiple connections would just ignore the <connection> parameter and use it's default single connection and note it's limits in it's own documentation.

<edit added> I know I'm on shakier ground in the above paragraph, as I don't yet fully follow all your class code.

Ok, now given the existance of a <connection> parameter how might this be handled internally in the plugin? Well, suppose you had a 'connection' STRUCT. This struct would contain the connection object, or a pointer to it. It should also contain the 'server', 'user', 'password' stuff for this particular connection. A 'IsConnected' entry could facilitate auto init on first use of the connection. It should also contain either the 'data' results set or a pointer to it. It's also a good place to keep misc pointers like 'firstrow', 'currentrow', and maybe 'lastrow' pointers particular to the individual connection. Say this struct is named 'connection'.

Multiple connections would use an array of this struct, say named 'connections' with as many copies of a 'connection' struct as you want to support multiple connections. With all the above in place, SQLExecDirect, SQLFetch, and SQLGetData would only need a layer of indirection applied as a prefix to the existing code references of struct contents. i.e. a 'connections[connectionparam].' prepended to all references. This approach looks pretty simple to me as it's not so much a rewrite as a cut and paste edit of references.

If I haven't missed any show stoppers in all that, it looks like a more end user friendly way to have multiple connections within a single DB engine. It still allows use of your approach for the special case of multiple DB engines.

So have I missed any show stoppers in this?

--- Grumalg ---
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Mon Dec 11, 2006 17:45    Post subject: Reply with quote

A short note beforehand: The current approach was not meant to be the most elegant way to support multiple DB connections. It just came almost for free and that's why I took it. I wanted to have an answer for this problem, which came up 2 or 3 times with NWNX2.

I did not think everything through, but your idea sounds reasonable. There are some open detail questions (like e.g. how the mapping between account data and connection string would work), but all-in-all, this would be the way to do it.

I wonder if it's worth it, though. There is probably only a very small percentage who would want multiple DB connections. It is not something the average user will need - if the queries get that complex, that you can not solve your problem with one DB connection (never happened to me, personally), your above "average" and could very well setup the current solution.

So, bottom line: I think the idea is good, and might implement it sometime. Right now, there are a lot of tasks that are a bit higher on my priority list, so please do not expect an implementation in the neat future. Of course, NWNX is open source, so...
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Grumalg



Joined: 04 Nov 2005
Posts: 70

PostPosted: Tue Dec 12, 2006 1:39    Post subject: Reply with quote

Well, to date I've never needed multiple connections myself. Nor did I expect them to be high on your priority list. I'm not pushing for you implement them soon, just discussing ways it could be done.

In my experience with various groups of programmers, bounceing around ideas in more than one head almost always leads to a better solution. My suggested approach wasn't intended to be a total solution. It was intended to show a framework I thought could work and that might stimulate you to an better final implementation.

I agree that the desire for multiple connections hasn't been a *massively* frequent request, but if they are simple enough to use that could change. They certainly *are* a powerful tool to have.

Beyond the ability to work with two recordsets while looping I have often seen asked for on this forum. I can think of a additional use where multiple connections could help a lot. I have seen discussion in the forum about handling large recordsets and avoiding TMI. Typically useing delay command recursion and things like LIMIT in SQL. Multiple connections could simplify this a lot as you could rely that the data initally requested was still around in a seperate connection AND still positioned on the current record each time you recurse a delay command routine. It would also avoid concerns in such use that some other event got between the delay commands and overwrote the recordset.

If I wanted to dust off my old C skills and get up to speed in C++, I *might* be able to do such things. But I'm *really* not interested in getting into a position with nwnx like the fast french stuff was. I'm content to wait for an official release from you, just like I'm waiting for a proc solution. Smile

While waiting I have a lot of time to think about my wild haired ideas and toss them at you.

--- Grumalg ---
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Tue Dec 12, 2006 13:47    Post subject: Reply with quote

Well, what FastFrench did was not very productive, since he basically took everything, modified some things here or there, and sticked his own label on NWNX. That did not help NWNX as much as it would have if he had contributed some code back.

So if you create something of general interest for NWNX, it could be integrated, rather than creating a fork that just doubles everybody's work. The source is available, and if the contributions come back in a form that allows them to be put easily into NWNX, I will be hapy to do so.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
The Bus Driver



Joined: 26 Mar 2005
Posts: 3

PostPosted: Wed Dec 13, 2006 16:48    Post subject: Reply with quote

I have run into situations where multiple connections would have been helpful, but I got around it by storing previous data as local variables. It would be much cleaner to have multiple connections, but certainly not mandatory. Most problems like this could probably be solved by using a more complicated SQL statement. Because your software is open source, I see no reason why another developer couldn't provide a plugin for it or some type of modification to support multiple connections.

PHP allows multiple connections by specifying an optional boolean in the connect function. Any request to close a connection must then specify the link identifier to close out that connection. I'm not sure when NWNX4 connects to the database, but I assume it connects when the program starts rather then each time a SQLExecDirect() statement is made (unlike PHP which can make new connections at will). I only state the way PHP handles multiple connections to possibly give some ideas into how it could be handled in NWNX4.
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Wed Dec 13, 2006 23:46    Post subject: Reply with quote

The mother of all non-elegant solutions in NWNX is indeed a simple one: No pointers. NWNX does what it does by simply passing one string from NWScript to the rest of the world. There is no such concept as pointers or references (at this point of time).

All other solutions have the luxury of "designing" a solution to a known problem. NWNX can just work around the known quirks Smile.

Before I start rambling further, let me just say that in theory, everything is possible with NWNX. If someone feels like it, a plugin which accesses 10 Oracle servers, with 25 databases, with 512 tables, a whole-lot-of stored procedures, and even more queries returning a absolutely amazing number of resultsets is - easy.

If someone sits down and codes it.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
kungfoowiz



Joined: 12 Oct 2006
Posts: 61

PostPosted: Thu Dec 14, 2006 14:07    Post subject: Reply with quote

Heh, it does sound a bit much to do it for a game plugin.

Though, I wouldn't mind doing a small-ish (say 4 or so) array of connections for the MySQL plugin, if there's a need for it?

You'd then specify in SQLExecDirect( STRING sQuery, INT nConnectionID = 1 );

Something like that.

---
kung
Back to top
View user's profile Send private message
Grinning Fool



Joined: 12 Feb 2005
Posts: 264

PostPosted: Thu Dec 14, 2006 17:47    Post subject: Reply with quote

Similarly, an unlimited number could be supported by using a hashmap -- where the user supplies a name for each connection, and this is used as a key to retrieve the actual connection data.
_________________
Khalidine, a NWN2 persistent world

Looking for volunteers.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Development All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group