Skip to content

approach to opening lots of datasources and tables in appframework

Forums Forums SIMPOL Programming approach to opening lots of datasources and tables in appframework

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • #29
    JD Kromkowski
    Participant

    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

    #2025
    JD Kromkowski
    Participant

    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.

    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 if

    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
    >

    #2026
    Michael
    Keymaster

    On 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 if

    There 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
    >>
    >

    #2030
    JD Kromkowski
    Participant

    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

    #2035
    Michael
    Keymaster

    On 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

    #2062
    JD Kromkowski
    Participant

    I'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 SB

    I'm still not clear how you do this for a set of datasources and tables.

    #2027
    Jim Locker
    Member

    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.

    #1648
    Jim Locker
    Member

    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 object

    I 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.

    #1699
    Michael
    Keymaster

    On 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 object

    Jim'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

    #1647
    JD Kromkowski
    Participant

    On 01/24/13 1:27 PM, jim wrote:
    > me.opentables[test] =@ t

    Ok, I see it now.

    #2072
    JD Kromkowski
    Participant

    On 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.

    #2076
    Jim Locker
    Member

    *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.

    #2077
    Jim Locker
    Member

    kromkowski 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.

Viewing 13 posts - 1 through 13 (of 13 total)
  • You must be logged in to reply to this topic.