How to know if the CloudKit Zone exists already - cloudkit

To add a CKRecord in a private CKRecordZone you need to make sure the zone exists already.
But does it mean that every time I need to insert a record I need to fetch all the zones and find if my zone exists using fetchAllRecordZonesWithCompletionHandler ? It wouldn't be very efficient.
What is the best strategy to adopt ?
Most of the examples I have seen show how to create a zone and add a record into it. But you are not going to create the zone every time, and you can't just assume it exists...
Code below will fail if the zone has not been created already
let customZone = CKRecordZone(zoneName: self.zoneName!)
// Create a CKRecord
let lessonRecord = CKRecord(recordType: self.recordType, zoneID: customZone.zoneID)
Thanks for your help.

To see if a specific zone exists, use CKFetchRecordZonesOperation and pass just the one record zone ID.
You only need to do this once if your code is setup properly.
Create a class that represents a record zone. This class should perform all of the CloudKit operations for a given zone. When you initialize an instance of this class for a specific zone, you can check to see if the zone exists. If not, then create the zone. Then you use that specific instance of this zone helper class each time you need to read or write data to that zone.
Of course every read and write operation needs to check error results to check for CKErrorZoneNotFound errors. Getting such an error probably means the zone was deleted from another copy of the app.

Related

How to reset an auto-incremented value when another value changes?

I'm actually working on a PostgreSQL DB structure and I'm having hard time figuring out how to solve a problem.
The DB will be recording data regarding architectural objects.
The main table, "object",have attributes that describe the object with information like type, localization, etc.
One of these attributes is a serial named object_num.
Another table is called "code" which contains a code made of three letters corresponding to the town where the mission is conducted.
Example :
I'm working on an architectural inventory for the city of Paris. The code_name will be PRS and the first entry (aka the first architectural entity : house, bridge, etc) will be associated to object_num 001.
So PRS001 will be a unique identifier referring to this specific architectural entity.
Things going on, I might end up with quite a few entries, for example entry PRS745.
Say this mission isn't finished yet but a new one starts for the city of Bordeaux, where BDX is going to identify the inventory. It would be great that the identifier for the first entry will be BDX001 rather than BDX746 (auto-increment).
Considering this, it will be also nice that, going back to the Paris mission after a few records for the Bordeaux mission (say BDX211), the next value will start back at (PRS)745 rather than (BDX)211.
So, is it possible to reset the value of a serial to 1 when using a new code ?
And is it possible to start back serial increment from the last value of a specific code ?
I guess you can perform this task with constraints and checks, but I'm not really familiar with these and am a bit lost...
Thanks for your help,
Yrkoutsk
You could create separate sequences for each code_name and grab your auo-increment based on the code_name:
CREATE SEQUENCE PRS START 1;
CREATE SEQUENCE BDX START 1;
insert into your_table (object_num, code_name, other_data)
values ( code_name||lpad(nextval(code_name)::char,3,'0')
, code_name, other_data);
You will have to create a new sequence every time you add a new code_name otherwise the db will end up throwing an error when you try accessing the nonexistent sequence.

grails 3.3.x java.sql.Date property is type-mismatched

In my domain class, I have something like this:
class User {
String name
java.sql.Date birthDate
}
I am getting the app working with scaffolding, and the scaffolded creation pages correctly show the d/m/y drop down date picker to specify the date, which is very good.
But when I hit the "Create" button, it gives:
Property birthDate is type-mismatched"
I am using the built in H2 DB currently, but will switch to MySQL later.
Any suggestions? I don't want to use the normal date/time as I only need the date, and it must not be affected by time zones. Obviously I could manually store the day, month and year fields separately, but this makes it harder to use later (e.g. for comparison).
We had a trick to get this working with Grails 2.x, but I don't have a copy of this old code.
Does anyone have a workaround for getting this working with the fields plugins?
In my update controller method, even if I manually set user.birthDate to a correct java.sql.Date instance, calling user.save() still fails with the type-missmatch error. It seems to be something in the save() method, which is presumably GORM code.

set timezone in pg-promise only once per client

I have a timestamp with timezone column in postgressql, named created , that the data are saved in UTC.
I am using pg-promise 8.4.4 and I want to select the data, but set a different timezone for every client.
The logic is that my angular app uses the node.js endpoints as an api and I guess I can set the timezone while creating a DB connection, but that would be good just for my app.
What if another app, from another timezone, wants to hit the same node endpoint? How can they set the timezone?
So, in SQL I can do something like
set timezone to 'europe/athens';
select created from table;
But, how do I do this in pg-promise, for different clients?
I could do something like
cmsuser.generalQuery(`select firstname, created AT TIME ZONE '+02' from table WHERE AND activated = $1 ORDER BY created`, [true])
.then((resolved)=>{
res.json({success:true, activated:resolved});
})
and make the +02 part dynamic?
The cmsuser.generalQuery is
const generalQuery = (text, params) => {
const s = pgp.as.format(text, params);
return db.any(s)
}
There are two problems with this approach right now
-1- With the above query, without having the timezone part as dynamic, I get the firstname, but not the created, that is the date. No errors in the console.
-2- Setting the timezone per query is not a smart thing to do.
What can I do here?
Thank you

How to have SQL and database createdAt dates match exactly?

I have an app which includes a functionality which allows users to send messages to one another. The process for sending the message involves saving the sent message to the sender's internal SQL database while at the same time saving the message to the overall app's database, which is a parse-server (and then actually send the message via push notifications to the recipient). What I am concerned about is with the discrepancy that is bound to arise between the 'createdAt' parameter for the message in the database and the same parameter for that message in the SQL database. The reason for the perceived discrepancy is because I have it set up as follows:
import Parse
func sendMessage(){
let newMessage = newMessage(messageString: "Hi", createdAt: Date())
//drop the newMessage into the SQL table... will save the Date() as a String at time A
let newMessageToDB = PFObject(className: "messages")
newMessageToDB["messageString"] = newMessage.messageString
//parse-server will automatically give the object a "createdAt" parameter when saved
newMessageToDB.saveInBackground()
//Since this is created automatically, the value will be the exact moment
//the object is saved to the DB, at time B
}
Since the createdAt value for SQL is created by Date(), this value is set at time A. The createdAt for the database is created by the completion of the async function saveInBackground() and will therefore be saved at time B. With this method, I can in no way guarantee that time A = time B. This creates the problem that for the recipient the time of the message will be time B from the database (which will be put into their SQL table with time B), while, for the sender, the time of the message will be time A.
My question:
1. First and foremost, does this discrepancy even matter? The entire explanation of the problem might be irrelevant if this difference doesn't actually create any issues.
2. If it is relevant and may cause issues, how do I fix it? I know I can send it to the server, and then read the value back immediately after it is created to get the database's 'createdAt' to be saved in the SQL statement, but is that inefficient? To save an object, then immediately read it back from the DB to extract a value?

Diffrence between "Created On" and "Record Created On"

In CRM, when I'm, trying to set up a work flow, I get to choose the timeout to be related to a certain entity's creation time. There are three fields to relate to.
Record Created On
Created On
Modified On
While the last one is very obvious, I can't see any logical difference between the two others.
The difference is that Created On (createdon) is filled out automatcally by the server when you actually create the record, while Record Created On (overriddencreatedon) will usually be null (unless the record was imported into CRM and you chose to explicitly override the record creation date to match when it was created in another system).
You should use the first and skip the latter, as it's not supported (as far I've got it right when I talked to a MVP about it). Why it show, she had no idea and neither do I. Maybe #JamesWood has a shot. He usually does. (sucking-up in progress)
I've never used the latter and I believe you'll keep your hair off-grey and on-head if you stick to the same approach.
From the SDK:
The createdon attribute specifies the date and time that the record was created. To import data in the createdon attribute, map the source column that contains this data to the overriddencreatedon attribute.
During import, the record’s createdon attribute is updated with the value that was mapped to the overriddencreatedon attribute and the overriddencreatedon attribute is set to the date and time that the data was imported.
If no source value is mapped to the overriddencreatedon attribute, the createdon attribute is set to the date and time that the data was imported and the overriddencreatedon attribute is not set to any value.
Link to BlogSpot
Link to Social MSDN