Changes in sqlite file when creating new version of App - iphone

i have a sqlite file in my app. the app is with enterprise certificate .
Now , if i am going to create new version with the changes in database then :
1) i have to change my Sqlite file name ?
2) if yes , then is there any way that if any person who is using my app, who has his saved data in app , will be inserted automatically in new version of my app .
otherwise if i create new file and then the older data would be removed!!!
Thanks in advance..

1) AFAIK, when you update, the old app bundle is replaced with the new app bundle. But the user data is untouched. i.e. the copy of the sqlite DB which the app changes with use by the user, is not deleted/replaced.
2) So, you can possibly ship changes to the DB as queries:
a) New tables go in as CREATE TABLE queries.
b) Changes to table structure go in as ALTER TABLE queries.
3) Now, one problem is, you didn't think about all this when you shipped the older version. So how will you make sure the queries 2a and 2b are executed only on upgrade?
a) When you first get control in the application, before allowing user interaction, fire a dummy SELECT SINGLE * FROM <tablename> on a table you have 'changed' in new version.
b) Use sqlite3_column_count and sqlite3_column_name to find out which version of the app the DB corresponds to [old or new].
c) If it is new version (i.e. new columns already exist), do nothing, else fire the queries I mentioned earlier as 2a and 2b.

If you haven't started by using this, then it's probably moot, but Core Data handles migrations (IMHO) fairly well; enough that it's worth the hurdle of learning the API. We've had great success with it (including complex migrations, inserting new objects "between" relationships, etc).

Related

Keeping database table clean using Entity Framework

I am using Entity Framework and I have a table that I use to record some events that gets generated by a 3rd party. These events are valid for 3 days. So I like to clean out any events that is older than 3 days to keep my database table leaner. Is there anyway I can do this? Some approach that won't cause any performance issue during clean up.
To do the mentioned above there are some options :
1) Define stored procedure mapped to your EF . And you can use Quarts Trigger to execute this method using timely manner.
https://www.quartz-scheduler.net
2) SQL Server Agent job which runs every day at the least peak time and remove your rows.
https://learn.microsoft.com/en-us/sql/ssms/agent/schedule-a-job?view=sql-server-2017
If only the method required for cleaning purpose nothing else i recommend you go with option 2
first of all. Make sure the 3rd party write a timestamp on every record, in that way you will be able to track how old the record is.
then. Create a script that deletes all record that are older than 3 days.
DELETE FROM yourTable WHERE DATEDIFF(day,getdate(),thatColumn) < -3
now create a scheduled task in SQL management Studio:
In SQL Management Studio, navigate to the server, then expand the SQL Server Agent item, and finally the Jobs folder to view, edit, add scheduled jobs.
set script to run once every day or whatever please you :)

breezejs update cache with changes from server

I am using breezejs in a offline first manner, executing query’s initially against a server and stashing the entities in local storage where I query the entity manager cache.
When data changes on the server (by means of another app changing it using breeze) the client app synchronizes by just getting a new copy of the entities from the server.
This works great but I am wondering if there is a way that I can get only the changes from the server, I was thinking maybe set a revision GUID or timestamp on each record and then checking the metadata if it needs updating but I really have no idea on how to proceed.
So my question is can breeze be tweaked to allow for such a use case?
And is there maybe a beter way that I am overlooking?
I think your direction is correct .If you had a column with a TimeDate in every table e.g "LastModified" and that column would get updated on every record update. then you could add a filter to every breeze query after the first that says that that date must be later than the last time you did this "rebase" query or the initial loading. so It's not supported out of the box, but you can get it to work yourself. the guid per version will not really be a good idea, as you will have to send all these guids on every request, and then check all of them. time stamp makes more sense.

Managing database changes

I'm starting to move more logic into the database, using triggers, views, functions, CTEs, etc. When plv8/json comes out for postgres, I can see myself putting lots of logic in there.
I'm having problems with the "standard" way of doing database migrations in sequel and activerecord. Both sequel and activerecord let you put arbitrary sql code into timestamped files. When each file is ran, a schema_versions table is updated with the filename (or timestamp in the filename), which keeps record of which migrations have been applied to the current database.
If a lot of coding is being done at the database level, that means that modifications to existing views, functions, etc follow the below pattern:
Migration 1 defines a function and a view that uses that function.
-- Migration 1
create function calculate(x int) returns int as $$
return x + 1;
$$ language sql;
create view foos as (
select something, calculate(something) from a_table
);
Requirements change, and I need to change a function type. In Migration 2 I have to drop all objects that depend on foo, and recreate them by copying their entire body -- even if there weren't any changes in most of the other code!
-- Migration 2
-- Have to drop all views and functions that depend on the
-- `calculate(int)` function.
drop view foos;
create or replace calculate(x bigint) returns bigint as $$
return x + 1;
$$ language sql;
-- I could do `drop function calculate(int) cascade`,
-- but I might accidentally drop some objects that wouldn't get recreated below.
-- Now I have to recreate foo.
create view foos as (
select something, calculate(something) from a_table
);
If I'm building a system based on views and functions and triggers, my migrations would be filled with duplicated code, and it's difficult to find the latest version of the code. You might say "don't do that!", but for my purposes (e-commerce, shipping, transactions), I'm finding it's a lot easier and faster to have the database ensure the integrity of the data by doing the logic inside the database.
You can (of course) dump the current database schema (which includes all the code definitions), but I think you lose comments. And you wouldn't generally want to edit a giant file that contains the whole schema.
Any ideas on how to solve this problem?
My best idea is to how the sql code contained in their own canonical files (app/sql/orders/shipping.sql, app/sql/orders/creation.sql, etc). Everyone develops directly on these. Whenever it's time for a release, then you'd want to make a new migration file, look at all the changed code since the previous release, figure out the dependency chain of the database objects that need to be dropped and recreated, and then copy the sql from the canonical sql files into a new sequel/activerecord migration file. But it's a pain. :/
Thoughts are very welcome. I hope I explained this well enough, I'm cutting back on my caffeine intake and I'm a little groggy atm.
Oh, I asked a similar question on Stack Overflow: Changing the type of a column used in other views The answer was a function that let me pass in:
sql code to run
database views to drop and recreate
The function would retrieve the view definition, drop the views, run the sql code, then recreate the view definition (in reverse order of dropping). Perhaps a system of functions like this would help solve the problem of having to copy/paste sql code into the migration files.
I'd recommend liquibase.
You create files which track the changes to your database and these will be run into the database in the correct migration order.
You might find Dave Wheeler's blog-posts interesting starting from here:
http://justatheory.com/computers/databases/simple-sql-change-management.html
My rate of database change is fairly small but I tend to be careless and make small changes to the schema directly, so I've had to come up with a fair bit of infrastructure to catch when I've done so. The basic elements are:
A makefile that can rebuild a development database from scratch
A set of schema-files separated into "modules" (lookups_schema.sql, lookup_data.sql)
A set of update files that transition from one revision to the next
I don't usually have the corresponding downgrade scripts, some people do
A script to populate my database with a plausible amount of test data
Crucially, a test suite via pgTAP that checks my various functions, views and also the upgrade scripts. The upgrade tests can be run against a live database too.
If you have a separate instance of PostgreSQL set up with fsync turned off / on ramdisk etc then rebuilding the whole DB and populating it can take seconds (if you don't have too much test data).
Start with #1, #2, then add #6 (pgTAP is very cool), then the rest. The crucial thing is a test suite that checks your in-database code.
There are tools that try to automate schema changes for you, but they are really only good at adding a new column to a table and that sort of thing. Once you have code in your db then they're not much help.

iOS - Create Database Schema (Run code only once)

I'm using FMDB for my iPhone App database and i want to create the database and tables schema only once.
How can i run OBJC code when the user installs or updates the app?
Kinds Regards
You can set a boolean value in NSUserDefaults - NSUserDefaults is only reset when the user deletes the app, so you have some code that executes if a particular boolean value is not found in the user defaults (and then saves that value after execution to prevent it from being run again).
That will cover your plain 'run code once upon install' scenario - you can achieve the same for updates with a similar approach, but utilising the CFBundleVersion variable (which will be different for each version of your app).
First of all, you might not want to think about executing something during upgrading, because it's not possible. Like #lxt suggested, you can store a value in the preference to indicate database version, but it might not be bulletproof.
A common approach to solve this problem is to use self-built meta-data. When you first created the database, you should create an extra table named "metadata" or "properties", with two varchar columns, "name" and "value". You insert one row, ("database_ver", "1").
In your database layer (or adapter) class, you create an "open" method to handle opening. Within this method, you first run select database_ver from metadata; to check database version. If nothing is fetched, you run table creation scripts, and insert database_ver=1 row.
Later on if you upgraded your table format, provide alter table statements for each version, and run them based on database_ver. For installations after the upgrade, you can use the updated create table statements, then set "database_ver" to "2" (or above) directly, without going through alter table.
Compared to storing value in the preference, it's actually more common to store it in the database itself. Because even if the user backed up the file somewhere, or skipped a version, you can still tell the format of the database by its metadata table.
FMDB has no problem running such mechanism.

Appending Dataset in Core Data execution of Update through iTuneStore

This one Also Resolved by myself.
Good answer would be,
New Edition App: make change the sqlite file name. check file exist, get the old edition app sqlite name value then remove, and add into that folder.
this is the best answer.
*New efficient answer
STEP 1: select .xcdatamodel file
STEP 2: Xcode -> Design -> Data Model -> Add Model Version
STEP 3: Manipulate new changes
For more detail about migrate or re-organize data model structure, visit Apple <here>
Although I didn't quiet sure how to add model version before reading Apple's document, My old way is still works.
Old resolved self answer
Example from 'Reciepe' given by apple, it don't replace the file if it is there already.
However, if your code need to update and get rid of old .SQL file then the explicit condition needed for check the old file sqlite name deleting function required for update.
Basic sequence would be,
CHECK 1: check if old file exist.
CHECK 2: if it does, remove it.
CHECK 3: then copy new one.
CHECK 4: if the old file don't exist,
CHECK 5: (if the new file don't exist),
CHECK 6: copy new file into that folder.
CHECK 7: if new file exist do nothing.
solved.
Original Posted Question
So I have completed my code work.
This is first time releasing the app through iTuneStore.
Current state of reading Core Data (.sqlite) file is already prefetched (already has information like apple's 'Reciepie' program).
Assuming I have successfully released through apple store, and decide to update my application to existing users.
Say I have sqlite contents but it contains bit more information than previous SQLite file under same structure.
Question 1. Every time update held to the existing user, does it removes previous ones and move new updated application?
Question 2. if it is not, then HOW can I append the existing sql value?
If you do not change the underlying data model, then the answers are:
1) updating from, say v1.0 to v1.1 does not remove the previous contents already stored and managed by Core Data.
2) Simply check the version of your application using the main bundle, and, if the version retrieved needs additional data to be inserted, do the insert. You can do the check and the insertion in
- (void)applicationDidFinishLaunching:(UIApplication *)application;