I'm writing a site on GAE-Java + Objectify which lets users create their own pages, with unique URL. I haven't been able to figure out a clear way to ensure that when two users try to claim the same url at the same time, only one user gets it.
This is what I'm trying to avoid:
User 1 does a check - its available
User 2 does a check - its available
Meanwhile, User 1 creates page and stores it.
User 2 creates a page and overwrites User 1.
Any ideas on how to solve this on GAE?
Why not just run your code in a transaction? I don't see where the issue is. Do you have a sample of something you've tried and had problems with?
Found a clearer explanation in the python docs:
Attempts to get the entity of the model's kind with the given key name. If it exists, get_or_insert() simply returns it. If it doesn't exist, a new entity with the given kind, name, and parameters in kwds is created, stored, and returned.
The get and subsequent (possible) put are wrapped in a transaction to ensure atomicity. Ths means that get_or_insert() will never overwrite an existing entity, and will insert a new entity if and only if no entity with the given kind and name exists.
In other words, get_or_insert() is equivalent to this Python code:
def txn():
entity = MyModel.get_by_key_name(key_name, parent=kwds.get('parent'))
if entity is None:
entity = MyModel(key_name=key_name, **kwds)
entity.put()
return entity
return db.run_in_transaction(txn)
Related
I have an app, in which a user can create a session for themselves. By a session I mean , it has a title and a frequency (For Example - {"title": "homework" , "frequency": "MWF"} where MWF is Monday,Wednesday,Friday). I want to store the session frequency and title in my firestore database in such a way that when the user creates a new session, i fetch from firestore the possible clashes -
For example - if the user is creating a session called "homework" and an "homework" already exists then , I can tell them that a session by that name already exists OR If a user is creating a session with frequency" MTS and already has a session with the frequency MWF, then I have to tell the user that there is a possible clash. Same with creating TTF and MWF already exists, then I have to inform the user of a possible clash.
My question, is that how can i do it, given the fact that I use the firestore database?
The easiest thing to do is simply query for any documents that would conflict before you allow the user to add the conflicting document. So, if you want to find a conflict where title="homework", you would query for conflicts first:
firestore.collection("your-collection").where("title", "==", "homework")
// then check the results to see if there was a match
Firestore doesn't provide a way to stop duplicate field values in a collection, so it's still possible that somehow a user could add a conflicting document. If you need to force uniqueness of a field value within a collection, that requires much more work, which might not be worthwhile for your case.
I'm creating a React application where my data has the following structure:
interface BookCase {
id: number;
bookShelves: BookShelf[];
}
interface BookShelf {
id: number;
}
Every bookcase and every bookshelf has an id property. I use this for the key attribute and for locating a bookshelf inside the bookShelves array. The id is generated in the backend by the database (With a BigSerial in PostgreSQL) on save.
I now want to create a new bookcase inside my frontend without immediately saving it to the backend. First I want to work with it, perform some operations on it (e.g. place a book on the shelf), and afterwards send the whole batch of changes with the new entities to the backend where it will then be persisted in the database.
Of course I do not yet have an id, although I need one to work on the bookcases. Should I rewrite my application to also accept null for id (I would prefer not to)? Should I just randomly create an temporary id, possibly having duplicates with the ids already present in the database (or for example use a negative value like -1)? Then I would need to replace all the ids afterwards after it has been saved to the database.
With UUIDs I could generate it on the frontend, but I guess there also has to be a common pattern to work with just incrementing integers as the id.
I do not think there is a clear answer here.
Essentially you have a object-relational mapping and there are various ways to handle it. Entity Framework for example just uses the default for the data type. So if the entity does not exist yet the ID will be 0 and any persisted entities have values starting at 1 so there are no conflicts.
One way i usually handle saving is by returning the updated record from the request, so you just replace your old one with that and you have the correct ID value applied automatically.
In our web application we want to use DB2 row level access control to control who can view what. Each table would contain a column named userId which contain the user id. We want log-in users be able to see only row's usereId column with theirs id. I have seen db2 permission examples using DB2 session_id or user, for example taking DB2 given Banking example :
CREATE PERMISSION EXAMPLEBANKING.IN_TELLER_ROW_ACCESS
ON EXAMPLEBANKING.CUSTOMER FOR ROWS WHERE BRANCH in (
SELECT HOME_BRANCH FROM EXAMPLEBANKING.INTERNAL_INFO WHERE EMP_ID = SESSION_USER
)
ENFORCED FOR ALL ACCESS
ENABLE;
Our table gets updated dynamically hence we don't know what row get added or deleted hence we don't know what are all the user Id in the table.
At any given time, different user would log-on to the web to view information retrieve from the tables, the permission declaration above only take SESSION_USER as the input, can I change it to something like Java function parameter where one can pass arbitrary id to the permission? If not then how do I handle different log-in users at arbitrary time? Or do I just keep changing SESSION_USER dynamically as new user login (using "db2 set" ??)? If so then is this the best practice for this kind use case?
Thanks in advance.
Since the user ID in question is application-provided, not originating from the database, using SESSION_USER, which equals to the DB2 authorization ID, would not be appropriate. Instead you might use the CLIENT_USERID variable, as described here.
This might become a little tricky if you use connection pooling in your application, as the variable must be set each time after obtaining a connection from the pool and reset before returning it to the pool.
Check out Trusted Contexts, this is exactly why they exist. The linked article is fairly old (you can use trusted contexts with PHP, ruby, etc. now).
I have a custom object in Salesforce which I need to setup a Master Detail relationship from Accounts. Accounts being the Master and CompHist being the Detail. The problem I am running into is that I need to set the relation to work off of custom fields within the objects. Example:
1.) Accounts has a custom field called CustomerId.
2.) CompHist also has custom field called CustomerId.
3.) I need to be able to have this linked together by CustomerId field for report generation.
About 2,000 records are inserted into CompHist around the 8th of each month. This is done from a .NET application that kicks off at the scheduled time, collects info from our databases and then uploads that data to salesforce via the SOAP API.
Maybe I'm misunderstanding how Salesforce relationships work as I am fairly new (couple months) to salesforce development.
Thanks,
Randy
There is a way to get this to work without triggers that will link the records or pre-querying the SF to learn Account Ids in .NET before you'll push the CompHistories.
Setup
On Account: set the "External ID" checkbox on your CustomerId field. I'd recommend setting "Unique" too.
On CompHist: you'll need to make decision whether it's acceptable to move them around or when the relation to Account is set - it'll stay like that forever. When you've made that decision tick / untick the "reparentable master-detail" in the definition of your lookup / m-d to Account.
And if you have some Id on these details, something like "line item number" - consider making an Ext. Id. for them too. Might save your bacon some time in future when end user questions the report or you'll have to make some kind of "flush" and push all lines from .NET (will help you figure out what's to insert, what's to update).
At this point it's useful to think how are you going to fill the missing data (all the nulls in the Ext. Id) field.
Actual establishing of the relationship
If you have the external ids set it's pretty easy to tell salesforce to figure out the linking for you. The operation is called upsert (mix between update and insert) and can be used in 2 flavours.
"Basic" upsert is for create/update solving; means "dear Salesforce, please save this CompHist record with MyId=1234. I don't know what's the Id in your database and frankly I don't care, go figure this out will ya?"
If there was no such record - 1 will be created.
If there was exactly 1 match - it will be updated.
If there were more than 1 found - SF won't know which one to update and throw error back at you (that's why marking as "unique" is a good idea. There's a chance you'll spot errors sooner).
"Advanced" upsert is for maintaining foreign keys, establishing lookups. "Dear SF, please hook this CompHist up to Account which is marked as "ABZ123" in my DB. Did I mention I don't care about your Ids and I can't be bothered to query your database first prior to me uploading my stuff?"
Again - exact match - works as expected.
0 or 2 Accounts with same ext. id value = error.
Code plz
I'd recommend you to play with Data Loader or similar tool first to get a grasp. of what exactly happens, how to map fields and how to not be confused (these 2 flavours of upsert can be used at same time). Once you'll manage to push the changes the way you want you can modify your integration a bit.
SOAP API upsert: http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_upsert.htm (C# example at the bottom)
REST API: http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_upsert.htm
If you'd prefer an Salesforce Apex example: Can I insert deserialized JSON SObjects from another Salesforce org into my org?
I'm currently creating my first real life project in Pervasive. The task is to map a certain XML structure containing orders (as in shops and products) to 3 tables I created myself. These tables rest inside a MS-SQL-Server instance.
All of the tables have a unique key called "id", an automatically incremented column. I've dropped this column from all mappings so that Pervasive will not try to fill it itself.
For certain calculations, for a split key in one of the tables and for references to the created records in other tables, I will need the id that the database has just created. For that, I have googled the answer. I can use "select ##identity;" as a statement, and this returns the id that has most recently been created for the current connection. This means that in Pervasive, I will have to execute this statement using the already existing target connection object.
But how to do that? I am quite sure that I will need a JDImport or DJExport object, but how to get one associated with the current connection that Pervasive inserts the records by?
Or is there any other way to handle this auto increment when I need to reference the id in other tables?
Not sure how things work in Pervasive, but you may run into issues with ##identity,. Scope_identity() would probably be safer but may still not work in Pervasive.
Hopefully your tables have a natural key in addition to the generated id, in which case you can select your id based on the natural key. This will avoid any issues you may have with disparate sessions and scope.
If there is anyone looking this post up and wonders about the answer, it's "You can't". Pervasive does not allow access to their very own connection object, the one they use to query the database. Without access to it, you cannot guaranteed fetch the right id. The solution for us was this: We used a stored procedure which we called in the Before-Transformation event that created the header record and returned the id and an optional error message as a table. We executed it and it returns the id we then save and use throughout our mapping.