Fix: correct the transaction queries.
The new info that we receive during scanning broke some assumptions we were making in the queries.
This commit is contained in:
parent
8808d9c58d
commit
82381c5381
|
@ -0,0 +1,345 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 5,
|
||||
"identityHash": "d6e9b05e0607d399f821058adb43dc15",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "transactions",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_tx` INTEGER, `txid` BLOB NOT NULL, `tx_index` INTEGER, `created` TEXT, `expiry_height` INTEGER, `block` INTEGER, `raw` BLOB, PRIMARY KEY(`id_tx`), FOREIGN KEY(`block`) REFERENCES `blocks`(`height`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "txid",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionIndex",
|
||||
"columnName": "tx_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "created",
|
||||
"columnName": "created",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "expiryHeight",
|
||||
"columnName": "expiry_height",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "minedHeight",
|
||||
"columnName": "block",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "raw",
|
||||
"columnName": "raw",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_tx"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "blocks",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"block"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"height"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "blocks",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`height` INTEGER, `hash` BLOB NOT NULL, `time` INTEGER NOT NULL, `sapling_tree` BLOB NOT NULL, PRIMARY KEY(`height`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "height",
|
||||
"columnName": "height",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "hash",
|
||||
"columnName": "hash",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "time",
|
||||
"columnName": "time",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "saplingTree",
|
||||
"columnName": "sapling_tree",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"height"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "received_notes",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `account` INTEGER NOT NULL, `value` INTEGER NOT NULL, `spent` INTEGER, `diversifier` BLOB NOT NULL, `rcm` BLOB NOT NULL, `nf` BLOB NOT NULL, `is_change` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`spent`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_note",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "outputIndex",
|
||||
"columnName": "output_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "spent",
|
||||
"columnName": "spent",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "diversifier",
|
||||
"columnName": "diversifier",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "rcm",
|
||||
"columnName": "rcm",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "nf",
|
||||
"columnName": "nf",
|
||||
"affinity": "BLOB",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "isChange",
|
||||
"columnName": "is_change",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "memo",
|
||||
"columnName": "memo",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_note"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"tx"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "accounts",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"account"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"account"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"spent"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tableName": "accounts",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`account` INTEGER, `extfvk` TEXT NOT NULL, `address` TEXT NOT NULL, PRIMARY KEY(`account`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "extendedFullViewingKey",
|
||||
"columnName": "extfvk",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "address",
|
||||
"columnName": "address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"account"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "sent_notes",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id_note` INTEGER, `tx` INTEGER NOT NULL, `output_index` INTEGER NOT NULL, `from_account` INTEGER NOT NULL, `address` TEXT NOT NULL, `value` INTEGER NOT NULL, `memo` BLOB, PRIMARY KEY(`id_note`), FOREIGN KEY(`tx`) REFERENCES `transactions`(`id_tx`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`from_account`) REFERENCES `accounts`(`account`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id_note",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "transactionId",
|
||||
"columnName": "tx",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "outputIndex",
|
||||
"columnName": "output_index",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "account",
|
||||
"columnName": "from_account",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "address",
|
||||
"columnName": "address",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "value",
|
||||
"columnName": "value",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "memo",
|
||||
"columnName": "memo",
|
||||
"affinity": "BLOB",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id_note"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": [
|
||||
{
|
||||
"table": "transactions",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"tx"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"id_tx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"table": "accounts",
|
||||
"onDelete": "NO ACTION",
|
||||
"onUpdate": "NO ACTION",
|
||||
"columns": [
|
||||
"from_account"
|
||||
],
|
||||
"referencedColumns": [
|
||||
"account"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"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, 'd6e9b05e0607d399f821058adb43dc15')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ import cash.z.wallet.sdk.entity.*
|
|||
Account::class,
|
||||
Sent::class
|
||||
],
|
||||
version = 4,
|
||||
version = 5,
|
||||
exportSchema = true
|
||||
)
|
||||
abstract class DerivedDataDb : RoomDatabase() {
|
||||
|
@ -163,15 +163,15 @@ interface TransactionDao {
|
|||
transactions.raw AS raw,
|
||||
sent_notes.address AS toAddress,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.value
|
||||
WHEN sent_notes.value IS NOT NULL THEN sent_notes.value
|
||||
ELSE received_notes.value
|
||||
end AS value,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.memo
|
||||
WHEN sent_notes.memo IS NOT NULL THEN sent_notes.memo
|
||||
ELSE received_notes.memo
|
||||
end AS memo,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.id_note
|
||||
WHEN sent_notes.id_note IS NOT NULL THEN sent_notes.id_note
|
||||
ELSE received_notes.id_note
|
||||
end AS noteId,
|
||||
blocks.time AS blockTimeInSeconds
|
||||
|
@ -207,15 +207,15 @@ interface TransactionDao {
|
|||
transactions.raw AS raw,
|
||||
sent_notes.address AS toAddress,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.value
|
||||
WHEN sent_notes.value IS NOT NULL THEN sent_notes.value
|
||||
ELSE received_notes.value
|
||||
end AS value,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.memo
|
||||
WHEN sent_notes.memo IS NOT NULL THEN sent_notes.memo
|
||||
ELSE received_notes.memo
|
||||
end AS memo,
|
||||
CASE
|
||||
WHEN transactions.raw IS NOT NULL THEN sent_notes.id_note
|
||||
WHEN sent_notes.id_note IS NOT NULL THEN sent_notes.id_note
|
||||
ELSE received_notes.id_note
|
||||
end AS noteId,
|
||||
blocks.time AS blockTimeInSeconds
|
||||
|
@ -226,7 +226,8 @@ interface TransactionDao {
|
|||
ON transactions.id_tx = sent_notes.tx
|
||||
LEFT JOIN blocks
|
||||
ON transactions.block = blocks.height
|
||||
WHERE :blockRangeStart <= minedheight AND minedheight <= :blockRangeEnd
|
||||
WHERE :blockRangeStart <= minedheight
|
||||
AND minedheight <= :blockRangeEnd
|
||||
ORDER BY ( minedheight IS NOT NULL ),
|
||||
minedheight ASC,
|
||||
blocktimeinseconds DESC,
|
||||
|
|
|
@ -40,6 +40,7 @@ open class PagedTransactionRepository(
|
|||
.setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
|
||||
.addMigrations(MIGRATION_3_4)
|
||||
.addMigrations(MIGRATION_4_3)
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.build(),
|
||||
pageSize
|
||||
)
|
||||
|
@ -151,6 +152,37 @@ open class PagedTransactionRepository(
|
|||
database.execSQL("PRAGMA foreign_keys = ON;")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val MIGRATION_4_5 = object : Migration(4, 5) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("PRAGMA foreign_keys = OFF;")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS received_notes_new (
|
||||
id_note INTEGER PRIMARY KEY,
|
||||
tx INTEGER NOT NULL,
|
||||
output_index INTEGER NOT NULL,
|
||||
account INTEGER NOT NULL,
|
||||
diversifier BLOB NOT NULL,
|
||||
value INTEGER NOT NULL,
|
||||
rcm BLOB NOT NULL,
|
||||
nf BLOB NOT NULL UNIQUE,
|
||||
is_change INTEGER NOT NULL,
|
||||
memo BLOB,
|
||||
spent INTEGER,
|
||||
FOREIGN KEY (tx) REFERENCES transactions(id_tx),
|
||||
FOREIGN KEY (account) REFERENCES accounts(account),
|
||||
FOREIGN KEY (spent) REFERENCES transactions(id_tx),
|
||||
CONSTRAINT tx_output UNIQUE (tx, output_index)
|
||||
); """.trimIndent()
|
||||
)
|
||||
database.execSQL("INSERT INTO received_notes_new SELECT * FROM received_notes;")
|
||||
database.execSQL("DROP TABLE received_notes;")
|
||||
database.execSQL("ALTER TABLE received_notes_new RENAME TO received_notes;")
|
||||
database.execSQL("PRAGMA foreign_keys = ON;")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue