smartlist dowork
Das Goravani
goravanis at gmail.com
Tue Apr 12 22:22:38 UTC 2022
Martin,
Now that I go to try to answer your question about my "LastRowUsed" variable, I realize that I should try to steer you away from it.
You see that was how I coded for a few years with SQLite. It was for an old app that I converted to using SQLite. Naturally the app had many File Classes, and thus File Class Fields, that were used on every window in it. Converting it FULLY to SQL was out of the question for me, too much work. So I devised a way to work with the File Class Fields AND SQL… I wanted to replace Datafile commands like "Find…", "Single File Find", "Update Files", "Next".. with SQL Equivalents that I could call, that would leave the CRB exactly as after the traditional commands, so that I could convert my app with minimal changes, minimal effort, done mostly with Find and Replace. That was my aim and I achieved it. I devised a way to have centralized code for Insert and Update, which would mimic "Update Files". Eg: The primary key has to be in the CRB after an insert.. it cannot be missing. That was one hurdle to cross. Also when I issue an Insert or Update command, the centralized code has to take the data from File Class Fields in the CRB (in memory) and work with that.. put them into the SQL columns, and save the record, either insert or update.
Now that I am free from working on that old single user-many file classes-app.. now that I am free from it and embarking on new projects, I am not having File Classes, I am working without them. I imagine, guess, that you are not working with File Classes, you are probably working without them.
tvLastRowUsed was set in part by things that pertain only to File Classes.
I hardly want to go into it, as I think it is not for you, or anyone, unless they are converting an old app that has File Classes and lots of code and windows that use the File Class Fields.
You see in that app, via that method, you name your table classes exactly as your File Classes, and they all have to be the same, ie, fcCustomers is the name of your File Class for customers, and it’s also the name of your Table in the database, for customers. Then, when you do a select, usually it’s on a column, like SELECT WHERE custNumber=10. The columns in your SCHEMAS and thus in your data tables have to be identical to what they are in your File Formats. The ORDER of fields has to be identical between Schemas and File Classes too. All your schemas have to named "sc"[Name] and your table classes have to be tcName, your file formats fcName. This is all in an effort to be able to have centralized code that works on any one of your tables.
Then you call the code using an object so that calls to the central routines look like this:
Do tvObject.$singlefilefind(myField,1)
That would do a single file find equivalent and would do so on field myField with the seek value of 1
Calls to do an insert or update looked like this:
Do tvObject.$updatefiles(myFileClass,’ADD’) does an insert as opposed to 'EDIT' which would do an update
Note that by passing the name of a file class as the first parameter I thus have my table name in hand in the called method.. because File Classes and Data Tables are named identically.
I would call my methods by calling them in an instantiated object. Once I do a few lines of code there, I then proceed over and finish in a table class.. because I was told I should.. that table classes are cool.. that there are reasons.. personally I have found the main reason to use table classes is that you can have a SQL error method in them that gets called automatically when there’s a SQL error while working on the row pertaining to that table class, or $cinst in other words. I have found that SQL error method to be the best reason to work with table classes. Of course there is the ability to say $cinst.. that also is only table classes pretty much… that’s helpful.. but not essential.
So in my table super class where all the finishing code is located for all my centralized methods, I do the following to arrive at the value that is put into tvLastRowUsed
In "Find" type methods, that do Selects, I do not pass into it the file format name, just the find field name. Like Find on myField as 'xyz'… I pass in that field name. So then I do this line to find the file class name:
Calculate lfileformat as pfindfield.$class().$name
I then do this concatenation:
Calculate lrowname as con('tv',lfileformat,'row')
My rows, and I have one task variable defined for each FileClass or data table, I have one row reserved for each one, and they are all named via the same way.. they start with tv for task variable, and end in row, inbetween is the File Class name.
I then just assign THAT RESULT to tvLastRowUsed
Calculate tvLastRowUsed as lrowname
So now, if right after the SELECT or FIND I want to update that record, I can use tvLastRowUsed as the base of the command instead of $cinst
Do [tvLastRowUsed].$update()
On inserts since I pass in the Data Table (File Class) name it’s in a parameter field and I use it this way:
Calculate lrowname as con('tv',pFileClass,'row') ## make the row name
Calculate loldrowname as con('tv',pFileClass,'old') ## make the old_row name
Do method $packrowfromcrb (pFileClass) ## pack the row from the CRB
Do [lrowname].$insert() Returns #F
Note that $packrowfromcrb does just that.. it is a repeat loop that goes through the identically named fields one by one and places the data into the SQL ROW out from memory. (CRB). I have the reverse method also, packCRBfromROW…. That puts the data into the MOFF fields in memory out from the SQL ROW.
Again, all this is done because I have an old app that is fully using File Classes and MOFF fields thus, was in the DF1, is now in SQL… is a large app where I didn’t want to do all the dot notation for each and every use of a field everywhere… too many windows to convert, too much code to convert, so I worked out how to "stay in the CRB" and also "use SQL".
If you like the idea of tvLastRowUsed it’s simply a matter of putting the name of the row you use for a table into it.. because usually the flow is
We select a record, pull it into memory from disk
Then we change it
Then we save the changes
So it we set "lastrowused" on that first line, the select line, then we can confidently use it on the "save changes" line as the base of our update command, ie
Do [tvLastRowUsed].$update()
This may displease some coders. They may not like my system. I understand in ways, it’s OK. But it works for the app I was working on. It worked out beautifully actually.
It was a simplistic app internally in many ways. That lent itself to this method therefore.
I’m so used to that app and it’s ways.. I am probably going to mimic that style going forward.. I like the idea of centralized commands that handle all my needs, as opposed to writing insert and update code over and over every time you have a need to save data..
Because I won’t have File Class Fields with which to do this trick:
Calculate lfileformat as pfindfield.$class().$name
I will have to pass the name of the Data Table in my calls to do a Find (A Select), ie,
Do tvObject.$find('myDataTableName','myFindColumnName','myFindValue')
Naturally, such calls are only good for one column finding upon, with one value. I have such methods as "$findontwobinds" (Find on two bind variables).. and others that I ended up needing. When in those rare cases there were multiple columns to be searched or other more strenuous things to be done in the selecting then I would go custom and write it for that one occurrence. In other words custom situations need custom solutions. Standard situations can be handled with centralized simpler code.
I hope this long digression has helped you in some ways. It’s off the track of what you started on.. you simply want to be able to insert and update. I can sympathize. I had long waits while I waited days for an answer to come to my insert and update problems back when I first began with SQL. I went through those.. for sure.. couldn’t get it to insert or update, depending.. it was one of them, then it was the other..
Like I said before my update problem came down to: I was passing a character variable with the old row name in it, as opposed to passing an actual row variable as old row. That was one long hang up that took days to figure out, don’t ask me why, it just did.
I also ran for a long time without $excludefromupdate
I just didn’t need it. Everything was working.
Then one day I started to get errors on my $update command.. I forget the errors now.. they were mean and tricky though.. they did not give away the answer. Then Kelly noticed I wasn’t using $excludefromupdate and he turned me on to it. I implemented it and the bug on updating went away. I use it since.
To the end of your troubles !!!
Das
On Apr 12, 2022, at 4:59 PM, Martin Obongita via omnisdev-en <omnisdev-en at lists.omnis-dev.com> wrote:
>
> Hi Das,You said, "So I capture the row being used in Find, Select, List selection, any read in of a record, I capture the name of that table vis the row I use for it.. "
> I have schema named s01_sysreflocal_pry and table class taSysRefLocal.
> How do I capture task var "tvLastRowUsed"?By capture do you mean to define the row as that table class?
> Rgds, Martin.
>
>
>
> On Tuesday, April 12, 2022, 09:01:58 PM GMT+3, Das Goravani <goravanis at gmail.com> wrote:
>
> $cinst.$update($cinst)
>
> In theory that command should work, but I found that theory didn’t pan out.
>
> I may have been misled by some other things, but I found in my work that $cinst didn’t always work. I had to go to putting a variable there that contains the name of the row being used, instead of $cinst
>
> So I capture the row being used in Find, Select, List selection, any read in of a record, I capture the name of that table vis the row I use for it.. and use that row when updating that record instead of $cinst
>
> Do [tvLastRowUsed].$update()
>
> (I did ALL my inserting, updating, deleting, via centralized code that is called from everywhere.. so I never knew which table was being used and had to have everything working on the premises that any table could come through there.. I did things that way.
>
> tvLastRowUsed is a task variable for greatest scope, and it contains the name of the row that is being used to hold a tables data, is related therefore by name to the table class being used, which uses what is in the master table super class code wise. So it is in the master table class that I put the real code that is run. You probably know and do this already.
>
> Don’t know if I’m crazy or not but I found $cinst didn’t always work right. In my desktop app which uses SQLite, I have a mixed arrangement now.. some with the name field and some using $cinst and it works out.
>
> I also capture the old row at the end of Finds, Selects, Read-Ins.. and save it after Inserts and Updates.. it is the OLD row when the NEXT update on it comes around.. I like knowing I have the actual old row in there. I know however that usually it only uses the Primary Key field from old row.. making having the actual old row not necessary, but I do it anyways.
>
>
>
>> On Apr 12, 2022, at 1:38 PM, Martin Obongita via omnisdev-en <omnisdev-en at lists.omnis-dev.com> wrote:
>>
>> Hi Das,I sent them my library on the issue of $dowork, and they couldn't figure out why the method $save Do $cinst.$update($cinst) Returns #Fwas returning a false flag.So they left me with, we will get back to you when we find a solution.
>> Martin
>>
>>
>> On Tuesday, April 12, 2022, 08:15:18 PM GMT+3, Das Goravani <goravanis at gmail.com> wrote:
>>
>>
>> Martin,
>>
>> I haven’t worked with smart lists much. When I did, I also had some trouble getting it right, getting it to work, but eventually was able to do so and I agree, smart lists are really cool..
>>
>> I don’t know a slick way to test if a data connection is still active. I myself look at the SQL Browser in the Browser to see if the connection is still showing there (with sub lines like "Tables"..) written underneath the connection name. That tells me it’s still active. Sometimes I click on tables and make sure they are all listed to make sure my data connection is still valid. I code to verify I have a connection I
>>
>> Clear a row
>> Do a select that should populate that row
>> Test if data is in the row just by If myVar =1 (a certain column should have a 1 in it)
>>
>> If I am able to fetch that record into that row then I have a valid data connection
>>
>> So I actually test in that way sometimes.
>>
>> There may be much slicker ways of testing if a data connection is up and running.
>>
>> From what I’ve read on here you are doing what is necessary to make smart lists work.
>>
>> I would agree with others who say that you should test if your data is happening.. make sure $insert and $update work, or one of them, then try the smart list.
>>
>> Smart lists are essentially simple.. they keep track of changes made to a table that they can easily represent in memory, or part of a table.
>>
>> You add lines, change lines, remove lines, and it remembers these things and "does" these changes to your data table with the "$do…" commands like $dowork()
>>
>> That’s it. There’s nothing more to them.
>>
>> When I saw your code, a long piece, posted earlier in this thread, I got concerned about other things in it, and urged you to step through it and make sure it is stepping onto the lines you wanted.. but that piece of code was a manual approach to what the dowork command does automatically.. so I would recommend the $dowork command instead.
>>
>> Something else you said recently was cause for concern.. when you described what you are now doing.. why $excludefromupdate wasn’t needed.. I think it’s always needed with Postgres.. excluding the primary key from the columns submitted with either insert or update. I thought from what I’ve learned that this is always needed with postgres.
>>
>> I myself am connected to postgres now having successfully set it up on servers, learned how to use pgAdmin and so forth.. Postgres is my database now.. but I have not coded a lot with it yet.. I have yet to make my much used central called insert and update routines have the workings that postgres requires.. so I’m not that authoritative on postgres yet..
>>
>> Hoping you find a way to make smart lists work. It may be in reducing the amount of code you use with them.. they are essentially really simple.
>>
>> All the best to you,
>>
>> Das Goravani
>>
>> Ps: I’m surprised Omnis support has given up on you on this. That’s surprising to hear. I once had a problem, with updating, and it was Jeramy who was helping me.. and he stayed until it was resolved. It turns out I was using not a real row variable to represent "old row" to the $update command.. everything looked right at first glance, but in fact I was using a character variable to hold the name of old row, I wasn’t passing an actual row variable.. we went around on other things for a long time and came back to this simple point which was the clincher.. so in the end it may turn out to be a really small thing that is stopping you..
>>
>> Verify that data is working.. then try issuing the smart list commands, they should work straight away
>>
>> Here’s to believing that bumble bees can fly and that Martin will get smart lists working !!!!
>>
>>
>> _____________________________________________________________
>> Manage your list subscriptions at https://lists.omnis-dev.com
>> Start a new message -> mailto:omnisdev-en at lists.omnis-dev.com
>>
>> _____________________________________________________________
>> Manage your list subscriptions at https://lists.omnis-dev.com
>> Start a new message -> mailto:omnisdev-en at lists.omnis-dev.com
>
> _____________________________________________________________
> Manage your list subscriptions at https://lists.omnis-dev.com
> Start a new message -> mailto:omnisdev-en at lists.omnis-dev.com
>
> _____________________________________________________________
> Manage your list subscriptions at https://lists.omnis-dev.com
> Start a new message -> mailto:omnisdev-en at lists.omnis-dev.com
More information about the omnisdev-en
mailing list