Can Xodus Entity Stores share a transaction? - xodus

I can see it is possible to use a single Environment transaction to work on multiple stores. (I'm also assuming writes are possible too).
The high level api of Entity Stores is very convenient for me, but I could not find a way of sharing Entity Store transactions. Looking at the code, I can see entity stores are actually creating Environment transactions but since these are individual transactions I cannot perform operations across multiple stores and commit/abort a single transaction.
Am I missing something or should I say goodbye to Entity Store apis and fall back to Store API?

I was the one who initially asked that question to which you are referencing.
In Xodus there are three different ways to use it:
- Environments;
- Entity Stores;
- VFS.
I'm using Environments API and all Transactions are created for whole Environment. And as I understood correctly you are using Entity Stores API, so you are able to use only StroreTransaction which is started only for a particular Store and to manipulate its Entities.
So, if you require to share one transaction against multiple stores then you require to switch to Environment API.
Taras

If using Environments API you can access any data in the environment regardless of how many named stores are created in it. In the Environments API, Store is just a named key-value map.
PersistentEntityStore is created atop of Environment. Single physical (disk) location corresponds to both Environment and PersistentEntityStore. Transactions are created against Environment or PersistentEntityStore. No matter which API you use, transactions cannot be shared between instances of Environment and between instances of PersistentEntityStore.

Related

What is the best way to sync data among a small number of users in swift?

As the header indicates, I am looking for the simplest way to sync user-generated data (Integers, Booleans, NSDates, etc) among a small number of individuals (at this point, I am just thinking of sharing data between two people). Within the app, users can populate an array with instances of a custom object and this data is used to populate a UITableview. Assuming all users in the select group have synced their devices they should all see the same data in the tableview.
My original idea was to write to a json file in a shared Dropbox or Google Drive folder. After looking around online, however, I found that this method is likely to lead to data corruption. Cloudkit only allows public or private (single account) syncing, nothing in between. I have seen some posts that recommend using Parse, but that service is now on its way out.
Does anyone know of a (preferably free) way to do this?
You have several options:
CloudKit databases - CloudKit's database system has the concept of a public database which does exactly what you want. It's fairly easy to use as well, and is "free" with an Apple developer account. The only downside is that it's for Apple devices only (AFAIK).
Firebase - Google's Firebase is basically identical to CloudKit in concept and features, but runs on multiple platforms. It is tied to the Google ecosystem, so your uses all need to provide a Google account to use it, but that's a small issue these days.
Realm - from a pure usability perspective, Realm is BY FAR the easiest data storage solution I've seen on iOS. However, it's sharing functionality is currently limited, CloudKit support is scheduled but currently all there is is this. If you only need local storage for now, then definitely keep this on your list.
No matter which engine you choose, users would be limited to certain views of the data through your own code. I would suggest that you save every record with a username of the creator, and then have another table containing read/write permissions, so for instance, the entry for "maurymarkowitz" has "bobsmith,ronsmith,jonsmith". You can retrieve these entries on login and then use them as the inputs to the query-by-example both systems use for getting records.
Thanks for all of the helpful responses. I ended up using cloudkit/coredata and it serves my purpose just fine. I simply used the public option and gave each set of users who are sharing data with each other a unique identifier, which is appended to any records they upload. When a user syncs their data with the cloud the application performs a query for only those records that contain the user's identifier. This way, multiple users can sync data among themselves even though they do not share an iCloud account.

Rails communication with web services

I am developing a Rails web shop application and I have the following system set up:
2 separate web services (very simple Rails apps with the same code but different databases)
Main Rails application which stores information from both web services.
The main application gets some information from both web services (in JSON format) and has to choose items (based on price). For testing purposes I currently take all items from both and add them to the main application's database. However, when items are being stored in the main database (with a simple .create and a hash with all parameters it seems as if it's adding on item multiple times and thus it takes a very long time.
First, what is generally a good strategy for doing this type of thing - getting data from the web services and storing it? Also, at what point do I want to ask for an update of the main database? It seems too much if it is every time a user connects.
I assume there is a key value for id in the data... if not you should define one. Most likely an auto incrementing integer ID since this is tagged as rails. Although you'll probably want a UUID (perhaps SecureRandom.uuid) since the two data sources are independent of each other, which adds significant complexity in a rails app
In that case you could use #model = Model.find_or_create_by(key_value: value) to avoid duplicates being created, and #model.update_attributes (essentially use an update action) to only modify what has changed.

Best way to store and version lookup Entities in local storage

For my SPA I have a series of Lookup entities that are loading into my entity manager on page load for various pick lists and lookup values. What I'd like to do is store these entities in local storage and import them into my manager instead of requesting them over the network.
These lookups can be edited by 3 people in my company. What I'm trying to figure out is how to version these lookups in local storage so that the file can be updated when a lookup changes (or at least give the client-side capability for determining when the records stale to request new ones). How can I achieve this? My lookups are simply tables in my overall database, and I don't see a way for the client-side to recognize when the lookups have changed.
I'm reluctant to add a timestamp column because I would need to evaluate the entities in local storage and compare them to the ones on the database and get the ones needed. Not sure how I would save page load time there.
I'm considering moving all of my lookups into a separate database and version the whole thing, requesting new lookups when any one of them changes. I would need to write a mechanism for versioning this db whenever one of the 3 people makes an edit.
Has anyone found a better solution to a problem of this type? My lookups() function is cannibalizing the wait time on users' first access.
Consider maintaining a separate version file or web API endpoint.
Invalidate lookups by type or as a whole rather than individually.
Bump the version number(s) when anything changes. Stash version number with your local copy. Compare and reload as needed.

Core Data Sync With Multiple Users

I would like to sync a core data app with a user with a different iCloud ID and I am trying to figure out the most graceful way to do this. I do not want the data to sync with all users, but want to be able to sync among family members for instance. From the research I have done, I do not think I can do that using iCloud Core Data sync because it only syncs between devices with the same iCloud ID. I have looked at this stackoverflow answer and read a little bit about Ensembles, Parcelkit and TICoreDataSync, Parse etc., but it is not clear to me if any of those options will allow me to sync with multiple users. Does anyone have a good method for syncing a Core Data app with multiple users?
Ensembles and TiCoreDataSync might work. They can use Dropbox file syncing, so in principle they should work with Dropbox shared folders. I don't think these are the main intended uses, so I suggest contacting the developers and/or doing some good testing yourself before assuming this would actually work.
You'll need to think about the user experience, though. At a minimum, your users would both need Dropbox accounts and would have to set up a shared folder before beginning to sync data this way.
Parcelkit probably won't work. It uses Dropbox's data store API which, unlike other Dropbox services, doesn't appear to support shared data.
Services that do support this kind of sharing exist-- for example, Parse and Firebase-- but make sure to review their pricing carefully before using them. Also of course, there have been any number of projects that have their own custom server back end, but that obviously requires having someone on the team who can do that kind of work.
You need to think about other device types (Android at least) if you want your application to be reaching more users.
I'm doing the same now by the following way:
Setup an online database with proper web services (careful with implementation for security matters - DB should NEVER be exposed by anything other than the web services).
Create a Class for your communication with the server (using Class methods with security handling like authentication and authorisation).
Use the class in your app to communicate with the server (SQL operations are done on the server).
To integrate with CoreData you need to create the model in your app similar to the structure in the backend database. Then you need to create a similar class for the app that deals with only local CoreData.
A higher level class might be required if you want to make sure that operations done on both server and local data storage.
Besides, you have to implement a lot of conditions to make sure that data written in local ONLY after making sure that it is stored online (or create an engine for differed operations to run later).
Another Way if you are familiar with notifications:
Use structured notifications between devices for data operations in order to keep everything in sync with other users. The problem with this is the "Autonomy" of the operations. If two operations were done in approximately the same time, you have to find a way to make sure the order of the operations is done properly (maybe timestamp or something).
I'm looking into the same thing for my app and I 'think' you can do a fairly unsecured version of what you are after using using the public folder in cloud kit as mentioned in this question (no accepted answer at time of posting) : Private data sharing using CloudKit
You would need to find a way to differentiate between data that is truly public and those shared among the users you need and some level of authentication.
I'm going to try exporting a permission file with access permission in it to whomever I want to share with combined with a unique identifier located in that permission file.
Keep in mind, as mentioned in the comments of the linked answer, my implementation will be security by obscurity (thanks for that phrase) unless you find a way of adding proper validation to it but my data is relatively insensitive.
Hope this, or any ridicule in the comments, points you in the right direction : )

One way sync with Core Data

I am about to build an internal-only iOS app for storing simple business data. The data store will consist of a single entity only, with one entry per day. To start with there will be around two years worth of data (~750 entries).
I want to set the app up to do one-way syncing only. i.e. Only one person can enter data, but others can read it. iCloud is out as it only works for a single user account.
Is there a lightweight way to sync this datastore out from the single write user to the other read users? Setting up a full sync system seems overkill for this case.
Instead of iCloud, you could use one of the online backends such as Parse.com or Simperium. They would allow you to share data using a db and also provide for user accounts, authentication etc. If you want to run the server locally you can investigate DataKit.

Resources