Forums › Forums › SIMPOL Programming › approach to opening lots of datasources and tables in appframework
- This topic has 12 replies, 3 voices, and was last updated 11 years, 3 months ago by Jim Locker.
- AuthorPosts
- December 29, 2012 at 3:58 pm #29JD KromkowskiParticipant
I have question about the “application function” which opens the datasources and tables function Myapplication.new(Myapplication me, wxmenubar mb, wxtoolbar tb, wxstatusbar sb, string iconname, string iconimagetype) ….. // I’d really like to be able to “standardize” the opening of the //necessary datasources and tables // To that end, I’ve tried to boil the code down a bit if appw =@= .nul wxmessagedialog(message=”Error creating window”, captiontext=sAPPMSGTITLE, style=”ok”, icon=”error”) else initmainmenu(appw.mb, me) appw.onmanagemenu.function =@ managemenu inittoolbar(appw.tb, appw) appw.onmanagetoolbar.function =@ managetoolbar // Here is the bit where I just like to use a loop // Data sources: // In theory you could just get this directly from form that // you’ve built // C:SIMPOLOffice1bindates.sbm // C:SIMPOLOffice1binclaims.sbm // C:SIMPOLOffice1binbill.sbm array tablelist tablelist =@ array.new() tablelist[0] = “dates.sbm” tablelist[1] = “claims.sbm” tablelist[2] = “bill.sbm” integer iCount iCount = tablelist.count()-1 while iCount > 0 src =@ me.opendatasource(“sbme1”,tablelist[iCount], appw, error=e) if src =@= .nul errmess = “Error opening the” + tablelist[iCount] + “file” wxmessagedialog(appw.w,errmess, sAPPMSGTITLE, “ok”, “error”) else string test test = .ucase(rtrim(tablelist[iCount],”.sbm”)) t =@ appw.opendatatable(src,test, error=e) if t =@= .nul wxmessagedialog(appw.w, “Error opening the” + test + “table”, sAPPMSGTITLE, “ok”, “error”) else // THIS IS THE PART me.BILL =@ t // How could I do this programatically. Something like indirection // (always a weak spot for me in SB, usually remembering after the fact) // or the EXECUTE string$ trick in SB end if end if end while // setting ok should be in the loop ok = .true end if
December 29, 2012 at 4:38 pm #2025JD KromkowskiParticipantBTW, this is proper way to strip off ".sbm"
string test
test = .ucase(.lstr(tablelist[iCount],.len(tablelist[iCount])-4))And there is a typo in docs regarding .lstr()
In the prototype there is a semicolon rather than a comma separating the
paramenters.and this is how I am currently handling issue. There still should a
better way because I may be opening dozens of datasources and tables.if test == "BILL"
me.BILL =@ t
else if test == "CLAIMS"
me.CLAIMS =@ t
else if test == "DATES"
me.DATES =@ t
else if test == "IMAGES"
me.IMAGES =@ t
end ifOn 12/29/2012 10:58 AM, kromkowski wrote:
> I have question about the "application function" which opens the
> datasources and tables
>
> function Myapplication.new(Myapplication me, wxmenubar mb, wxtoolbar tb,
> wxstatusbar sb, string iconname, string iconimagetype)
>
> ….
>
> // I'd really like to be able to "standardize" the opening of the
> //necessary datasources and tables
> // To that end, I've tried to boil the code down a bit
> if appw =@= .nul
> wxmessagedialog(message="Error creating window",
> captiontext=sAPPMSGTITLE, style="ok", icon="error")
> else
> initmainmenu(appw.mb, me)
> appw.onmanagemenu.function =@ managemenu
> inittoolbar(appw.tb, appw)
> appw.onmanagetoolbar.function =@ managetoolbar
>
> // Here is the bit where I just like to use a loop
>
> // Data sources:
> // In theory you could just get this directly from form that
> // you've built
> // C:SIMPOLOffice1bindates.sbm
> // C:SIMPOLOffice1binclaims.sbm
> // C:SIMPOLOffice1binbill.sbm
>
> array tablelist
> tablelist =@ array.new()
> tablelist[0] = "dates.sbm"
> tablelist[1] = "claims.sbm"
> tablelist[2] = "bill.sbm"
>
> integer iCount
> iCount = tablelist.count()-1
> while iCount > 0
> src =@ me.opendatasource("sbme1",tablelist[iCount], appw, error=e)
> if src =@= .nul
> errmess = "Error opening the" + tablelist[iCount] + "file"
> wxmessagedialog(appw.w,errmess, sAPPMSGTITLE, "ok", "error")
> else
> string test
> test = .ucase(rtrim(tablelist[iCount],".sbm"))
> t =@ appw.opendatatable(src,test, error=e)
> if t =@= .nul
> wxmessagedialog(appw.w, "Error opening the" + test + "table",
> sAPPMSGTITLE, "ok", "error")
> else
> // THIS IS THE PART
> me.BILL =@ t
> // How could I do this programatically. Something like indirection
> // (always a weak spot for me in SB, usually remembering after the fact)
> // or the EXECUTE string$ trick in SB
> end if
> end if
> end while
> // setting ok should be in the loop
> ok = .true
> end if
>January 2, 2013 at 6:46 pm #2026MichaelKeymasterOn 29/12/2012 16:38, kromkowski wrote:
> BTW, this is proper way to strip off ".sbm"
>
> string test
> test = .ucase(.lstr(tablelist[iCount],.len(tablelist[iCount])-4))
>
> And there is a typo in docs regarding .lstr()
>
> In the prototype there is a semicolon rather than a comma separating the
> paramenters.Thanks, I will have a look.
> and this is how I am currently handling issue. There still should a
> better way because I may be opening dozens of datasources and tables.
>
> if test == "BILL"
> me.BILL =@ t
> else if test == "CLAIMS"
> me.CLAIMS =@ t
> else if test == "DATES"
> me.DATES =@ t
> else if test == "IMAGES"
> me.IMAGES =@ t
> end ifThere is a way of accessing a property of a given string value. See the !setproperty() system function. I have to check if I have
distributed it, but I also have a function called hasproperty() that returns .true or .false depending on whether the string
passed is a property of the type passed.Ciao, Neil
>
>
>
>
>
>
>
>
>
>
> On 12/29/2012 10:58 AM, kromkowski wrote:
>> I have question about the "application function" which opens the
>> datasources and tables
>>
>> function Myapplication.new(Myapplication me, wxmenubar mb, wxtoolbar tb,
>> wxstatusbar sb, string iconname, string iconimagetype)
>>
>> ….
>>
>> // I'd really like to be able to "standardize" the opening of the
>> //necessary datasources and tables
>> // To that end, I've tried to boil the code down a bit
>> if appw =@= .nul
>> wxmessagedialog(message="Error creating window",
>> captiontext=sAPPMSGTITLE, style="ok", icon="error")
>> else
>> initmainmenu(appw.mb, me)
>> appw.onmanagemenu.function =@ managemenu
>> inittoolbar(appw.tb, appw)
>> appw.onmanagetoolbar.function =@ managetoolbar
>>
>> // Here is the bit where I just like to use a loop
>>
>> // Data sources:
>> // In theory you could just get this directly from form that
>> // you've built
>> // C:SIMPOLOffice1bindates.sbm
>> // C:SIMPOLOffice1binclaims.sbm
>> // C:SIMPOLOffice1binbill.sbm
>>
>> array tablelist
>> tablelist =@ array.new()
>> tablelist[0] = "dates.sbm"
>> tablelist[1] = "claims.sbm"
>> tablelist[2] = "bill.sbm"
>>
>> integer iCount
>> iCount = tablelist.count()-1
>> while iCount > 0
>> src =@ me.opendatasource("sbme1",tablelist[iCount], appw, error=e)
>> if src =@= .nul
>> errmess = "Error opening the" + tablelist[iCount] + "file"
>> wxmessagedialog(appw.w,errmess, sAPPMSGTITLE, "ok", "error")
>> else
>> string test
>> test = .ucase(rtrim(tablelist[iCount],".sbm"))
>> t =@ appw.opendatatable(src,test, error=e)
>> if t =@= .nul
>> wxmessagedialog(appw.w, "Error opening the" + test + "table",
>> sAPPMSGTITLE, "ok", "error")
>> else
>> // THIS IS THE PART
>> me.BILL =@ t
>> // How could I do this programatically. Something like indirection
>> // (always a weak spot for me in SB, usually remembering after the fact)
>> // or the EXECUTE string$ trick in SB
>> end if
>> end if
>> end while
>> // setting ok should be in the loop
>> ok = .true
>> end if
>>
>January 3, 2013 at 10:56 pm #2030JD KromkowskiParticipantJDK wrote:
> // THIS IS THE PART
>>> me.BILL =@ t
>>>// How could I do this programatically. Something like indirection
>>>// (always a weak spot for me in SB, usually remembering after the fact)
>>>// or the EXECUTE string$ trick in SBI'm still not clear how you do this for a set of datasources and tables.
I guess what I am looking for is a Buildapplication function/sml
inputs:
Form(s)
Menuoutput:
application project
Something like that starts looking like a real RAD tool.
I am already sort of doing this with find and replace
JDK
January 23, 2013 at 12:54 pm #2035MichaelKeymasterOn 03/01/2013 22:56, kromkowski wrote:
> JDK wrote:
>> // THIS IS THE PART
>>>> me.BILL =@ t
>>>> // How could I do this programatically. Something like indirection
>>>> // (always a weak spot for me in SB, usually remembering after the fact)
>>>> // or the EXECUTE string$ trick in SB
>
> I'm still not clear how you do this for a set of datasources and tables.
>
> I guess what I am looking for is a Buildapplication function/sml
>
> inputs:
>
> Form(s)
> Menu
>
> output:
>
> application project
>
> Something like that starts looking like a real RAD tool.
>
> I am already sort of doing this with find and replace
>
> JDK
>To do this right you would just take the components as you are describing them, and output a new project with complete source.
Although I have some plans for something like that, I am not yet ready to do it. The idea would be that in SIMPOL Personal there
is a menu option that lets you pick the database tables/sources, forms, print forms, quick reports, etc., tick a few boxes in a
wizard, and it spits out a complete project ready to be compiled. This would be a one way trip though.Ciao, Neil
January 24, 2013 at 5:48 pm #2062JD KromkowskiParticipantI'm not sure why it would be "a one way trip". why not let the IDE user
have access to code.but I still don't have answer to
JDK wrote:
> // THIS IS THE PART
>>> me.BILL =@ t
>>> // How could I do this programatically. Something like indirection
>>> // (always a weak spot for me in SB, usually remembering after the
fact)
>>> // or the EXECUTE string$ trick in SBI'm still not clear how you do this for a set of datasources and tables.
January 24, 2013 at 6:27 pm #2027Jim LockerMemberIf I understand what you are asking correctly, I handle that exact problem
by setting up an array in my app type:array opentables
then, for this code,
> if test == "BILL"
> me.BILL =@ t
> else if test == "CLAIMS"
> me.CLAIMS =@ t
> else if test == "DATES"
> me.DATES =@ t
> else if test == "IMAGES"
> me.IMAGES =@ t
> end ifI would have:
me.opentables[test] =@ t
This expands indefinitely, and I can quickly get the table handle I want.
I do the same thing with indexes.
January 24, 2013 at 7:15 pm #1648Jim LockerMemberActually, when you get down to it, I handle pretty much my entire system
this way. The arrays in simpol are, IMO, the most useful feature of the
language.I'm not using Neil's appframework; I have my own framework which is
essentially an MVC framework, with the database fields fully separated
from the form controls, and bound to each other through my controller
software and the extensive use of arrays.For instance, when I go to get a record from a table, I have a function
called getrecord() which returns an array of the contents of the desired
record. The array format is determined by the structure of the record,
but takes the general form of:rec["fieldname"] = value
rec["fieldnamedt"] = data type of value
…
rec["errno"] = error number returned from the database operations
rec["recobj"] =@ the record objectI then have a standard routine called bind_form_read() which copies data
from the array into the form using the contents of a bindings file (a text
file in my configuration directory) to determine what goes where, and
another routine called bind_form_write() which copies all the data from
the form to the array. There is another function called bind_me which is
an event handler for edittextboxes which copies the contents of that
edittextbox to the matching array. There is a bindings file for almost
every form in my system, and there are a LOT of different forms in my
system.When I want to write a record, I invoke the routine stdstore() which
handles the writing, and pass it that array.All operations are performed on the array, with subsequent updates to the
form as required using bind_form_read and to the database as required
using stdstore. No database objects at all are used or accessed outside
of the database handler library…only arrays are used. This facilitates
changing backends as required.Similarly, I am presently migrating all form object references into one
library to facilitate changing front ends (to, for instance, an html front
end, or even a socket for the front end).Thus, the command to get the text in an edittextbox:
text = fc.gettext()
is replaced in my system by:
text = gettext(app,"controlname")
and the function gettext handles the details…whatever those details
might be for the front end that is actually being used..jim wrote:
> If I understand what you are asking correctly, I handle that exact problem
> by setting up an array in my app type:> array opentables
> then, for this code,
>> if test == "BILL"
>> me.BILL =@ t
>> else if test == "CLAIMS"
>> me.CLAIMS =@ t
>> else if test == "DATES"
>> me.DATES =@ t
>> else if test == "IMAGES"
>> me.IMAGES =@ t
>> end if> I would have:
> me.opentables[test] =@ t
> This expands indefinitely, and I can quickly get the table handle I want.
> I do the same thing with indexes.
January 24, 2013 at 8:07 pm #1699MichaelKeymasterOn 24/01/2013 19:15, jim wrote:
> Actually, when you get down to it, I handle pretty much my entire system
> this way. The arrays in simpol are, IMO, the most useful feature of the
> language.
>
> I'm not using Neil's appframework; I have my own framework which is
> essentially an MVC framework, with the database fields fully separated
> from the form controls, and bound to each other through my controller
> software and the extensive use of arrays.
>
> For instance, when I go to get a record from a table, I have a function
> called getrecord() which returns an array of the contents of the desired
> record. The array format is determined by the structure of the record,
> but takes the general form of:
>
> rec["fieldname"] = value
> rec["fieldnamedt"] = data type of value
> …
> rec["errno"] = error number returned from the database operations
> rec["recobj"] =@ the record objectJim's approach is a perfectly valid choice. The only thing I would probably change is that I would use a type that contains all of
the information that he is storing in various places in the array, then I would have a very simple array or objects of that type.
I have used arrays both ways, and find that once you get beyond a few bits, they become very messy in the code. That is why I then
switch to using a data type and managing that in the array.One of the reasons for choosing XML as our form storage format is that we can then later do XSL transforms on the forms to produce
things like an HTML5 form from them.We have recently produced a fully compliant JSON library that reads and writes JSON (it also handles the various encoding schemes
and even copes with legal but non-typical JSON formats). When reading it creates a set of JSON objects that produce a full JSON
tree/hierarchy that models the original JSON content. One of the next items that will be produced is a tool that uses that library
to produce a SIMPOL type (or set of types) that can represent the JSON that is being read, plus a function that can move data from
the JSON root object into the set of types, and from the set of types into the JSON. This will allow us an easily understood and
tested group of functionality for assisting in the development of programs that need to communicate using JSON, without the use
needing to understand anything about the JSON protocol.One of our longer term goals is to provide conversion tools for systems that use our data-aware forms and framework so they can be
migrated easily into an HTML5 (with JavaScript) client and a generic web server core with extensions.Ciao, Neil
January 28, 2013 at 6:08 pm #1647JD KromkowskiParticipantOn 01/24/13 1:27 PM, jim wrote:
> me.opentables[test] =@ tOk, I see it now.
January 28, 2013 at 6:12 pm #2072JD KromkowskiParticipantOn 01/24/13 3:07 PM, Neil Robinson wrote:
> I have used arrays both ways, and find that once you get beyond a few bits, they become very messy in the code. That is why I then
> switch to using a data type and managing that in the array.some where years back I think there was a thread I started about arrays
and use in lieu of app framework idea which had not yet been entirely
fleshed out at. My problem is that I'm just not enough of a programmer
(its really a side thing for me) to work through it all. In early
experiments, I also found it to get pretty "messy" not that I am not the
king of spaghetti.January 28, 2013 at 8:22 pm #2076Jim LockerMember*shrug* if it is going to get messy, use objects to encapsulate things and
keep everything tidy.
..
I'm actually quite pleased with my framework; the record information I
carry in arrays is only the value and the type, both hashed on the field
name, and all – I repeat – ALL the code that processes binding those
arrays to the forms totals 187 lines including comments, and this code is
servicing a program that is presently 40,000 lines of Simpol, and I'm
still translating from Superbase..
..
Of course, there's other processing that goes on with the forms; grids and
listboxes for instance often incorporate a many to one relationship
between database records and the form control, so those have to be handled
case by case in order to do the right things – and for some of those
things I DO use objects.
..
Generally, though, the way I'm doing it is quite elegant and I am quite
pleased with how it is turning out.January 28, 2013 at 8:56 pm #2077Jim LockerMemberkromkowski wrote:
> some where years back I think there was a thread I started about arrays
> and use in lieu of app framework idea which had not yet been entirely
> fleshed out at. My problem is that I'm just not enough of a programmer
> (its really a side thing for me) to work through it all. In early
> experiments, I also found it to get pretty "messy" not that I am not the
> king of spaghetti.Oh, I guess I need to be clear about something. I am not using arrays in
lieu of an "app framework". To the contrary, an app framework that is
very similar to Neil's is at the very core of my program. In fact, when I
was first starting to learn Simpol, I studied Neil's app framework and
adapted those parts of it that suited my design goals to my own purposes.So my app framework is descended from Neil's and works at the basic level
much the same way as his does. At this point, I don't really recall, but
I'm pretty sure that what became my startup and initialization code is
closely descended from a sample program provided with the Simpol
distribution. It spawns multiple windows in multiple threads and employs
an applist ring to tie things together.This is just the optimum way to set things up, given the features of this
language and environment.It is from that point that my design philosophy diverges sharply from
Neil's. His appframework incorporates data-aware forms and works to bind
the form controls rather closely to the database. My framework is
specifically designed to do the exact opposite; I separate the form from
the database just as far as I can, and I handle the binding using
middleware that is agnostic about the database and about the form
controls. - AuthorPosts
- You must be logged in to reply to this topic.