Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ android {
minSdkVersion 21
compileSdk 34
targetSdkVersion 34
versionCode 101
versionName "2.1.0"
versionCode 102
versionName "2.1.1"
}

applicationVariants.configureEach { variant ->
Expand Down
134 changes: 134 additions & 0 deletions app/schemas/org.secuso.privacyfriendlynotes.room.NoteDatabase/6.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{
"formatVersion": 1,
"database": {
"version": 6,
"identityHash": "dfaa34068d0a54f9cf797b7c441c2d92",
"entities": [
{
"tableName": "notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `content` TEXT NOT NULL, `type` INTEGER NOT NULL, `category` INTEGER NOT NULL, `in_trash` INTEGER NOT NULL, `last_modified` INTEGER NOT NULL, `custom_order` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "_id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "category",
"columnName": "category",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "in_trash",
"columnName": "in_trash",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "last_modified",
"columnName": "last_modified",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "custom_order",
"columnName": "custom_order",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "categories",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `color` TEXT)",
"fields": [
{
"fieldPath": "_id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "notifications",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_noteId` INTEGER NOT NULL, `time` INTEGER NOT NULL, PRIMARY KEY(`_noteId`))",
"fields": [
{
"fieldPath": "_noteId",
"columnName": "_noteId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_noteId"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'dfaa34068d0a54f9cf797b7c441c2d92')"
]
}
}
140 changes: 140 additions & 0 deletions app/schemas/org.secuso.privacyfriendlynotes.room.NoteDatabase/7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"formatVersion": 1,
"database": {
"version": 7,
"identityHash": "8143c5ddeca8ab31795f588769331b34",
"entities": [
{
"tableName": "notes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `content` TEXT NOT NULL, `type` INTEGER NOT NULL, `category` INTEGER NOT NULL, `in_trash` INTEGER NOT NULL, `last_modified` INTEGER NOT NULL, `custom_order` INTEGER NOT NULL, `readonly` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "_id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "category",
"columnName": "category",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "in_trash",
"columnName": "in_trash",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "last_modified",
"columnName": "last_modified",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "custom_order",
"columnName": "custom_order",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "readonly",
"columnName": "readonly",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "categories",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `color` TEXT)",
"fields": [
{
"fieldPath": "_id",
"columnName": "_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "notifications",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_noteId` INTEGER NOT NULL, `time` INTEGER NOT NULL, PRIMARY KEY(`_noteId`))",
"fields": [
{
"fieldPath": "_noteId",
"columnName": "_noteId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "time",
"columnName": "time",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"_noteId"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '8143c5ddeca8ab31795f588769331b34')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import androidx.room.migration.Migration;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteDatabase;
import androidx.sqlite.db.SupportSQLiteStatement;

import org.secuso.privacyfriendlynotes.room.dao.CategoryDao;
import org.secuso.privacyfriendlynotes.room.dao.NoteDao;
Expand All @@ -37,12 +38,10 @@
import org.secuso.privacyfriendlynotes.room.model.Notification;

import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.Locale;

/**
* The database that includes all used information like notes, notifications and categories.
Expand All @@ -57,7 +56,7 @@ public abstract class NoteDatabase extends RoomDatabase {
public static final int VERSION = 7;
public static final String DATABASE_NAME = "allthenotes";

static final Migration MIGRATION_6_7 = new Migration(6,7) {
static final Migration MIGRATION_6_7 = new Migration(6, 7) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE notes ADD COLUMN readonly INTEGER NOT NULL DEFAULT 0;");
Expand All @@ -76,19 +75,48 @@ public void migrate(@NonNull SupportSQLiteDatabase database) {
+ "last_modified INTEGER NOT NULL DEFAULT(unixepoch('subsec') * 1000),"
+ "custom_order INTEGER NOT NULL DEFAULT 0,"
+ "PRIMARY KEY(_id));");
// Prepare INSERT statement
SupportSQLiteStatement stmt = database.compileStatement(
"INSERT INTO notes_new(_id, in_trash, name, type, category, content, last_modified, custom_order)" +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?);"
);
// Previous date format: Calendar.getInstance().time.toString() -> "Thu Jul 08 12:34:56 UTC 2023"
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.getDefault());
try (Cursor cursor = database.query(new SimpleSQLiteQuery("SELECT * FROM notes;"))) {
while (cursor.moveToNext()) {
@SuppressLint("Range") String lastModified = cursor.getString(cursor.getColumnIndex("last_modified"));
long lastModifiedMillis = Date.parse(lastModified);
long lastModifiedMillis;
try {
Date parsed = sdf.parse(lastModified);
lastModifiedMillis = parsed.getTime();
} catch (ParseException | NullPointerException e) {
try {
lastModifiedMillis = Date.parse(lastModified);
} catch (IllegalArgumentException iae) {
lastModifiedMillis = 0L;
}
}
@SuppressLint("Range") int _id = cursor.getInt(cursor.getColumnIndex("_id"));
@SuppressLint("Range") int in_trash = cursor.getInt(cursor.getColumnIndex("in_trash"));
@SuppressLint("Range") String name = cursor.getString(cursor.getColumnIndex("name"));
@SuppressLint("Range") int type = cursor.getInt(cursor.getColumnIndex("type"));
@SuppressLint("Range") int category = cursor.getInt(cursor.getColumnIndex("category"));
@SuppressLint("Range") String content = cursor.getString(cursor.getColumnIndex("content"));
@SuppressLint("Range") int custom_order = cursor.getInt(cursor.getColumnIndex("custom_order"));
String value = String.format("(%s,%s,'%s',%s,%s,'%s',%s,%s)", _id, in_trash, name, type, category, content, lastModifiedMillis, custom_order);
database.execSQL("INSERT INTO notes_new(_id, in_trash,name,type,category,content,last_modified,custom_order) VALUES" + value + ";");
stmt.bindLong(1, _id);
stmt.bindLong(2, in_trash);
stmt.bindString(3, name);
stmt.bindLong(4, type);
stmt.bindLong(5, category);
stmt.bindString(6, content);
stmt.bindLong(7, lastModifiedMillis);
stmt.bindLong(8, custom_order);

// Execute insert
stmt.executeInsert();

// Clear bindings to be ready for next row
stmt.clearBindings();
}
}
database.execSQL("DROP TABLE notes;");
Expand Down
Loading