On the uselist there was a question from Mike Kerner
My answer - because I had a few problems was this - maybe it will help others - maybe not?I'm working on a session for next week's LCG. We are all working on
fun super-advanced pushing-the-envelope things in LC, but I wanted to do
something for the beginners who are watching LCG, and handling data seemed
like an obvious choice.
I have to admit, I haven't stored data in a stack in a long time, since the
database options are so easy to use. If you're currently storing data in a
stack, have you run into any issues on any platform with it, especially on
mobile, for instance, where the rules can be a little weird?
Hi Mike,
I have 60+ machines running windows7 embedded running a POS/TILL system also a few tablets running windows and android with the same system - wth abouth 8 lines of code added to work on Android.
In the first version of the system I save the arrays which held all the Clerks orders/totals etc and items into an external stack every time they added an item.
I then saved the whole thing and cleared the "dirty" flag on shutdown.
If the"till" program started and the dirty flag was true then system would know it was a powercut and load all the "open" orders and other status information etc.
I have users who have not had a problem in over 2 and a half years others who have 3 "tills" with no problems and just a few maybe (4 who have had a corrupt stack maybe 1 to 3 times a years - 2 or three times is too many. There is no ryme or reason because others have had powercuts (6 in an hour ) with no damage but others can can switch off without exiting the till properly without a problem and yet I can have a corrupt stack with everything shut down properly. So Now I have removed that stack and just save the arrays to "general" config table called TABS in sqlite in a row with an idkey of '99' other IDkeys can save other configuration information- NOT ONE PROBLEM since I have done this - go figure.
I'll make a posting on the forum with the code - not trying to teach my granny to suck eggs here, but maybe some beginners on the forum might find it useful - I would have done in the beginning.
Code: Select all
-- The code has had a lot of extra code removed as not adding anything to the Erudition of the code , so there might be a typo here or there ....
-- The code could be simplified by not encoding into Base64 and loading via revQueryDatabase. I did it this
---way because I wanted to be able to "cut and paste" into a text editor for testing and never went back to
-- change it -- "if it aint broke fix it until it is" ?
-- During the running of the program the arrays are saved after every addition and pClean is empty
-- so "YES" is stored in the "dirty" flag on disk. When they exit normally the arrays are saved and pass
-- "anything" in pclean so that the "dirty flag" is empty meaning all is OK.
on SaveArrays pClean
local lcgTencoded, lcgTBase64, lcgOencoded, lceOBase64
local lcDirty, lcSql, lnID, lcResult
put ArrayEncode(gTabs) into lcgTencoded
put Base64EnCode(lcgTencoded) into lcgTBase64
-- Other arrays removed ---
---
---
put ArrayEncode(gOrders) into lcgOencoded
-- This is only needed if you want the field to be "TEXT" and not a BLOB (binary data)
put Base64encode(lcgOencoded) into lcgOBase64
-- DirtyFlag empty means they exited OK
-- Dirtyflag is "YES" means it is dirty -- they did not exit via the proper exit button (maybe a powercut?)
put IIF(pClean is empty,"YES","") into lcDirty -- see ternary function below
put "UPDATE TABS SET gTabs= " && Q(lcGTBase64) & "DirtyFlag=" & Q(lcDirty) "WHERE idKEY = " & Q("99") into lcSql
put the cnDbConnection of this stack into lnID
revExecuteSql lnID, lcSql
end SaveArrays
on LoadArrays
local lcSql, lnId, lcResult, lcEncoded, lcData
put the cnDbConnection of this stack into lnID
put "select gTabs,TempO from TABS WHERE idKEY = " & Q("99") into lcSql
get revDataFromQuery("~","±",lnID,lcSql)
put IT into lcData
put the result into lcResult
set the itemdel to "~"
put Item 1 of lcData into lcEncoded
put Base64DeCode(lcEncoded) into lcEncoded
put ArrayDecode(lcEncoded) into gTabs
-- Other arrays removed
put Item 2 of lcData into lcEncoded
put Base64DeCode(lcEncoded) into lcEncoded
put ArrayDecode(lcEncoded) into gOrders
revExecuteSql lnID, lcSql
put the result into lcResult
-- Hasn't happened yet ....
if lcResult is not 0 then
answer "Houston, we've had a problem!! - CALL LAGI" with "Gotit"
end if
end LoadArrays
function DirtyShutDown
local lcSql, lnID, lcDirty, llDirtyFlag, lcREsult
put the cnDbConnection of this stack into lnID
put "select dirtyflag from TABS WHERE idKEY = " & Q("99") into lcSql
get revDataFromQuery(comma,return,lnID,lcSql)
put IT into lcDirty
put the result into lcResult
if lcDirty is"YES" then
NoBuzzer
answer warning "Till Not Shut down Properly" with "Gotit"
return true
end if
put false into llDirtyFlag -- If there is an n error we have bigger fish to fry
if lcDirty contains "revDB" then
answer warning "Database error - We've had a problem Houston!!" with "Gotit"
NoBuzzer
quit
end if
Return llDirtyFlag
End DirtyShutDown
function Q pStr
return "'" & pStr & "'"
end Q
-- Function : IIF() -- C / Foxpro Ternary operator workalike
-- Remarks : Returns one of two expressions depending on the logical expression passed
-- : Sometimes called Immediate If - Replaces simple and multiple (if nested) if then else
-- : IIF(1 > 2,"Yes","No") would return "Yes"
-- : IIF("15/01/2014" is a date,"Yes", "No") gives "No" for American Date Format
-- : IIF(true,IIF(false,"**","It Works"), "**False**") gives "It Works" - IIF can be nested
-- Param : pLogical, pExp1, pExp2
function IIF pLogical, pExp1, pExp2
if the value of pLogical is true then
return pExp1
else
return pExp2
end if
end IIF