|
Dharkael |
Posted: Thu Apr 03, 2008 10:09 am
Python Sqlite COM Component for ZMUD/CMUD |
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Sat Apr 19, 2008 7:02 pm |
It's just the demo, nothing changed. So, in theory, it should work. I tried it on zMUD, works. I tried it on CMUD, doesn't work.
Charneus |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sat Apr 19, 2008 7:06 pm |
I don't know what to tell you. I've suffered through a rather large learning curve, but the demo works for me as well as recoded scripts that now use the SQLite database (Though, not all!).
|
|
_________________ Sic itur ad astra. |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Sat Apr 19, 2008 8:07 pm |
My advice: balls to the zScript->Python->SQL route, get an sql plugin for Lua and use that instead ;)
|
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sat Apr 19, 2008 8:45 pm |
Yeah cuz everything always works so smoothly in CMUD it must be bugs in my code. >|:p
I'd start with some basic troubleshooting.
Is the component being created in properly in CMUD?
Try testing the properties for values.
#echo @comsql.IsOpen or #echo @comsql.AutCommit
Should return the string True or False and not an empty string.
Once its confirmed that the component is being created.
Try to isolate at what point the script is failing.
The LastError property is great for finding out when and where something is going wrong.
Lastly this script is pretty small only a few key lines of code
here's a stripped down version
Code: |
#var stuff %comcreate("Sqlite.ZMUD.WSC")
#call @stuff.Open(":memory:")
#call @stuff.Execute("create table herblist (herb,method,effect,cures)")
#call @stuff.Execute("insert into herblist values(?,?,?,?)","Siriena","Eat","Cure for the Black Death. ","Black death")
#for @stuff.Execute("SELECT * FROM herblist WHERE method=? AND effect REGEXP ?","Eat","(C|c)ure") {#echo ******;#showdb {%i}}
|
With a few well placed echos you should be able to see at what point things are going wrong.
Code: |
#var stuff %comcreate("Sqlite.ZMUD.WSC")
#echo Is the Component created?: @stuff.AutoCommit
#call @stuff.Open(":memory:")
#echo Is the database open ?: @stuff.IsOpen
#call @stuff.Execute("create table herblist (herb,method,effect,cures)")
#echo Error after create table : @stuff.LastError
#call @stuff.Execute("insert into herblist values(?,?,?,?)","Siriena","Eat","Cure for the Black Death. ","Black death")
#echo Error after insert ?: @stuff.LastError
#for @stuff.Execute("SELECT * FROM herblist WHERE method=? AND effect REGEXP ?","Eat","(C|c)ure") {#echo ******;#showdb {%i}}
#Echo Error after SELECT : @stuff.LastError |
Goodluck |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sat Apr 19, 2008 9:55 pm |
Anaristos wrote: |
Mystery solved. Corrupted file path |
I'm glad to see you got to the root the problem.
Anaristos wrote: |
I've suffered through a rather large learning curve... |
Yeah and I for one appreciate it.
I tried to make the component easy to use and to debug if something goes wrong, and although I'm pretty confident I haven't made any large mistakes, I'm open to suggestions to improving its implementation.
That said, I think that as more people use it and the body of knowledge regarding it's usage grows it'll show itself to be a pretty useful and facile tool.
When Zugg gets around to incorporating his new DB module the experienced gained will be relevant and for the zMUD users well this means they wont get left behind with access to a zMUD friendly true database component. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sat Apr 19, 2008 11:08 pm |
How about making exec an alias for Execute? It is the most used function and it is quite cumbersome to type out.
Also, creating a file that doesn't exist should be optional. It would remove the problem that I had. A ForcedOpen() function might do the trick.
The Open() function would return false if the file didn't exit while the ForcedOpen() function would create said file if it didn't exist.
The fact that the zMUD/cMUD implementation is interpreted, makes it wide open for all kinds of additions and/or improvements.
For me, it is quite fun to use, though sometimes I've spent hours looking at my meager code trying to figure out why it doesn't work. I think that's all part of the experience. |
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 12:09 am |
Heh, come on thats pretty lazy :p , I'll add an Exec alias to save the wear on your fingers.
As for the ForcedOpen suggestion, I'm instead of adding a PathExists method instead,
one that returns a Boolean value indicating the existence of the file.
EDIT: PathExists and Exec added.
After updating and saving contents of the Sqlite.ZMUD.WSC file it is necessary to Unregister then Register the file in order for the changes to the interface to be available to COM.
Any components already created will not have reflect the changes and sometimes it maybe necessary to Close and Reopen ZMUD/CMUD if it does not automatically acquire the new interface. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 12:36 am |
On the other hand, I am about to give up for a while. The "no such table xxxxx" messages are back and I just can't figure out why they are happening. I moved the table to it's own file and it won't find it. The really bizarre thing is that it writes to the file just fine, it just can't read it.
|
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 1:05 am |
Post your script verbatim including the SQL required to make it.
Sqlite Expert gives the SQL required to make each table under the DDL tab.
Really it should either work or not!
Let me see the code.
Tell me what you want it to do and at which point it fails.
If you don't want to post all that to forum PM if you like. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 1:35 am |
OK, here is the function body.
Code: |
#VAR comsql %comcreate( "Sqlite.zMUD.WSC")
;;
#CALL @comsql.Open("C:\Anaristos\SQLite Expert\Databases\Core.db3")
;;
$name = %concat( "'%", %trim( %-1), "%'")
;;
#IF (@comsql.IsOpen()) {
$rec = @comsql.Execute("Select * from moblist WHERE name LIKE ?", $name)
#CALL @@comsql.Close()
#RETURN $rec
}
{#ECHO ERROR: @comsql.LastError() : file open is @comsql.AbsolutePath()}
|
This fails to find any matches, However if the function is called with a full name and the code is changed to this
Code: |
....
$rec = @comsql.Execute("Select * from moblist WHERE name = ?", %trim(%-1))
....
|
where %-1 now holds the mob name without any while cards, then it returns the appropriate match. |
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:00 am |
Okay this one is easy you're enclosing the name your looking for in extra single quotes '
The qmark substitution automatically quotes everything for you.
Code: |
$name = %concat( "'%", %trim( %-1), "%'") |
would give you something like SELECT * FROM moblist WHERE name LIKE "%'somename'%"
Code: |
$name = %concat( "%", %trim( %-1), "%") |
Is what you should be using.
One of the main reasons for using qmark ? substitution oy is that you just pass in the data exactlyis that there is no need to quote or escape special characaters, this is done for you.
Where are you having problems with "no such table xxxxx" messages?
Because really I'd like to get to the bottom of that. Once you create the table and the transaction is commited (Which happens after every Execute when AutoCommit is True which it is by default)
Then the table stays in the database until its dropped. Do you have any DROP TABLE xxxx statements in your code.
Show me.
EDIT: my original example of the correct method was faulty |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Last edited by Dharkael on Sun Apr 20, 2008 2:33 am; edited 1 time in total |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 2:05 am |
No, no DROPs at all. The problem is, I believe, that CMUD makes the COM variable stale for some reason. So by re-acquiring the object before each use the problem seems to go away. I will try this now without the quotes and let you know what happens. I put them in because it seemed to have worked with them once. There is the problem of the embedded quotes that I was trying to solve. (e.g. Jenny's)
|
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:16 am |
Embedded quotes are fine to match Jenny's
You could do
$name = "%nny's" As long as you're using the qmark sub it will match.
If you're putting the string in directly into the SELECT statement
you would have to do
Code: |
SELECT * FROM moblist WHERE name = '%nny''s' |
That is you would have to both put quotes around the string you're trying to match and also double any single quotes contained therein.
Are you also using SQLite Expert at the same time? It's possible there maybe some conflict if both attempt to get a write lock and maybe causing the problem. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 2:22 am |
Yes, that is right. I was just trying to use the same SELECT that I've been using with my %mapquery. There I double the single quotes before passing it to the function. Now the problem am I having is that the WHERE LIKE only works when I pass it the exact string. That is, it will match ST:TNG but return nothing for ST.
|
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:26 am |
So is the string your passing in is? something like
Code: |
$name = %concat( "%",%trim( %-1),"%")
$rec = @comsql.Execute("Select * from moblist WHERE name LIKE ?", $name) |
Where %-1 contains the string "ST"? |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 2:29 am |
No, I followed your suggestion. I am passing the raw parameter.
Code: |
$rec = @comsql.Execute("Select * from Areas WHERE area LIKE ?", $name)
|
It works when I pass it "ST:TNG", but if fails when I pass it "ST", or any truncated name for an area.
@comsql.LastError() is empty.
$name = %-1. |
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:36 am |
Okay there was some confusion due I'm sure to my original example of the "correct" way being faulty that is it was the same way you had been doing it.
Code: |
$name = %concat( "'%", %trim( %-1), "%'") |
Was INCORRECT
Code: |
$name = %concat( "%", %trim( %-1), "%") |
IS CORRECT notice we are no longer concat'ing in the single quotes.
Sorry 'bout that
But in order to use the pattern matching facility of the LIKE function/keyword you still need to use the % where appropiate. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 2:38 am |
Silly me! I forgot about the %. I am tired.
EDIT: It is now working like a champ!
So the only problem left is the stale COM object. I was hoping to create the object once a session and also to open the database just once, but I don't thing that will work. |
|
_________________ Sic itur ad astra. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:47 am |
Honestly I'm not sure why the COM object should still remain valid, I've used the same one for days.
Try reusing the COM object, but Don't Edit the file with SQLite Expert or anything else during that time and see if that clears it up. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
xekon Apprentice
Joined: 11 Oct 2007 Posts: 154
|
Posted: Sun Apr 20, 2008 5:51 am |
Success on first try using the com component you listed and I threw the example code into an alias. I am using Cmud 2.18
Now I am going to try this using a file and see if I can make some really neat stuff happen for an equipment database. |
|
|
|
Progonoi Magician
Joined: 28 Jan 2007 Posts: 430
|
Posted: Sun Apr 20, 2008 11:30 am |
Hrm, I'm not so lucky apparently.
Started to muck about with it and installed latest ActivePython, installed it, made the .WSC file, registered it and successfully.
Then I entered the test code provided into ZMud's cmd line and it gave me a pop-up error window saying
Code: |
Error parsing command
OLE error 800C00005
|
EDIT: This error msg is followed by the whole test code inside the same pop-up box.
I have never ever messed around with COM and such so I have no idea what to do or try next :)
Glad of any help I can get.
Prog |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 2:33 pm |
Hmm did you rename or move or delete the .WSC file after registering it?
I was able to reproduce your error doing just that.
COM needs to be able to find the file so if you have moved it, unregister then register the file.
If you haven't moved it, do it anyways.
Then test it by putting in just the first line of the test script, the one with the comcreate call.
If no errors pop up then we know COM can find the component.
Then try the script in its entirety and get back to me with the results. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Progonoi Magician
Joined: 28 Jan 2007 Posts: 430
|
Posted: Sun Apr 20, 2008 2:46 pm |
Yeah, I moved it initially.
Did the unregister/register thing now in the place where I put it but no go with first line of the script.
Exactly same error again.
And gives the code line inside the error box. Just like the first time.
Thanks for the help, btw.
Prog |
|
_________________ The Proud new owner of CMud.
--------------------------------
Intel Core i5-650 3,2GHz
4 DD3 RAM
GTX 460 768MB
Win 7 Home Premium 64x
-------------------------------- |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Sun Apr 20, 2008 3:10 pm |
No Probs..
Have you tried shutting down and restarting ZMUD I played around with moving the file and then re-registering it and I also got the OLE error
until I restarted. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Sun Apr 20, 2008 5:26 pm |
I've gotten than error in CMUD also. It comes from the Python side when it fails to validate the COM connection for some reason (the error code tells us, I am sure, but I haven't looked it up) and one tries to use it anyway (because one doesn't know). Best solution, restart CMUD/ZMUD to clear the connection (with Python) error.
EDIT: I just attempted to find out exactly what error code 0x800C00005 means. This is the way I interpret it:
0x800XXXXXX is an OLE error prefix.
0x800C0XXXX indicates that the exception is thrown by Python.
0x800C00005 is the specific code related to the validity of the COM connection.
This is an educated guess based on what I researched, the documentation is scanty. My wild guess is (from my experience) is that one has invoked Python via a call (Open(), IsOpen(), etc) after a call to %comcreate that fails because OLE didn't complete the far connection. This type of error is beyond ZMUD/CMUD to handle. Perhaps someday, the function will place an error code in the variable when a far-side exception is thrown. |
|
_________________ Sic itur ad astra. |
|
|
|
|
|