Tips_tutorials   >   Studio101   >   Table Class
Table classes are non-visual classes that operate between other classes in your application and the database. Table classes give you a central point to control all of the database operations and communications. A very good thing from an object-oriented programming point of view.
Schema and query classes are used to define the columns in a list or row variable which we then use to fetch records from the database. We can not create instances of schema or query classes and we can not add methods to schema or query classes. They are simply used to define list or row variables which are mapped to tables in the database.
We can create instances of table classes and we can add methods to table classes. Once you see how this works, you begin to see how powerful table classes really are.
The Omnis Studio table classes comes with a very helpful set of built-in methods which we can see in the
In this section we will create a table class and add some custom methods to be used by our application. or through the .To create a table class as follows:
Do List.$definefromsqlclass('tCountry')
We'll use the
to test the table class:Do List.$definefromsqlclass('tCountry')
If List.$colcount=0
OK message [sys(85)] (Icon) {The list has zero columns after $definefromsqlclass('tCountry')}
Else
Do List.$sessionobject.$assign($ctask.dbsessionobj)
Do List.$select() Returns FlagOK
If not(FlagOK)
OK message [sys(85)] (Icon) {Flag false after $select()}
Else
Do List.$fetch(kFetchAll) Returns FetchStatus
If not(FetchStatus)
OK message [sys(85)] (Icon) {Flag false after $fetch(kFetchAll)}
End If
End If
End If
Getting all the records from a table is a common task, especially for tables like the Country table which contain a small number of records. In this section we'll add a $getAllRecords custom method to the table class to select and fetch the records.
; Calculate the ORDER BY clause.
Calculate OrderBy as "ORDER BY CountryName"
; Select all the records in the table.
Do $cinst.$select(OrderBy) Returns FlagOK
If not(FlagOK)
OK message [sys(85)] (Icon) {Flag false after $select()}
Else
; Fetch all the records in the table.
Do $cinst.$fetch(kFetchAll) Returns FetchStatus
If not(FetchStatus)
Calculate FlagOK as kFalse
OK message [sys(85)] (Icon) {Flag false after $fetch(kFetchAll)}
Else
; Set the current line to the first line.
Do $cinst.$line.$assign(1)
End If
End If
Quit method FlagOK
Notice the code is similar to our previous test code, but the variable, List, has been replaced with $cinst. This was confusing to me the first time I saw this in Omnis Studio. The reason $cinst is being used in the table class methods is that when we define a variable from a table class using Do List.$definefromsqlclass('tCountry'), we bind the variable to the table class. The list and the table class become one. Think of it like a wedding ceremony when the minister says and the two shall become one. Once the list variable and the table class are bound, and you are inside any of the table class methods, you are inside of the table class instance of the list variable, so to refer to the list, you must use $cinst rather than the list variable name.
Do List.$definefromsqlclass('tCountry')
If List.$colcount=0
OK message [sys(85)] (Icon) {The list has zero columns after $definefromsqlclass('tCountry')}
Else
Do List.$sessionobject.$assign($ctask.dbsessionobj)
; Get all the records in the table.
Do List.$getAllRecords() Returns FlagOK
End If
Test the code:
If you accidentally or intentionally
to a method and then decide you want to get out of that method and return to stepping through the code in the preceeding method click the button in the IDE toolbar. The button is a handy feature that was added in Omnis Studio v4.1.When we inserted the records into the Country table we manually set the primary key values. In this section we'll add a $setPrimaryKey custom method to automatically set the primary key to the one more than the maximum value primary key currently in the table.
; Check if the primary key column is null and not zero.
Calculate ColName as 'Country_pkey'
If isnull($cinst.[ColName])&$cinst.[ColName]<>0
Calculate FlagOK as kTrue
Else
; Get a new statement object from this table instance's session object.
Do $cinst.$sessionobject().$newstatement() Returns StmntObj
; Select and fetch the maximum primary key column value froma the table's records.
Calculate TableName as 'Country'
Calculate SQLText as con("SELECT MAX(",ColName,") FROM ",TableName)
Do StmntObj.$execdirect(SQLText) Returns FlagOK
If not(FlagOK)
OK message [sys(85)] (Icon) {SQL error when issuing the following SQL Text: [SQLText]}
Else
Do StmntObj.$fetchinto(MaxPKey) Returns FetchStatus
If FetchStatus=kFetchError
Calculate FlagOK as kFalse
OK message [sys(85)] (Icon) {SQL error when fetching the max pkey after issuing the following SQL Text: [SQLText]}
Else
; If the maximum value is less than 1000, set it to 1000.
If MaxPKey<1000
Calculate MaxPKey as 1000
End If
; Set the primary key column to the maximum primary key value plus one.
Calculate $cinst.[ColName] as MaxPKey+1
End If
End If
End If
Quit method FlagOK
Let's test the method:
; Define the list binding it to the table class.
Do List.$definefromsqlclass('tCountry')
If List.$colcount=0
OK message [sys(85)] (Icon) {The list has zero columns after $definefromsqlclass('tCountry')}
Else
; Set the session object.
Do List.$sessionobject.$assign($ctask.dbsessionobj)
; Add a line to the list and make it the current line.
Do List.$add()
Do List.$line.$assign(1)
; Set the country name and the primary key.
Calculate List.CountryName as 'Italy'
Do List.$setPrimaryKey() Returns FlagOK
End If
The $setPrimaryKey code is not necessarily the code you would use to to set the primary key in a large application with lots of users. There is a problem with the $setPrimaryKey method code which we just wrote, and that is, if you are setting the primary key for a batch of records before inserting the first record, the method will keep returning the same primary key value... not good. An alternate technique which I use is to have a separate table in the database which keeps track of the last primary key for each table. If you are using a RDBMS it likely has a technique for getting a unique primary key value for each table.
You can override any of the Omnis Studio built-in table class methods by adding a custom method by the same name as the built-in method to the table class.
The $dowork built-in table class method is a great code saver for Omnis Studio developers.
After you define a list from a SQL class and set the session object you can set the list to be a smartlist. When you set a list to be smartlist, Omnis Studio immediately creates a history list which keeps track of the original values in the list and tracks any changes you make to the smartlist.
When you are finished with adding, updating, and deleting lines in the list you simply, Do List.$dowork(), and Omnis Studio generates and executes all the SQL for deleting, updating, and inserting, records into the database.
In this section we will add a $dowork method to override the built-in $dowork. The $dowork method will call the $setPrimaryKey method for any records being inserted, and then do the Omnis Studio default $dowork method. By making this modification the table class will be responsible for making sure the primary key is set for any new records we are inserting into the database.
; Store the current line number.
Calculate StartLineNum as $cinst.$line
; Reduce the smartlist to the lines to be inserted only.
Do $cinst.$includelines(kRowInserted)
; Preset the flag to true before the loop.
Calculate FlagOK as kTrue
; Loop through the lines to be inserted.
For $cinst.$line from 1 to $cinst.$linecount step 1
; Set the primary key.
Do $cinst.$setPrimaryKey() Returns FlagOK
If not(FlagOK)
Break to end of loop
End If
End For
; Include all the normal list lines.
Do $cinst.$includelines(kRowInserted+kRowUnchanged+kRowUpdated)
; Restore the current line.
Do $cinst.$line.$assign(StartLineNum)
If FlagOK
; Do the built-in default $dowork method.
Do default Returns FlagOK
If not(FlagOK)
OK message [sys(85)] (Icon) {Flag false after running the default $dowork method.}
End If
End If
Quit method FlagOK
Test the code:
; Define the list binding it to the table class.
Do List.$definefromsqlclass('tCountry')
If List.$colcount=0
OK message [sys(85)] (Icon) {The list has zero columns after $definefromsqlclass('tCountry')}
Else
; Set the session object.
Do List.$sessionobject.$assign($ctask.dbsessionobj)
; Set the line to be a smartlist before adding a new line to the list.
Do List.$smartlist.$assign(kTrue)
; Add a line to the list and make it the current line.
Do List.$add()
Do List.$line.$assign(1)
; Set the country name.
Calculate List.CountryName as 'Sweden'
; Issue a $dowork to save smartlist changes to the database.
Do List.$dowork() Returns FlagOK
If FlagOK
; Get all records to check to see if the record was added.
Do List.$getAllRecords() Returns FlagOK
End If
End If
In this section you have learned: