• Welcome, Guest. Please login.
 
July 13, 2020, 07:53:30 am

News:

Welcome to the SQLitening support forums!


Recent posts

Pages1 2 3 ... 10
1
You've got Questions? We've got Answers! / Re: slSelBind
Last post by Fim - July 12, 2020, 01:56:54 pm
I previously received some wise answers to my question. But they have disappeared now that I should take up the matter.
Fim W.
2
General Board / Re: slOpen memory leak
Last post by cj - June 17, 2020, 07:20:37 pm
Fredrick,
I don't think it is a bug so I doubt it. That is up to Paul Squires.
Options:
1. Use slClose before slOpen.
2. Use IF ISFALSE(slIsOpen) THEN slOpen.
3. Don't call slOpen more than once without first closing.
4. Write a function or macro that replaces slOpen.
5  Add line IF thDab THEN EXIT FUNCTION like I did.

Fim,
Thank you for reporting this 4/1/2020 at:
https://sqlitening.planetsquires.com/index.php?topic=9756.msg26645;topicseen#msg26645
3
General Board / Re: slOpen memory leak
Last post by Fredrick Ughimi - June 17, 2020, 05:53:13 pm
Hello CJ,

Thank you for the information.

Would this fix be included in the installation files?

Best regards.
4
General Board / slOpen memory leak fix
Last post by cj - May 14, 2020, 11:48:07 am

FUNCTION slOpen ALIAS "slOpen  ...
  IF thDab THEN EXIT FUNCTION  '<--- add  line in SQLitening.Bas and compile

Rather than test every program ever written, make above 1-line change to SQLitening.Bas
This is not an error in SQLitening, but a programming error not checking if database was open.
Calling slOpen will now just return if database is open and not create new handle and leak previous handle.



Test new SQLitening.dll to be sure duplicate handles are not created using slOpen
#INCLUDE "sqlitening.inc"  'test new sqlitening.dll with 3 open methods

SUB Test(sdatabase AS STRING)
 LOCAL h AS LONG
 slOpen sdatabase
 h = slgethandle
 slOpen sdatabase
 IF h <> slGetHandle THEN ? "Memory leak"
END SUB

FUNCTION PBMAIN () AS LONG
 Test "temp.tmp"  'test database file
 Test ":memory:"  'test in-memory database
 Test ""          'test temp database
 ? "Done"
END FUNCTION

Also tested over the internet and using threads.
5
General Board / Re: slOpen memory leak
Last post by cj - May 11, 2020, 10:36:43 pm
Hi, Bern.

I can't think of any use.  The docs mention making direct calls to SQLite.
I only use slOpen in other threads.
.
I never realized a new global or threaded file handle was created with each call to slOpen.
I always thought SQlitening ignored a call to an already open database.

I will be modifying some programs by mostly using IF ISFALSE(slIsOpen) Then slOpen ...


Quote from: undefinedslGetHandle ([rsModChars String, rlSetNumber Long]) Dword

Returns the requested handle.  ModChars will determine which handle is returned.  The database handle may be used to call SQLite directly or can be passed to a different thread to be used in slOpen.  The set handle may only be used to call SQLite directly and then only if in local mode. A %SQLitening_InvalidStringOrRequest error will occur if you try to get a set handle in remote mode.


ModChars:
·    D = Return the open database handle. This is the default.
·    S = Return the open set handle for set number passed in SetNumber.


Returns zero if an error occurs and the global return errors flag is on.
6
General Board / Re: slOpen memory leak
Last post by Bern Ertl - May 11, 2020, 10:14:01 pm
Is there ever a case where opening more than one handle to the same database file within a single process might be useful?  I can't think of one right now, but maybe there is.
7
Fim,

I was able to get an error 7 by calling slOpen 1000's of times.
Looking at task manager the memory use went over a billion bytes.

Calling slOpen multiple times without slClose before reopening would be my first guess at the problem.
This would corect it:
IF ISFALSE(slIsOpen) THEN slOpen "Mydatabase.db3"

Test program that demonstrates a global handle is created each time slOpen is called.
https://sqlitening.planetsquires.com/index.php?topic=9760.msg26646#msg26646


This program demonstrates getting an error 7. 
If you run task manager before starting this you will see the memory usage go sky high.

GLOBAL gs AS STRING
#INCLUDE "sqlitening.inc"

FUNCTION PBMAIN () AS LONG
slSetProcessMods "E2"
LOCAL x AS LONG
Logit "Open database only if not open"
FOR x = 1 TO 5
  IF ISFALSE(slIsOpen) THEN slopen "junk.tmp","C": Logit USING$("handle #",slGetHandle)
NEXT
slClose
KILL "junk.tmp"
Logit  ERROR$(ERR) + " killing junk.tmp"

Logit ""
Logit "Open database without testing if already open"
FOR x = 1 TO 32000
  slopen "junk.tmp","C"
  IF x MOD 1000 = 0 THEN Logit USING$("#",slGetHandle)
NEXT
slClose
KILL "junk.tmp"
LOGIT ERROR$(ERR) + " killing junk.tmp"

? gs

END FUNCTION

SUB LogIt(s AS STRING)
gs = gs + s
END SUB
8
General Board / slOpen memory leak
Last post by cj - May 11, 2020, 09:30:43 am
This demonstrates how multiple global handles are incorrectly created (programming error) for the current database.
Notice the database cannot close correctly or be killed if this is done.  Permission denied error.
Calling slOpen many times without closing it will eventually produce an error 7.

GLOBAL gs AS STRING
#INCLUDE "sqlitening.inc"

FUNCTION PBMAIN () AS LONG
slSetProcessMods "E2"
LOCAL x AS LONG
Logit "Open database only if not open"
FOR x = 1 TO 5
  IF ISFALSE(slIsOpen) THEN slopen "junk.tmp","C": Logit USING$("handle #",slGetHandle)
NEXT
slClose
KILL "junk.tmp"
Logit  ERROR$(ERR) + " killing junk.tmp"


[b]'Now show how to incorrectly use slOpen[/b]

Logit ""
Logit "Open database without testing if already open"
FOR x = 1 TO 5
  slopen "junk.tmp","C"
  Logit USING$("handle #",slGetHandle)
NEXT
slClose
KILL "junk.tmp"
LOGIT ERROR$(ERR) + " killing junk.tmp"

? gs

END FUNCTION

SUB LogIt(s AS STRING)
gs = gs + s + $CR
END SUB
slOpen.png
9
Quote from: undefinedIn my system, I handle all processing of a Sql database via a special IO module, a module for each table. Everything works as I had imagined. But in a special case I get error code 7. I have done some tests and it seems I do NOT get error if I make all SQL calls directly in a program without going through an io module.
I get the error after 3732 calls with function GU (get unique).
Searching for SQLITE_NOMEM and it shows out of memory or something of that nature.
It could be an array out of bounds or passing nothing.

slGetUsedSetNumber (never needed it.)

The opening of the database from a udt memory might be it if the value is "".
That would open a temporary table without returning an error to you with perhaps no data to process.

Might be running out of memory if the recordsets are not processed until the end (or slSetClose was needed.)
' Process records of Set 1  (example in the help file)
Do While slGetRow(1)
' check the value of field 3   
  if slF(3, 1) >= "AB100" then Exit Do
Loop
slCloseSet(1)

https://www.sqlite.org/search?s=d&q=SQLITE_NOMEM


REM #define SQLITE_NOMEM        7  /* A malloc() failed */
10
General Board / Join 2D arrays with a column a...
Last post by cj - April 21, 2020, 08:59:39 am
Enables a column delimiter and a new row delimiter in new JOIN2$ function.
This makes it easy to display a string from a 2-dimensional array with a $CR  or other characters as a row delimiter.

Improved money macro to automatically display passed column name instead of printf statement.
SQlite "AS" is optional so just appended colname to the money macro.
Don't like leading 0 displaying on money columns so used ltrim to remove it.

Enjoy!

#DIM ALL
MACRO money(colname)= CHR$("ltrim(printf('%.2f',",colname,"*.01),'0')",colname)
#INCLUDE "sqlitening.inc"

FUNCTION PBMAIN () AS LONG

 LOCAL sql,sColDel,sRowDel,rs() AS STRING
 slopen "sample.db3"
 sql = "select manuf,redref,"+ money("PRICE") + " from parts limit 20"
 slselary sql,rs()
 sColDel = "   "
 sRowDel = $CR
 ? JOIN2(rs(),sColDel,sRowDel),,USING$("Rows #_, Cols #",UBOUND(rs,2),UBOUND(rs))

END FUNCTION

FUNCTION JOIN2(rs() AS STRING,sColumnDelimiter AS STRING,sRowDelimiter AS STRING) AS STRING
 LOCAL sb AS ISTRINGBUILDERA
 sb = CLASS "STRINGBUILDERA"
 'sb.capacity = 1024*1000 'does well without capacity

 LOCAL c              AS LONG
 LOCAL LowCol         AS LONG
 LOCAL HighCol        AS LONG
 LOCAL HighCol_minus1 AS LONG

 LOCAL r              AS LONG
 LOCAL LowRow         AS LONG
 LOCAL HighRow        AS LONG

 LowCol = LBOUND(rs,1)
 HighCol= UBOUND(rs,1)
 HighCol_minus1 = HighCol-1
 LowRow = LBOUND(rs,2)
 HighRow= UBOUND(rs,2)

 FOR r = LowRow TO HighRow
  FOR c= LowCol TO HighCol_minus1
   sb.add  rs(c,r)
   sb.add sColumnDelimiter
  NEXT c
  sb.add rs(c,r)
  sb.add sRowDelimiter
 NEXT r
 FUNCTION = sb.string
END FUNCTION
Pages1 2 3 ... 10