Good day. There are two classes: the class contract - ClassContract and the class where it is created, opens the database class - ClassDBHeler. I use a ready-made database, which I put in the assets folder of the project and when the user installs the application, the database is copied to it and he uses the application.

Here is the class ClassContract

public class ClassContract { private ClassContract() { }; public static final class ClassEntry implements BaseColumns { public final static String TABLE_NAME = "table1"; public final static String _ID = BaseColumns._ID; public final static String COLUMN_WORD = "field1"; public final static String COLUMN_TRANSLATION = "field2"; public final static String COLUMN_TYPE = "field3"; public final static String COLUMN_FAVORITES = "field4"; } } 

Here is the class ClassDBHeler

 public class ClassDBHeler extends SQLiteOpenHelper { private static String DB_PATH = "/data/data/ru.mysite.project1/databases/"; private static final String DATABASE_NAME = "dbase.db"; private static final int DATABASE_VERSION = 1; public SQLiteDatabase database; private Context myContext; public ClassDBHeler(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.myContext = context; } public void createDataBase() throws IOException { boolean dbExist = checkDataBase(); if(dbExist){ }else{ this.getReadableDatabase(); try { copyDataBase(); } catch (IOException e) { throw new Error("Error copying database"); } } } private boolean checkDataBase(){ SQLiteDatabase checkDB = null; try { String myPath = DB_PATH + DATABASE_NAME; checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } catch(SQLiteException e){ } if(checkDB != null){ checkDB.close(); } return checkDB != null ? true : false; } private void copyDataBase() throws IOException{ InputStream myInput = myContext.getAssets().open(DATABASE_NAME); String outFileName = DB_PATH + DATABASE_NAME; OutputStream myOutput = new FileOutputStream(outFileName); byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer))>0){ myOutput.write(buffer, 0, length); } myOutput.flush(); myOutput.close(); myInput.close(); } public void openDataBase() throws SQLException { String myPath = DB_PATH + DATABASE_NAME; database = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } @Override public synchronized void close() { if(database != null) database.close(); super.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } 

I updated the database and I want these updates to occur in users. In the onUpgrade method, how can I access the database that users already have? How do I understand the db parameter in onUpgrade is a new database, and how to access the table from the old database?

    1 answer 1

    db is an existing base. On the phone so far there is only 1 version. in SQLite, you cannot just delete a column, you have to create a temporary table, transfer data there, delete the original, create it again with the necessary structure, dump data from the temporary table into it and delete the temporary table.

    See, your application has been updated. And now, at startup, it will try to connect to the database version 2, but it will see that the existing version = 1 and call the onUpgrade method, giving you the opportunity to make the necessary changes to the database structure.

    And what will happen if the user puts a new application on a fresh smartphone for the first time?

    In this case, the application will also try to connect to the database version 2. But since the application is just installed, the database does not exist yet. The application creates a database and assigns version 2 to it, since It can work with this version. At creation, the onCreate method in DBHelper will be called.

    Here is an example of the update from the lessons.

     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.d(LOG_TAG, " --- onUpgrade database from " + oldVersion + " to " + newVersion + " version --- "); if (oldVersion == 1 && newVersion == 2) { ContentValues cv = new ContentValues(); // данные для таблицы должностей int[] position_id = { 1, 2, 3, 4 }; String[] position_name = { "Директор", "Программер", "Бухгалтер", "Охранник" }; int[] position_salary = { 15000, 13000, 10000, 8000 }; db.beginTransaction(); try { // создаем таблицу должностей db.execSQL("create table position (" + "id integer primary key," + "name text, salary integer);"); // заполняем ее for (int i = 0; i < position_id.length; i++) { cv.clear(); cv.put("id", position_id[i]); cv.put("name", position_name[i]); cv.put("salary", position_salary[i]); db.insert("position", null, cv); } db.execSQL("alter table people add column posid integer;"); for (int i = 0; i < position_id.length; i++) { cv.clear(); cv.put("posid", position_id[i]); db.update("people", cv, "position = ?", new String[] { position_name[i] }); } db.execSQL("create temporary table people_tmp (" + "id integer, name text, position text, posid integer);"); db.execSQL("insert into people_tmp select id, name, position, posid from people;"); db.execSQL("drop table people;"); db.execSQL("create table people (" + "id integer primary key autoincrement," + "name text, posid integer);"); db.execSQL("insert into people select id, name, posid from people_tmp;"); db.execSQL("drop table people_tmp;"); db.setTransactionSuccessful(); } finally { db.endTransaction(); } } } 
    • I read this lesson. But I can not understand one thing. If, in the onUpgrade () method, db is an existing database that the user has, then how to access the database of the new version? I need to do the following. leave the records from the user database as is, but add new records to them from the new version of the database. And I need to somehow address the new version of the database and the old version of the database. How it's done? - Michael
    • You cannot access the new version, it does not exist yet. It will appear only after the onUpgrade method works, which will update the old database to the new one. And in this method, you will write down what you need to do in order to get a new base out of the old one. - Andrew Grow
    • This is the problem that I don’t know what to write in this method, so that the old entries of users do not change and add new ones (( - Mikhail
    • Is there any method that is called before onUpgrade? To save data from the old version of the database? - Michael
    • I found the onConfigure () method through it, before I could call onUpgrade (), pull the data into the cursor. But the documentation says that it should be used only to configure connection settings, etc. If to get to the cursor data from the old database use nothing terrible? - Michael