Converting FileMaker to Xojo And ActiveRecord

We are currently converting a FileMaker app to a Xojo web app.  We are about  3/4 of the way through the project and it’s been a surprisingly easy conversion.  Our biggest challenge has been normalizing the database since the original FileMaker developer did some things that were less than ideal.

Hal Gumbert over at Camp Software is starting a series of blogposts on their own transition from FileMaker to Xojo.  It is a recommended read.

One of the big things that many developers want coming from FileMaker and MS Access and other tools where the database is tightly integrated into the development tool is data binding.  It makes for a quick way to load/save data to and from the user interface.  We don’t do data binding and I’ll get into that a bit later.

In Hal’s blog post he goes into the various Xojo options and ActiveRecord is one of them.  I thought I’d spend a little time talking about ActiveRecord to fill you in on what it does.

ActiveRecord eliminates many common mistakes that developers have when creating database applications using Xojo.  How many times have you mistyped a table or field name in an SQL query?  We used to do it a lot and ActiveRecord eliminates much of it.  It does this by creating a NameSpace module and creating a class for each table.  The properties in those classes then map to the field in each table.

A register function for ActiveRecord uses Introspection to ensure you have all of the tables and fields from the database mapped in your classes.  If not, an assertion takes place in debug mode which tells the developer if they’re missing a table, field, or if a field is mapped to the wrong datatype.  This is very handy on large projects where you might be adding a bunch of fields to meet changing conditions and this way you definitely will not forget to add them to the ActiveRecord classes.

Creating the classes can be tedious especially with very large databases.  Our ARGen utility will help generate the classes for your by scanning your database and creating the classes for you.  For some this might seem backwards but we tend to design the database first and then code to it and we find that ARGen does 75% of the repetitive work for us by creating the classes and adding some shared methods to each class that help in queries and finding a particular record.

Once created, using ARGen is fairly simple.  To get a list of records in normal Xojo code you would create a query.  ActiveRecord does something similar using a class shared method.  Here is an example of using the List shared method to load a ListBox:



for each oCompany as Data.T_Company in Data.T_Company.List(sCriteria, sSort, iOffset)
   
   lst.AddRow oCompany.sCompanyNameCurrent,  _
   
   oCompany.sStreet1, oCompany.sCity, _
   
   oCompany.sStateCode, _
   
   oCompany.sZipCode, _
   
   oCompany.sCompanyStatusName, _
   
   oCompany.sAgentName, _
   
   oCompany.sParentName
   
   dim iRow as integer = lst.LastIndex
   
   lst.RowTag(iRow) = oCompany
   
next


Data is the NameSpace and we are calling the T_Company List method and we pass in three parameters.  The first is our search criteria, the second is the sort criteria, and the last is the offset which allows us to ‘page’ our data.  It returns an array of Data.T_Company objects and we simply add what we need to the ListBox and stash the object in the RowTag event.  The best part about this is that AutoComplete in the Xojo code editor will show us the table and field names and we don’t have to remember any of it.

Screen Shot 2015-06-24 at 9.49.32 AM

When we wish to edit the record we grab it from the ListBox.RowTag property and pass it in to our editor.



dim oCompany as Data.T_Company =  lst.RowTag(lst.ListIndex)

dim pg as new pgCompanyDetails

pg.Display oCompany


ActiveRecord doesn’t do data binding.  We simply don’t find it useful for a variety of reasons.  First, to do data binding your need to have controls that can handle the data source.  We could create control subclasses but after working with custom data bindings in Xojo on a project or two I was not happy with the endless tweaking we had to do to get them to work properly.  Maybe someone with more patience that I do will be satisfied with it but I never was.  Plus, most developers I’ve met that have done data binding on large projects remain unsatisfied in some form or another or go to extraordinary lengths to make it ‘easy’ (like having every field be string even for things that should clearly be a numeric data type).

Instead we chose a much simpler route.  In our edit forms we have three methods:  Load, Save, Validate.  We feel this offers us some advantages over binding.  First, everything is local to the window.  We don’t have to go find the subclass that handles the data load, save, and validate.  This lets us customize everything for that particular form.  An example Load method:



Private Sub Load()
   
   if moCompany.IsNew then
      
      lblCompanyID.text = "New"
      
      pmStatus.Enabled = false
      
   else
      
      lblCompanyID.text = moCompany.iCompany_ID.ToString
      
      pmStatus.setid moCompany.iCompanyStatus_ID
      
      pmStatus.Enabled = true
      
   end
   
   //Other code here
   
   if moCompany.IsNew then
      
      ccDatePicker1.dtmSelected = new date
      
   else
      
      ccDatePicker1.dtmSelected = moCompany.dtClientSince
      
   end
   
   txtCompany.text  = moCompany.sCompanyNameCurrent
   
   ccLastModified1.SetRecord moCompany
   
End Sub


Right away we can see that what we load depends if the record is new or existing.  Data binding wouldn’t help us there.  Labels and TextFields are the easies to do data binding with but since you’ll need a TextField to do a numbers only field or a date field you now have to create multiple subclasses.  Probably not a big deal but we’ve found it to be a hassle.  Having everything local means we can handle the edge cases with ease rather than having to modify the control subclass that’s doing the binding.

Before we can call our save method we have a Validate method that simply returns true if everything is okay.  If not, it presents a message to the user:



Private Function Validate() As boolean
   
   SetError ""
   
   if txtCompany.text.trim = "" then
      
      seterror "Validation Error.  Company name cannot be blank."
      
      txtCompany.SetFocus
      
      return false
      
   end
   
   if Data.T_Company.IsDuplicate(txtCompany.text.trim, moCompany.ID) then
      
      seterror "Validation Error. That Company name is already in use."
      
      txtCompany.SetFocus
      
      return false
      
   end
   
   return true
   
End Function


Then finally in our Save method we load data from the controls into the object for saving:



Private Sub Save()
   
   moCompany.CompanyStatus pmStatus.RowTag(pmStatus.ListIndex)
   
   moCompany.dtClientSince = ccDatePicker1.dtmSelected
   
   moCompany.sCompanyNameCurrent = txtCompany.text
   
   moCompany.iCompanyEmployeeCount = txtNumberOfEmployees.text.val
   
   moCompany.SICCode ccSic1.SICcode
   
   moCompany.sURL = txtWebSite.text
   
   moCompany.sTaxIDNumber = txtTaxID.text
   
   moCompany.bInactive = chkInactive.Value
   
   moCompany.save
   
End Sub


Note that our save method doesn’t care if it’s a new or existing record.  Behind the scenes ActiveRecord does the appropriate Insert or Update prepared statements.

Every place where we are editing data we have these three Load, Save, Validate methods.  Everyone on our team knows to look for those so it’s very easy for our team to work on projects collaboratively and know pretty much what’s going on.

Could ActiveRecord do data binding?  Sure.  The classes are open source so feel free to modify them to your hearts content but I truly believe it’s more a matter of the controls being the real pain.

ActiveRecord has a number of events that are handy to use.  We track who created and who changed the records using 4 fields on each table CreatedDate, ModifiedDate, CreatedByID, and ModifiedByID.  We add the BeforeCreate and BeforeUpdate events.  For example, the BeforeCreate event looks like this:



Sub BeforeCreate()
   
   dtCreatedDate = new date
   
   if session.oUser <> nil then
      
      iCreatedBy = Session.ouser.iUser_ID
      
   end
   
End Sub


This gets called before we save anything so the class properties get modified before we attempt to save.  In many projects we have an audit trail to know who changed what data so we add the AfterCreate and AfterSave events of Data.T_Company and pass the entire object into the Audit table:



Sub AfterCreate()
   
   dim oAudit as Data.T_Audit = Data.T_Audit.AuditAdd(self)
   
   oAudit.iCompany_ID = self.id
   
   oAudit.Save
   
End Sub


Then it’s up to the Audit class to query the ActiveRecord class to find changed data and put that into its table.  Again, the code to do this is one one spot rather than all over the project.

I could spend hours talking about ActiveRecord as we tend to use on all of our new database projects.  It speeds up development of database applications.  It eliminates many of the common errors.  It tends to force most database code into the NameSpace classes.  And the compiler can warn you if you’re doing bad things with data.

ActiveRecord is not for EVERY project but we’ve found it incredibly useful in our consulting.  If you dread doing a database project because of the tediousness of database coding then perhaps ActiveRecord is for you.

We recently did a webinar with Xojo on ActiveRecord.  You can view it at http://developer.xojo.com/webinar-simplying-db-access-with-bkeeney-activerecord.  ActiveRecord itself is open source.  ARGen is $19.95.  We also use ActiveRecord in one of start to finish training projects at our training site called Link Share.

ActiveRecord home page 

ARGen home page 

Xojo Training Site

Database Field Madness!

Two clients in the last several weeks have shown up with the exact same issue and it’s time to talk about it.  In both cases the clients had a field in a table that could contain multiple sets of data.  This is a really bad idea and if you find yourself doing it…well…stop it!

In the first case their company table has an email field and at some point in their past they decided that some users needed two email addresses.  Instead of creating an additional field for an alternate email address they simply decided to concatenate the data into one string separated by a comma.

To be honest I’m not sure why it sounded better to concatenate the data rather than create a second field but that’s what they did.  This decision was made years ago, of course, by a developer no longer working for the company, but it’s now up to me to ‘fix’ it.

With emails being prolific it might make more sense to have an email specific table that tie to the customer and can be inactivated.  This solves a number of issues.  It lets users have more than one email addresses.  The other thing it does is keep a history of the customer email addresses so if you are trying to verify a user account via the phone it might be a way to verify their identify when all else fails (not that I’d solely use that).

In the second case the customer table has several fields that can grow over time.  One field has notes separated by carriage returns, another field has billing data and another has payment data and each has ‘records’ in that single field separated by carriage returns and the data in each record separated by pipes.

Example:  The notes field for a single customer might be something like this:

6/20/2010 This is a note

6/30/2010 This is another note

7/5/2014 This is another note that could be pages long.

If you find yourself designing your database like this STOP right now and step away from the keyboard!  Databases are really good at having tables with related data.  Your notes, bills, and payments tables would all have a foreign key references back to the customer table.  That way you can have as many of those children tables as needed without affecting the customer table.  Having fields that grow exponentially in a single record is a bad thing.

Another issue that I see a lot is that you, the programmer, should never, ever, generate your own record id’s.  Let the database do that unless you have some really special-use scenario where you can do a better job of it.  To be clear, I’ve never seen this scenario.  Instead, your primary key should be an auto-incrementing integer and is something that you should never be able to modify.  That’s not to say that you can’t create your own ‘human readable’ code but it should never be used as the primary key of your table.

Another thing, take the time to use the native data types for the database.  If it’s an integer use an integer field type.  If it’s a date then use a Date or DateTime field type.  Booleans, if not a native data type for the database you’re using, can be a TinyInt with a length of 1.  Your conversion to and from Xojo will not be an issue and you let the database do a tremendous amount of work for you.  One client had an Amount field set up as string.  To get a total amount they had to load the entire recordset in, loop through it, convert the string to a double and keep a running total.  Instead, they could have done a simple Sum in an SQL statement and let the database do all the work!  Trust me, it’s much faster that way.

Those are my database hot button topics.  My DBA wife (i.e. The Database Goddess) has her own hot button topics and has beaten them out of me convinced me of the error of my ways and I no longer do them (or at least not without a reprimand).

In most cases the clients didn’t know any better and I’m sure at some point in my distant software development past I did some silly things like that too.  Those silly bad habits were beaten out of me after several accounting projects where database speed was essential.

What sorts of database blunders have you seen that now drive you nuts?

Xojo Cloud Database Support

Last week Xojo announced new features for Xojo Cloud.  They now support MySQL and PostgreSQL database servers in addition to SQLite that they have supported since day one.  One of the interesting features with the database support is that db admin tools that support SSL tunnels can connect to the database as if it was running locally.  In my testing it was surprisingly easy to setup and use.

The first thing to do is log into your Xojo Cloud account control panel.  Then simply enable either the MySQL or PostgreSQL database and enable the SSL Tunnel.  In each case you will receive a username and password that you’ll need to copy before moving on to the next step.

Screen Shot 2015-02-26 at 10.28.25 AM

Our MySQL admin tool of choice is NaviCat.  Setting it up was pretty easy to do.  Create a new connection and then navigate to the SSH tab.  Enter your server IP address, the username and password.

Screen Shot 2015-02-26 at 10.32.30 AM

Then navigate to the General tab and enter a Name for this connection (I used Xojo Cloud).  Because you’re using the SSL Tunnel you need to enter ‘localhost’ into the Host field.  Enter your Xojo supplied username and password and then test your connection.

Screen Shot 2015-02-26 at 10.38.00 AM

After that, everything acts just as if the server were local to you.  In this example I created a sample database named ‘bkeeney’ and a table called ’t_temp’.

Screen Shot 2015-02-26 at 10.34.09 AM

Your Xojo web application, then, will connect to it via the localhost parameter along with username and password suppled to you from Xojo.  Because it’s inside the firewall your web app needs to do nothing more.

Setting up a database server in Xojo Cloud really is that simple.  It just works.  From start to finish it only takes a few minutes to get up and running.  It’s a great addition to Xojo Cloud.

Data Paging Control

A lot of Xojo developers don’t give too much thought to how much data they’re loading into a listbox. For many desktop apps a couple of thousand rows is not uncommon and, frankly, not a big deal. Push that to ten thousand rows and things start to get dicey and when you get to a million rows you’re talking some serious wait time for all million rows to get added to a list box.

For web apps it’s even worse. When the server gets the request to load a WebListbox with a million rows it has to build all of the HTML, first, on the server, push it down the internet connection to your browser, and THEN the browser has to reconstruct those million rows of HTML into a display. Any time you deal with strings there is a performance penalty and needless to say a million rows of data is huge hit to performance.

Trying to show the user a million rows is bad on multiple levels. First, your application is slammed with unnecessary string handling and second, the user can’t possibly handle a million rows of data. The listbox scrolling alone would be a nightmare! Just don’t do this!

Web apps have been using paging controls for years to limit the amount of data the user sees. I’ve seen some web sites limit this data to 100 rows and some to even less unless the user specifies more. That way the onus is on the user for the webpage being slow.  And more recently I’ve seen more desktop apps limiting the amount of data too.

Data Page Control

Today we released a new 48 minute training video showing you how to build your own paging control in Xojo desktop and web apps. We build the Paging Control using a Container Control and standard controls and then use it control a listbox. Then it’s a matter of using the SQL keywords LIMIT and OFFSET to control which records are returned. Of course the video comes with a desktop and web project file with source code you can use in your own projects.

The running example of the web app is at http://xojo.bkeeney.com/BKSWebExamples/#datapaging

This video is available to subscribers at http://xojo.bkeeney.com/XojoTraining/xojotraining.cgi?video=338

If you’ve not looked at our training videos you might find some interesting things. I invite you to take a look!

ARGen 1.6.3

ARGen64BKeeney Software released a new version of ARGen today.  ARGen is an ActiveRecord class generator for Xojo and Real Studio.  It allows you to generate all of the classes required to use ActiveRecord in your projects.

Version 1.6.3 Fixes a CubeSQL bug that kept the Load function from working properly.  You could get around this by using the FindByID shared method but some people prefer the Load method.

This version also modifies the ActiveRecord classes a bit so it uses the prefix/suffix preferences used in ARGen to make sure your classes have the required property to match the field in the table.  For example, if you had a field PlaywrightID and were using a prefix of ‘i’ it will now flag the developer if there isn’t a property named iPlaywriteID.  In previous versions it didn’t really matter what you used.  This is just one more developer aid.

It is recommended that all Windows users update manually since a bug was discovered in earlier versions of the auto updater.

Recordset’s are Funny Things

We have a new developer working at BKeeney Software and he’s in the learning phase of Xojo. Not only is he new to Xojo but he doesn’t have a ton of experience doing software development in general. As someone who’s been using Xojo for a long time it is interesting to see how people struggle with the language and the IDE.

Today we had one of those “teaching moments” as he was beating his head up against the wall with this bit of code in a save method. This is a simple Invoice application saving the invoice line item to an SQLite database that’s on the local machine. See if you can spot the mistake.

dim rs as recordset =db.sqlselect( "Select * From tinvoicelineitem where invoicelineitem_ID = " + str(iInvoiceLineItem_ID) )
if db.error then
   msgbox CurrentMethodName + " db error: " + db.ErrorMessage
   break
   return false
end
rs.Field("InvoiceID").IntegerValue = iInvoiceID
rs.Field("salesTax_Flag").BooleanValue = bSalesTax_Flag
rs.Update

if db.error then
   msgbox CurrentMethodName + " db error: " + db.ErrorMessage
   break
   return false
end


Have you spotted the error yet? I don’t blame you. It’s easy to miss and it took me a few minutes of staring at it to find it. The code runs with zero code errors and zero database errors. The only thing that’s wrong is that it doesn’t save any line item data.

Okay, I’ll tell you. I forgot to add the rs.edit command at the top of the method. Without telling the recordset that you’re editing it, it will never generate the SQL to update the RecordSet.


dim rs as recordset =db.sqlselect( "Select * From tinvoicelineitem where invoicelineitem_ID = " + str(iInvoiceLineItem_ID) )
if db.error then
   msgbox CurrentMethodName + " db error: " + db.ErrorMessage
   break
   return false
end
rs.Edit // IMPORTANT!
rs.Field("InvoiceID").IntegerValue = iInvoiceID
rs.Field("salesTax_Flag").BooleanValue = bSalesTax_Flag
rs.Update

if db.error then
   msgbox CurrentMethodName + " db error: " + db.ErrorMessage
   break
   return false
end


I can argue that the lack of an error is bad. Sure, I didn’t code it right, but you’d think there would be some sort of error if an update was called without a starting edit. I’ve added <feedback://showreport?report_id=35134> to the Feedback system.

To be honest, we don’t do straight Xojo database calls much any more simply because we’re using ActiveRecord for most projects. AR eliminates most of the tedious database coding and let’s you deal with the data and the UI. When you call the Save in ActiveRecord you don’t need to care if it’s a new record or not. AR handles all the gory (and boring) details for you.

What say you my Xojo friends? Do you get bit by this type of thing when doing database coding?

Names Mean Something

This week I had an ARGen user contact me.  They had purchased a license and it wasn’t outputting the tables like it should.  He was able to send me the database and I confirmed the problem.   I looked at the XML file that ARGen was producing and it appeared to be an error in the XML generation.  I did a quick fix and sent it back to him.

Except, that didn’t really solve the issue.  Silly me for not looking more into the issue (it’s good to be busy, but sometimes…).  Of his four tables, only the first two were generated for the DataFile namespace we use for ActiveRecord.  Digging into it some more I discovered that Database.FieldSchema was failing.

Silly me for not checking for a database error.  I find this ironic that I preach db error checking and I didn’t check it in that particular case.  I guess I just didn’t think that FieldSchema would return an error.  Anyway, the SQLite database had a table named ‘group’.  That happens to be a reserved keyword in SQLite and you really shouldn’t be able to do it, but some tools will let you do it anyway.  In fact, all of my tools let me do it but they must be qualifying table names internally.

In SQLite, if you put single quotes around the name like ‘group’ it will work.  In a quick test against MySQL and PostgreSQL that doesn’t work and generates a db error.  Now ARGen checks for the error and will warn if it bails prematurely because it can’t find the schema of a table.

I also recommended to the developer that he change his table name.  Having ‘group’ in every SQL statement is going to be a royal pain.  It’s easy to forget and unless your QA and testing staff (stop laughing and catch your breath) tests every single code path it’s quite possible that your customer will find it before you.  Why make life harder on yourself?

Which leads me to what BKeeney Software does.  Carol, our resident DBA (otherwise known as the Database Goddess) has a bunch of naming conventions for databases.  All tables have a prefix.  Regular tables have a “t_” prefix.  Reference tables like states, types, zip codes, etc, get a ‘tr_’ prefix.  Tables that are a many to many relationship have a ‘tx_’ prefix.  Views get a ‘vw_’ prefix and stored procedures have a ‘sp_’ prefix.

Some other rules:

  • Table names are never plural.  It’s never t_people, it would be t_person.  t_check not t_checks and so on.
  • If it’s a child table it will have the parent table name in its name.  So an invoice line items table might be t_invoicelineitems.
  • Avoid abbreviations unless it makes sense to use them.  We just finished a large accounting app with payroll.  We had well over 100 tables JUST for payroll, so rather than having payroll spelled out in every single table we just used ‘pr’ in the table names.
  • For the Primary Key field we insist on auto increment integers.
  • Primary key field name cannot be a simple ‘id’.  It’s too easy to get confused with which ‘id’ you’re talking about in joins.   Our primary field name is TableName_ID (underscore ID at the end).  So the primary key for t_person would end up being Person_ID.

I’m sure some of you are thinking that these rules are overboard and I’d agree if I didn’t do a dozen large database applications every year.  Once you get past a dozen tables or so things start to get confusing so having rules give us some advantages on big projects.  At a glance we can tell the function of a table.  Time is money and with a staff of four, the last thing we want to do is make it harder for a team member to determine what the function of a table is.

Names mean something and some names have implications.  If the developer had used our naming rule so that his table name was t_group, ARGen would have had zero issues.  Oh well, it was an instructive bug report.  I get to chastise myself for not doing some error checking and I get to write about it.

What things do you do on databases to make your life easier?

ActiveRecord and ARGen Updates

ARGen256We’ve been consistently updating ActiveRecord for our consulting and internal projects.  We find ActiveRecord to be a wonderfully way to get the Xojo IDE to do more work for you.  It reduces table/field name errors and gives you some nice autocomplete features in the Xojo Code Editor.  In addition to all that you never have an issue with silent data type conversion errors.  It has saved us hundreds of hours of development time in the past couple of years.  Another huge bonus for us in team development is having it flag the developer (runtime exception) when a new field is added but it’s not in the class yet (at runtime it’s silent).

Today, we released an update to the general ActiveRecord release and is available through the ActiveRecord page at http://www.bkeeney.com/rbinto/activerecord/

New in this release:

  • Support for CubeSQL Server
  • Provisional support (meaning don’t call us if it doesn’t work) for Oracle DB servers
  • Fixed a number of issues with MySQL, and PostgreSQL
  • Added SQLiteDatabase for Xojo users migrating away from REALSQLDatabase
  • Added more comments for errors when there are missing plugins (now very likely with CubeSQL support).

We also updated ARGen, our utility to generate the classes required to use ActiveRecord in your Xojo applications.  This $19.95 utility is a tool that makes creating the ActiveRecord classes a breeze.  Point it to the database you want, select the tables, hit the create button and it generates the Xojo classes required to use the database with your ActiveRecord application.

While it’s not very hard to create your own classes but this utility is a huge time saver.  For a test I took one of our big databases (about 350 tables with varying number of fields in each) and ran it through ARGen.  In 20 seconds it generated all of the data classes for the database and all I had to do was open the resulting XML in Xojo and drag the data classes into a project.

More information on ARGen at http://www.bkeeney.com/allproducts/argen/

New in this release:

  • Support for CubeSQL Server
  • Provisional support (meaning don’t call us if it doesn’t work) for Oracle db servers
  • Added SQLiteDatabase for Xojo users migrating away from REALSQLDatabase
  • Added the ability to add suffixes to your field names (in addition to the prefix)

Database Primary Keys

The primary key that you define for your tables is critical to a well performing and well designed database.  The primary key to your table is very important so it’s worth spending some time on it BEFORE you start coding.

Let’s start out by describing what the primary key does.  The primary key is the unique identifier of a record for each table.  Regardless of how many rows the table has in it, the primary key is the pointer to a particular row.  This key will never change during the entire lifespan of the row.  There will never, ever, be two records with the same ID.

The primary key should never change.  This is why using a text field as a primary key that contains human readable/changeable data is such a bad idea.  I’ve worked on databases where they used Name as a primary key.  This is such a bad idea especially in cultures where women change their last name when getting married.  Even exempting female name changes most places in the world allow you to change your name legally.  Since it can change it’s a bad idea for use as a primary key.

Another example that we’ve dealt with in the past is using a Social Security Number (national id).  Another bad idea for a number of reasons.  One, data entry mistakes happen.  Two, government agency mistakes occasionally happen where there are two (or more) people with the same SSN.  Three, it’s not uncommon in certain parts of the country where undocumented workers use the same SSN.  Four, identity fraud is common.  Because this means it’s possible for two people or more people to have the same SSN it’s not a unique identifier.  Avoid using it.  It’s  a bad idea.

We recommend using an auto increment integer primary key.  Let the database do what it does best and let it pick it out for you.  That way there will never be any collisions or duplicates.  It’s what databases do very well all on their own.

I’ve worked on projects where there was no auto-increment primary key and was defined as an integer.  The developer devised a scheme to get the largest record ID and increment it by one when needed.  This was fine when a single user used the app but when multiple people were inserting data at the same time collisions occurred generating errors because primary keys must be unique.  It was ugly to fix and it all would have been avoided if they had used an auto increment primary key to begin with.

Someone asked me the other day if ActiveRecord could use a text primary key.  No, and it won’t ever.  It expects an integer primary key.  If you ARE using a text primary key.  Stop.  Add an auto-increment primary key and then add a Unique Index on the text field.

Real Studio/Xojo has some interesting things happen if you try to open a recordset that’s not returning the primary key in the query.  It won’t be able to update it in some cases.  You’ll get a generic message about not know which record you’re trying to access.  I’ve had some issues, in the past, using many-to-many tables that couldn’t be edited even though they had a unique index on fields.  So I recommend adding an auto-increment primary key event to many-to-many tables.  Then, if you have constraints on your index (like the index needing to be unique) you can add them there.  So far it’s worked for me.

For primary keys we use a standard naming convention:  tablename_ID.  A lot of people use a generic ID field but we’ve found that to be less than ideal when doing table joins.  If you have table A, B, and C all with an ID field joining them together means I have to put an alias in my SQL statement so I can retrieve those primary keys later.  By using the A_ID, B_ID, C_ID I never have to alias the field names in a query.  Plus, it has the added benefit of making the SQL easier to read because the name is explicit and the _ID tells me its a primary key.

Each database has its own internal record id.  SQLite uses rowid and you can actually query against it.  If you haven’t specified a primary key in your table it will use that rowid as the primary key.  When you specify a primary key, the specified primary key and rowID are the same.  However, if you do not specify the primary key the rowID is not guaranteed to stay the same.  If you were relying upon rowid to identify records in other tables you might be putting yourself in through a world of hurt if the user ever does a vacuum on the database.    The moral of the story is don’t rely upon the internal id – always specify your own primary key (that auto increments if you haven’t heard it enough now).

If you get into the habit of using an auto increment integer primary key you’ll avoid many problems later.  You don’t have to use our naming standard for primary keys but doing so will improve the readability of your SQL statements.  Primary keys are too important for anyone/thing but the database to figure them out.

Happy Coding!

Xojo Licensing Changes

Xojo, Inc. confirmed last week that the licensing for Xojo is changing.  The IDE now costs nothing.  Free.  Zip.  Zilch.  Nada.  Now we all know that it’s awful hard to stay in business by not charging any money, so the catch is that to make a build you need a license.  If you’re building for desktops (Mac, Windows, Linux) you need a desktop license.  Building for Web you’ll need the web license.  Building a console app you’ll need a console license.  The only oddity in the mix is if you’re using database servers which requires an additional license SQLite is included in all licenses).

Now that the IDE is free all users can take advantage of all Xojo features.  Item encryption, server sockets, SSL support, database encryption, remote debugging, container controls, code profiling, IDE scripting and build automation are the big items that were not available to all users depending on what license they had for Real Studio.  This has some advantages for training and getting people to actually use those features.  Everyone has the same set of features and all are available on all supported platforms.

Announced Pricing is this:

Console Licenses $100 ($50 renewal)

Desktop $300 ($150 renewal)

DB Servers $300 ($150 renewal)

Web $400 ($200 renewal)

So what does this mean for those with existing Real Studio licenses?  Real Studio personal licenses automatically get a Xojo Desktop license.  Real Studio Professional get Desktop, Database, and Console licenses for Xojo.  Real Studio Web licenses get converted to Xojo Web and Database.

Real Studio Enterprise licenses now get what’s called Xojo Pro.  Xojo Pro gives you all licenses.  You get desktop, console, web, and database licenses.  It comes with Priority Support which means that Xojo Inc. will handle all Priority Support issues first and then everything else.  Pro licenses also work on three machines (in contrast to the two for other licenses).

Another feature for Xojo Pro is that it gives you guaranteed access to the beta’s.  The Real Studio beta list really had no restrictions.  You signed up and you got access.  They didn’t say this but I suspect this is in response to the many people on the beta list that never reported anything but generated a ton of useless chatter.  This will definitely cut down on that problem.

Some people have taken offense to this.  They are not going to be Xojo Pro users so they feel that they’ll be cut out of the beta list.  The wording in the keynote was very specific.  Xojo Pro gives you ‘guaranteed’ access to the beta list.  That does not mean that you can’t join the beta it just means that it’s up to their discretion.  Those that have contributed in the past will most likely be welcome.  Those that have not are probably out of luck.

Another advantage of getting a Xojo Pro license is access to a Xojo Pro Only forum.  They figure it will most likely be the full-time developers (such as BKeeney Software) that use it.  Honestly, I have a problem with this even though I will most likely have several Pro licenses.  I have been a top 10 poster in the Real Studio forums for many years and I just don’t see how this helps me, or the community.  It seems like it will introduce some stratification into the community where there is none now.  I can’t imagine having an issue that I wouldn’t ask the entire community about.  I could go on about this but it seems to me that it’s a marketing bullet-point to make Pro look better.  I think it’s a bad idea and probably won’t use it.

The final ‘advantage’ of the Pro license is that Feedback cases now get a 3x multiplier. Real Studio licenses are a little different.  I believe Personal licenses get no multiplier, Pro/Web gets 3x and I thought that Enterprise licenses now get a 5x multiplier.  So in this scenario everyone else gets no multiplier but Pro users are the only ones to get it.

The Feedback multiplier isn’t a huge change but it definitely favors the Pro license.  I like this but I have my doubts that it will change anything significant.  As a pro user I have needs that are not being met by Real Studio (and now Xojo) despite many years of blogging and generating feedback reports.  Instead they have consistently gone for marketing bullet-point solutions and solutions that make it easier to sell to beginner and hobbyist developers.

Don’t get me wrong.  The free licensing has the potential to introduce Xojo to a lot of people that would consider themselves hobbyist or part-time developers.  That’s a good thing.  But it’s the folks like me (the Pro’s) that spend serious cash.  I want and need features that a) make my development life easier or b) help make me money (usually in completing things faster).  Not a whole lot of those types of features have been introduced in the past five years.

What do you think about the new licensing and the Xojo Pro features?