 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
nick
Joined: 24 Aug 2005 Posts: 345 Location: Berlin / Germany
|
Posted: Wed Sep 20, 2006 8:54 am Post subject: #INCLUDE SQLite.ahk - Functions to access SQLite3 DB's |
|
|
Hello,
I found an interesting script SQlite.au3 at http://www.autoitscript.com/forum/index.php?showtopic=17099 and thought it could be interesting for the AHK community too. So I tried a "translation" and now in my opinion the important functions are realized and raw tested. I'll try to use for some productive tool, but I'd want some others to test it too and give response for missing functions and/or optimizations.
To try out you need the SQLite3.exe and SQLite3.dll (3.3.7) from http://www.sqlite.org/download.html. Both are free and don't need any installation. Once there, you should have a look on http://www.sqlite.org/lang.html and
http://www.sqlite.org/sqlite.html. This Documentation is rather brief, but I found no other.
Now, what's the script for:
The script's functions give full access on SQLite3 databases. You even can create databases - if you really need - using the _SQLite_SQLiteExe function.
Queries (SELECT statements) are supported as follows:
_SQLite_GetTable returns the full result of a query including column names in a string with column values/names separated by "|" and rows seperated by "`n".
_SQLite_Query prepares a query and creates a query handle. To get column names, you have to call _SQLite_Fetchnames, to get the values of first/next row, you have to call _SQLite_FetchData. The results are passed out in a string with "|" separated values.
All non query SQL-statements (INSERT, UPDATE, DELETE...) are executed via _SQLite_Exec.
To make testing a little bit easier I added the script SQLite_sample.ahk. It creates a small database, tries some functions on it and displays the result of a SELECT * FROM ... in a ListView.
Changelog:
2006-09-23New global $SQLITE_s_ERROR for functions error messages instead of "ByRef $sErr" parameter in function calls. New optional parameter $iMaxResult in _SQLite_GetTable to restrict the amount of returned rows. SQLite_sample.ahk adapted.
2006-11-15
Adjusted code in _SQLite_GetTable to run under AHK 1.0.45.
Maybe some more changes will be needed!
SQLite.ahk - 2006-11-15
Please download the script from http://www.autohotkey.net/~dwuttke/SQLite/SQLite.ahk
Here's some sample code to show how to use the functions:
| Code: | ;===============================================================================
; Script Function: Sample script for SQLite.ahk
; AHK Version: 1.0.44.13
; Language: English
; Platform: WinXP
; Author: nick
; Version: 0.00.01/2006-09-23/nick
;===============================================================================
; Autoexec Section
;===============================================================================
; AHK Settings
;===============================================================================
#NoEnv
#SingleInstance force
#Persistent
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
SetWinDelay -1
;===============================================================================
; Includes
;===============================================================================
#Include %A_ScriptDir%
#Include SQLite.ahk
;===============================================================================
; Variables
;===============================================================================
$iRC := 0
$sErr := ""
;===============================================================================
; Use SQLITE3.EXE - Create a Database and Table
;===============================================================================
$sDBFileName := "TEST.DB"
$sCSVFileName := "TEST.CSV"
$sDBFileName := "TEST.DB"
$sCSVFileName := "TEST.CSV"
$sInput =
(Ltrim
CREATE TABLE Test (Name, Fname, Phone, Room);
.separator \t
.import '%$sCSVFileName%' Test
)
$sOutput := ""
IfExist %$sDBFileName%
{
FileDelete %$sDBFileName%
}
IfExist %$sCSVFileName%
{
FileDelete %$sCSVFileName%
}
Loop 99
{
FileAppend,
(LTrim Join
Name%A_Index%%A_Tab%Fname%A_Index%%A_Tab%
Phone%A_Index%%A_Tab%Room%A_Index%`n
),%$sCSVFileName%
}
$iRC := _SQLite_SQLiteExe($sDBFileName, $sInput, $sOutput)
If ($iRC <> 0)
{
MsgBox Fehler bei SQLITEEXE: %$iRC%`n%$SQLITE_s_ERROR%`n%$sOutput%
ExitApp
}
;===============================================================================
; Use SQLITE3.DLL - Query the Database
;===============================================================================
$iCols := 0
$iRows := 0
$sRC := ""
$sResult := ""
$iRC := _SQLite_Startup()
If ($iRC <> 0)
{
MsgBox Fehler bei STARTUP: %$iRC%
}
$sRC := _SQLite_LibVersion()
If ($SQLITE_s_VERSION <> $sRC)
{
MsgBox,
(LTrim
SQLite Scriptversion = %$SQLITE_s_VERSION%
SQLite DLL version = %$sRC%
)
}
$iRC := _SQLite_OpenDB($sDBFileName)
If ($iRC <> 0)
{
MsgBox Fehler bei OPENDB: %$iRC%
}
$sSQL := "INSERT INTO Test VALUES('Name111', 'Fname111', 'Phone111', 'Room111');"
$iRC := _SQLite_Exec($SQLITE_h_DB, $sSQL)
If ($iRC <> 0)
{
MsgBox Fehler bei EXEC: %$iRC%`n%$SQLITE_s_ERROR%
}
$iRC := _SQLite_LastInsertRowID(-1, $iRows)
If ($iRC <> 0)
{
MsgBox Fehler bei EXEC: %$iRC%`n%$SQLITE_s_ERROR%
}
Msgbox Last inserted Row = %$iRows%
$sSQL := "SELECT * FROM Test;"
$i := A_TickCount
$iRC := _SQLite_GetTable($SQLITE_h_DB, $sSQL, $sResult, $iRows, $iCols)
If ($iRC <> 0)
{
MsgBox Fehler bei GETTABLE: %$iRC%
}
MsgBox % A_TickCount - $i
Msgbox Zeilen : %$iRows%, Spalten : %$iCols%
/*
$iRC := _SQLite_Query($SQLITE_h_DB, $sSQL)
If ($iRC <> 0)
{
MsgBox Fehler bei QUERY: %$iRC%
}
$iRC := _SQLite_FetchNames(-1, $sResult)
If ($iRC <> 0)
{
MsgBox Fehler bei FETCHNAMES: %$iRC%
}
$sResult = %$sResult%`n
MsgBox %$sResult%
$iRC := _SQLite_FetchData(-1, $sResult)
If ($iRC <> 0)
{
MsgBox Fehler bei FETCHNAMES: %$iRC%
}
MsgBox %$sResult%
$iRC := _SQLite_QueryFinalize(-1)
If ($iRC <> 0)
{
MsgBox Fehler bei FINALIZE: %$iRC%
}
*/
; Show the Result in Listview
Gosub SHOW_LISTVIEW
; Wait for GUiClose
WinWait, SQLite Result - Close with ESC, , 20
IfWinExist, SQLite Result - Close with ESC
{
WinWaitClose, SQLite Result - Close with ESC
}
Sleep 100
; Now GUI is closed
$iRC := _SQLite_CloseDB(-1)
If ($iRC <> 0)
{
MsgBox Fehler bei CLOSEDB: %$iRC%
}
$iRC := _SQLite_ShutDown()
If ($iRC <> 0)
{
MsgBox Fehler bei SHUTDOWN: %$iRC%
}
ExitApp
;===============================================================================
; Gui Subs
;===============================================================================
SHOW_LISTVIEW:
$LV =
$LVCOUNT := $iRows + 1
Loop, Parse, $sResult, `n
{
If (A_Index = 1)
{
Gui, Add, ListView, r20 w420 Grid Count%$LVCOUNT%, %A_LoopField%
}
Else
{
StringSplit, $LV, A_LoopField, |
LV_ADD("", $LV1, $LV2, $LV3, $LV4)
}
}
LV_ModifyCol(1, 100)
LV_ModifyCol(2, 100)
LV_ModifyCol(3, 100)
LV_ModifyCol(4, 100)
Gui, Show, Autosize Center, SQLite Result - Close with ESC
Return
;===============================================================================
GuiClose:
GuiEscape:
Gui, Destroy
Return
|
Have a nice time and tell me your opinions![list=][/list] _________________ nick
denick @ http://de.autohotkey.com/forum/
Last edited by nick on Wed Nov 15, 2006 6:17 am; edited 2 times in total |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed Sep 20, 2006 9:34 am Post subject: |
|
|
Oh, I suppose it is a follow-up of http://www.autohotkey.com/forum/viewtopic.php?t=8324
Thank you for sharing, I am sure lot of people will find this interesting.
The alternative is Cheetah -- lighter, but less common, no SQL.
Or the big MySQL...
Or using ODBC for abstracting the database. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
nick
Joined: 24 Aug 2005 Posts: 345 Location: Berlin / Germany
|
Posted: Wed Sep 20, 2006 10:40 am Post subject: |
|
|
Yes, you're right. There was not much response, but I wanted to have it, so I went on.
| PhiLho wrote: | The alternative is Cheetah -- lighter, but less common, no SQL.
Or the big MySQL...
Or using ODBC for abstracting the database. |
I don't know Cheetah, but in my opinion AHK and SQlite seem to be perfect for each other. To deploy tools, no installation is needed, you have only to copy the script.exe and the SQLite3.dll (and SQLite3.exe, when used) into the same folder (or SQLite... into the system path) for direct, simple and fast database access with SQL support. I like it. _________________ nick
denick @ http://de.autohotkey.com/forum/ |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10474
|
Posted: Thu Sep 21, 2006 11:05 am Post subject: |
|
|
| I like your introductory remarks and the nicely structured script. Thanks for creating and sharing this resource. |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Sep 22, 2006 8:05 am Post subject: error message in sample script |
|
|
Thanks for your work.
The sample script returns an error message
| Quote: | Error at line 159.
Line Text: SHOW_LISTVIEW
Error: Duplicate label.
|
Dirk |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Fri Sep 22, 2006 8:28 am Post subject: |
|
|
Dirk, remember to use a nickname, even if not logged in, thanks.
You should do a search in the code you try to run. Searching SHOW_LISTVIEW in the topic shows it only thrice: a Gosub, the label definition, and in your message.
Perhaps you accidentally pasted the code twice? _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
finet
Joined: 22 Sep 2006 Posts: 4 Location: Belgium
|
Posted: Fri Sep 22, 2006 2:13 pm Post subject: error message sample script |
|
|
I copied the script one again. Error message remains.
Dirk |
|
| Back to top |
|
 |
Dolby Guest
|
Posted: Fri Sep 22, 2006 3:09 pm Post subject: |
|
|
| I had no problems with the script. It works fine. The issue must be on your end. |
|
| Back to top |
|
 |
finet
Joined: 22 Sep 2006 Posts: 4 Location: Belgium
|
Posted: Mon Sep 25, 2006 8:31 am Post subject: |
|
|
It was indeed on my end.
Sorry!
Dirk |
|
| Back to top |
|
 |
valenfor
Joined: 26 Feb 2005 Posts: 20
|
Posted: Tue Nov 14, 2006 8:56 am Post subject: |
|
|
OK, as I noted in the thread I had started thanks again for this module. In my excitement I have been up way past the time I should be sleeping however trying to figure out an error I am having.
I am sorry for what may be a double post, however I wanted to make sure I got this in the right spot since you started a new thread. I also realize the above person's note that 'it worked for them so it must be on my machine'. I wouldn't disagree, however I could use some pointers if someone has any as to what might be the cause.
On my first run, I had experience a strange error where the program was overwriting itself replacing items with 'name name' as I mention in the original thread here http://www.autohotkey.com/forum/viewtopic.php?t=8324
However I started fresh and now I am getting another error that feels similar stating: Error in #include file "C:\dev\sqliteahk\SQLite.ahk": This DllCall requires a prior VarSetCapacity. The program is now unstable and will exit. It no longer hard crashes to the point it wants to send a note to Microsoft (as it did in my first error description) however it does still fail after showing the 'Last Insert ID'. It is not overwriting the code with various pieces of 'Name Name'
Now I have made sure I am on the same SQLite version, and have moved from 3.7 to 3.8 without any changes. I had 1.0.45 of AHK installed, and that was when I had the first error described (name name replacing items in the running file). I tried downgrading to 1.0.44 as the author points out in the source with no change, however when I moved up to the latest version that is when the error did change.
Again, any thoughts on what I may have done wrong here would be appreciated. I look forward to implementing all kinds of goodies using SQLite which I didn't have the ability to complete myself - KUDO's. |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Tue Nov 14, 2006 9:50 am Post subject: |
|
|
This is because AutoHotkey has become, with latest version, more picky on the size of variables used as buffer, ie. where the WinAPI will write.
That's a good thing, the old versions probably has hidden side effects, like memory overwriting.
Quick fix: Search in the code all the "UInt *" declarations in DllCalls.
Look at the variable name after this declaration. It is, most of the time, initialized like $h_DB := 0. Just change 0 to 0000 and it should be OK.
In _SQLite_Exec, $iErr isn't even initialized, add a $iErr := 0000 line after $i_RC init.
I suppose nick will update his script. nick, I suggest you remove the code pasted in the message and upload the file to AutoHotkey.net, if possible. Above a given number of lines, this becomes impractical. Thanks.
Note that the sample can remain there, it is rather small and it gives an idea of what the API looks like.
I fear the day the v.2 will be out... Will lot of scripts no longer working, we will have lot of similar messages... _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
nick
Joined: 24 Aug 2005 Posts: 345 Location: Berlin / Germany
|
Posted: Tue Nov 14, 2006 11:34 am Post subject: |
|
|
| PhiLho wrote: | I suppose nick will update his script. nick, I suggest you remove the code pasted in the message and upload the file to AutoHotkey.net, if possible. Above a given number of lines, this becomes impractical. Thanks.
Note that the sample can remain there, it is rather small and it gives an idea of what the API looks like. |
Hello PhiLho and valenfor,
I'll try to find out what's wrong, but it may need a few days. I'll also follow the suggestion to move the script to AutoHotkey.net.
See you! _________________ nick
denick @ http://de.autohotkey.com/forum/ |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Tue Nov 14, 2006 12:18 pm Post subject: |
|
|
| nick wrote: | | I'll try to find out what's wrong, but it may need a few days. | Please, re-read my post, I explain how to correct it... I didn't tested it, though! Some issues might remain. _________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
valenfor
Joined: 26 Feb 2005 Posts: 20
|
Posted: Tue Nov 14, 2006 12:41 pm Post subject: |
|
|
Thank you for the tip. I did the changes you suggested PhiLho, however the error still persisted. I traced back and found that when this call was made inside _SQLite_GetTable the $s_Col doesn't have its capacity set. So, just trying to find the solution I added this line as shown in the code below:
VarSetCapacity($s_Col, 1024)
| Code: |
VarSetCapacity($sResult, $i_GetRows * $iCols * $iCharSize)
VarSetCapacity($s_Col, 1024)
$i_Off := 0
Loop %$i_GetRows%
{
$s_Row =
Loop %$iCols%
{
$s_Col =
DllCall("lstrcpyA"
, "Str", $s_Col
, "Uint", _#SQLite_ExtractInt($p_Result, $i_Off))
$s_Row = %$s_Row%%$s_Col%|
$i_Off += 4
}
StringTrimRight $s_Row, $s_Row, 1
$sResult = %$sResult%%$s_Row%`n
}
|
This did fix the problem and it ran. I realize that the column size should be calculated, however I wanted to see if I at least found the right location. Just figured I would post in case it saves you some time Nick.
Thanks again for the help.
Val. |
|
| Back to top |
|
 |
nick
Joined: 24 Aug 2005 Posts: 345 Location: Berlin / Germany
|
Posted: Tue Nov 14, 2006 3:36 pm Post subject: |
|
|
| valenfor wrote: | | This did fix the problem and it ran. I realize that the column size should be calculated, however I wanted to see if I at least found the right location. Just figured I would post in case it saves you some time Nick. |
Hi,
I fixed it too, but too late!
What do you think about an additional optional parameter like iMaxLength=256 to pass the maximum column width to the function whenever needed?
THX for using the script and supporting me!  _________________ nick
denick @ http://de.autohotkey.com/forum/ |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|