Breedmate is one of the few (possibly only) pedigree programs with its own scripting language. The language is called RIO. Currently it is only accessible as a text report which means that you will see them listed under the Forms-Reports section in the Chooser bar on the left of the Breedmate window.
In simple terms you can use RIO to write your own analysis functions that either produce text outputs (which incidentally can be easily written to output to say Excel) or will mark records so they can be filtered in the main grid view.
The following sections have been extracted from the Rio Scripting guide. See also the RIO scripting reference.
The first sample generally listed for any language is “Hello world!”. Here is the program:
That’s it. Just put in the text. (This is possibly the shortest Hello World program ever). Any normal text is just output. Apart from normal text there is only one other type of text – it’s called program text. All program text starts with the two character sequence <# and ends with #>.
So another example of the Hello world! Program is as follows:
<# println "Hello world!" #>
It’s a one line program (not counting the delimiters that indicate this is program text). The program has two parts: a println command which prints anything to the right of it and adds a new line after it. The second part is the string “Hello world!” – note that all strings are wrapped in double quotes.
As a slight variation on the above we can also do:
<# println 'Hello' , 'world!' #>
In the above case we have two strings separated by a comma. RIO simply prints any list of arguments in order. Println will put a space automatically between arguments if the previous argument is not blank.
Using a variable
In this next variation we will assign the string to a variable then print it:
<# $var='Hello' println $var #>
Note all variables start with $.
Simple maths and a loop
Combining the above with some maths and a while loop we have the following short program that prints the numbers from 1 to 10 and their square.
<# $var=1 while $var < 10 then $sqr = $var * $var println $var, $sqr $var = $var + 1 end while
The output from this is:
1, 1 2, 4 3, 9 4, 16 5, 25 6, 36 7, 49 8, 64 9, 81
The main elements of the while statement are while TEST then do something end while. But we could also do the above with a for loop in which case it looks like:
<# for $i in 1:10 println $i , $i *$i end for #>
This is interesting but Breedmate is after all a pedigree program designed to deal with database tables, records and fields so we’ll now start exploring what commands are available to handle this type of data.
Print the name of the first record
Starting with this simple example that simple prints the name from the first record of the Pedigree table. BTW to see the first record of a table you need to click the unsort button on the grid view toolbar because normally it is in alphabetic order on the first column.
<# $var=$Pedigree println $var #>
In the above we have used the pre-defined $Pedigree variable (a pre-defined variable for every table in your database is automatically created for you). Then we index it with 0 to get the first "record" in the Pedigree table and assign it to $var. Then in the println statment we index the record with 0 to get the value of the first field in the record which incidentally is the name field.
Alternatively we could have written it explicitly like this by indexing the record not by the field position but by its name.
<# $var=$Pedigree println $var[“Name”] #>
Lets say we want to print the name and reg number separated by -- then we would write:
<# $var=$Pedigree println $var['Name'], ' -- ' , $var['Reg No.'] #>
Note that println has three comma separated arguments.
List the name and registration of all champions
Now for something more useful The following code lists all champions including their name and registration #.
<# println 'Test to print name and reg no of all champions' for $p in $Pedigree where $p['PreTitle'].like('CH') println $p['Name'], $p['Reg No.'] end for #>
In this example $p is a record (i.e. a record in a table). $Pedigree is the table so when we say $p in $Pedigree RIO will loop over every record in that table. The "for" statement has a where clause that tests to see if the Titles field contains the string “CH” anywhere in regardless of case. Inside the for loop we have just one println statement to print name and reg #. Note that the square brackets are called an “indexer”. The bookmark represents a record which can be considered a list of fields, The indexer allows access to one of those fields either by position or by name. Note that the name is case sensitive and must match exactly.
Here is part of the output of that script:
Test to print name and reg no of all champions: Almondene Bärandalë Heather, 1116725 Almondene O'Barandale Lassie, 1116675 Almondene Beautys Lass, 1177415 Almondene Celtic Beauty, 1163625 Almondene Charger, N1264555 Almondene O'Dell, 14702 Almondene Digger, 1264535>
The above works quite well but can be SLOW for large database tables because it is having to read all the records in the pedigree table then filter them based on whether the "PreTitle" field contains "CH". The faster way is to get the database to do the filtering using an SQL query. This is done using the "query" function. So rewriting the above we have the following.
<# println 'Test to print name and reg no of all champions' for $p in query("select * from pedigree where Pretitle like '%ch%' ") println $p['Name'], $p['Registration'] end for #>
Note in the above, in SQL, field and table names are case insensitive so we could "select * from PEDIGREE" or "select * from pedigreEE". Also the "like" statement also does case insensitive matching. The percent % either side of ch tells "like" to match "ch" anywhere within a string so it will match "US CH" or "CH Grand". The "query" function is covered in more detail in the "Scripting Reference"
For those unfamiliar with SQL the * in the "select * from" means return ALL the fields in the table. We could possiby make our query slightly more efficient, and therefore run faster, by only fetching the fields we want to use. Son in this case instead of "select * from pedigree where Pretitle like '%ch%' " we could make it "select name, registration from pedigree where Pretitle like '%ch%' "
If we are printing lots of fields out, then instead of using "println" with lots a $p['Name'] we could instead use the "expr" function with an expression. Here is what this would look like.
<# println 'Test to print name and reg no of all champions' for $p in query("select * from pedigree where Pretitle like '%ch%' ") println expr($p, "[Name] [Registration]") end for #>
Mark all champions
In this sample, rather than print the champions, we mark them so that they can be viewed or filtered in Grid view.
<# println 'Mark all champions' $count=0 for $p in $Pedigree where $p['Titles'].like('CH') $p.setMark(1) $count=$count + 1 end for println 'There were' , $count, 'champions marked.' #>
The report is very similar to the previous report but inside the for loop we call the “setMark” method of the record variable with a value of 1. 1 corresponds to the red mark. If we had used 2 then the mark would be orange, 3 is yellow and so on. We also keep a count of how many we have marked and print that out at the end.
Print a record of a specific name
Indexers are very powerful functions. As well as working on a bookmark to get a field they can also work on a table to get a bookmark (i.e. a record or row). In the following example we print out every field from a record with a specific name:
List record by name
<# $var=$Pedigree['Almondene Beauty'] println $var #>
The result of running that on the DogSample.bmx database is:
List record by name
Almondene Beauty, F, , Collydale Toss, Almondene Meg, 1116715, , , Blue, , Barry Tanwell, Barry Tanwell, , , , , TAS 294, , , , , , , , AKC, , , rhapsody1.jpg, , , , , , , , , , , , , , , , , , , , , , , , , , , 2011-07-28 19:35:04, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
List all entries owned or bred by this breeder
In this example we will list the names of all entries that were owned or bred by the breeder of the currently selected record.
<# $breeder=$Subject['Breeder'] println 'Entries owned or bred by this breeder: ' , $breeder for $p in $Pedigree where $p['Breeder']= =$breeder or $p['Owner']= =$breeder println $p['Name'] end for #>
In the first line we use the predefined variable $Subject – this is the currently selected row (i.e. record or bookmark) in the currently selected table. We then get the contents of the Breeder field and assign it to the $breeder variable (this is just a convenient name – we could have called this variable anything like $fred – the important thing is it starts with $).
In the second line the println statement will just output the fixed text starting with “Entries owned…” and append the $breeder to the end. We output this first so its clear what entries we are matching to.
The third line is a for statement which iterates (loops over all values) over the Pedigree table basically looping over all the record. Each time through the loop it assigns the record to the $p variable. The for statement has a where clause that tests if this record is what we want by pulling out both the Breeder and Owner fields and comparing with our nominated breeder. If either is a match then the for loop will use that record.
Inside the for loop we have just one statement – a println which uses the $p variable – which in this case contains a record, and then gets the field in that record called Name and prints it.
The result of running the above on the DogSample.bmx database is:
Entries owned or bred by this breeder: Barry Tanwell Almondene Bärandalë Heather Almondene O'Barandale Lassie Almondene Beauty Almondene Black Beauty Almondene Gallant Lad>
Mark all champions
If all you want to do is filter the records you see in grid view then this can be done by using the setMark() command as we do in the following example which is a simple modification of the “List all champions” sample.
<# println 'Mark all champions' $count=0 for $p in $Pedigree where $p['Titles'].like('CH') $p.setMark(1) $count=$count + 1 end for messageBox('There were '+ $count+ ' champions marked.') #>
Inside the for loop we use $p (which is the current record or row in the table) and call setMark(1) which sets the marks on this record to 1 (the red mark). We also keep a count of how many records we have marked and display a message using the messageBox() command which takes a string argument.
Note there were the argument to the messageBox command was three values concatenated or joined together. Two of them are strings while the middle is an integer (or whole number). RIO automatically converts the number to a string before doing the join.
List all entries born within five years
This is an example of handling dates. The first line merely print the subjects (currently selected record in the grid view) name and date of birth.
We then read the DOB and put it into $date. Dates are internally stored as numbers and each daya is equivalent to 1 so adding say 7 is the same as adding a week. By adding 365 * 5 we have added five years to the date and assigned it to $datePlusFive.
We go into a loop over all the records in the Pedigree table testing if the DOB field is after our subject’s DOB and before the DOB plus five years. Inside the loop we print the records name and DOB.
<# println 'Mark entries born within five years of this record: ' + $Subject['Name'] + ' who was born: ' + $Subject['DOB'] $date=$Subject['DOB'] $datePlusFive=$date + 365.0 *5 // add five years to the subject's DOB for $p in $Pedigree where $p['DOB'] < $datePlusFive and $p['DOB'] > $date println $p['Name'] + ', ' + $p['DOB'] end for #>
Partial output is below:
Mark entries born within five years of this record: 24kt-kats Buddy who was born: 04-10-1996 A'far Major Paine, 26-01-1997 Abizaq Southern Exposure, 10-03-1998 Abyfinns Hermione, 20-11-2000 Abyriginal Blonde Ambition, 02-11-1996 Abyriginal Desert Hawke, 02-11-1996 Abyroad Moonlight Sonata, 20-04>