Firestore async dataset methods in TMS WEB Core v1.7
In this last blog article of 4 blog posts, we introduce a last major new feature in the Google Firestore dataset, i.e. new async features. Before providing details about these new features, let’s first look at the classic VCL TClientDataSet, how it can work how it works and what the implications are of inherently asynchronous implementations for use with a REST API based communication between a client dataset and the Google Firestore backend. Classic VCL TClientDataSet operations The editing and navigation interface for a TClientDataSet is best provided by using data-aware controls such as TDBGrid, TDBNavigator and more. Still, many times you need to process some records in code according to specific business logic. When it comes to populating and modifying a TClientDataSet in classic VCL code, you would use code similar to the following code snippets. Inserting a record in the dataset ClientDataSet1.Insert; ClientDataSet1.FieldByName(‘Description’).AsString := ‘Call up a meeting with Sales group.’; ClientDataSet1.FieldByName(‘Status’).AsString := ‘New’; ClientDataSet1.Post; Modifying a record in the dataset ClientDataSet1.Edit; ClientDataSet1.FieldByName(‘Status’).AsString := ‘Done’; ClientDataSet1.Post; Deleting a record in the dataset Processing all the records in the dataset ClientDataSet1.First; while not ClientDataSet1.EOF do begin //do some processing based on one or more fields of the record ClientDataSet1.Next; end; Equivalents with Firestore? Question is, will the above code work in Firestore ClientDataSet too? Yes the above code will work as standalone. But the code that follows the above code will fail if it depends on the success of the database operation in the previous code. This is important to understand so let’s look at 2 examples of how the code that follows can fail in Firestore TClientDataSet. Failing code example 1 Consider the following variation of the last example: if not ClientDataSet1.Active then ClientDataSet1.Open; ClientDataSet1.First; while not ClientDataSet1.EOF do begin // do some processing based on one or more fields of the record .. ClientDataSet1.Next; end; This will fail on TClientDataSet1.First. Why? Because an open is an asynchronous operation that takes time to open the cloud database. There is no guarantee that the open will be complete by the time you reach the next statement. What will happen is unpredictable. In fact, this is true of all the ClientDataSets in TMS Web Core dealing with cloud databases. Failing code example 2 Consider another example where we want to first insert a record in a Firestore collection, then get the record’s id that Firestore generates and stuff it as a foreign key value in another dataset’s new record. // adding a new customer’s record Customers.Insert; Customers.FieldByName(‘FirstName’).AsString := ‘John’; … more data for the customer record as needed … Customers.Post; // getting the generated id from Firestore newid := Customers.FieldByName(‘id’).AsString; // adding the invoice for the customer Invoices.Insert; … more data for the invoice record as needed … // setting the foreign key value as the id generated earlier Invoices.FieldByName(‘customer_id’).AsString := newid; Invoices.Post; Do you see what will cause a problem here? Customers.Post is an async operation as it will add a new record in the Firestore collection. There is no guarantee that it will finish by the time you reacth the next statement that remembers the generated id in newid. To rescue with async Fortunately, we have a solution for the above coding problems in the new version of TWebFirestoreClientDataSet. They consist of the following methods that allow you […]
