mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-04-25 09:18:01 +00:00
Initial commit: Pezkuwi Wallet Android
Complete rebrand of Nova Wallet for Pezkuwichain ecosystem. ## Features - Full Pezkuwichain support (HEZ & PEZ tokens) - Polkadot ecosystem compatibility - Staking, Governance, DeFi, NFTs - XCM cross-chain transfers - Hardware wallet support (Ledger, Polkadot Vault) - WalletConnect v2 - Push notifications ## Languages - English, Turkish, Kurmanci (Kurdish), Spanish, French, German, Russian, Japanese, Chinese, Korean, Portuguese, Vietnamese Based on Nova Wallet by Novasama Technologies GmbH © Dijital Kurdistan Tech Institute 2026
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
@@ -0,0 +1,341 @@
|
||||
package io.novafoundation.nova.core_db
|
||||
|
||||
import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import io.novafoundation.nova.core_db.converters.AssetConverters
|
||||
import io.novafoundation.nova.core_db.converters.ChainConverters
|
||||
import io.novafoundation.nova.core_db.converters.CryptoTypeConverters
|
||||
import io.novafoundation.nova.core_db.converters.CurrencyConverters
|
||||
import io.novafoundation.nova.core_db.converters.ExternalApiConverters
|
||||
import io.novafoundation.nova.core_db.converters.ExternalBalanceTypeConverters
|
||||
import io.novafoundation.nova.core_db.converters.LongMathConverters
|
||||
import io.novafoundation.nova.core_db.converters.MetaAccountTypeConverters
|
||||
import io.novafoundation.nova.core_db.converters.NetworkTypeConverters
|
||||
import io.novafoundation.nova.core_db.converters.NftConverters
|
||||
import io.novafoundation.nova.core_db.converters.OperationConverters
|
||||
import io.novafoundation.nova.core_db.converters.ProxyAccountConverters
|
||||
import io.novafoundation.nova.core_db.dao.AccountDao
|
||||
import io.novafoundation.nova.core_db.dao.AccountStakingDao
|
||||
import io.novafoundation.nova.core_db.dao.AssetDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserHostSettingsDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserTabsDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainAssetDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainDao
|
||||
import io.novafoundation.nova.core_db.dao.CoinPriceDao
|
||||
import io.novafoundation.nova.core_db.dao.ContributionDao
|
||||
import io.novafoundation.nova.core_db.dao.CurrencyDao
|
||||
import io.novafoundation.nova.core_db.dao.DappAuthorizationDao
|
||||
import io.novafoundation.nova.core_db.dao.ExternalBalanceDao
|
||||
import io.novafoundation.nova.core_db.dao.FavouriteDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.GiftsDao
|
||||
import io.novafoundation.nova.core_db.dao.GovernanceDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.HoldsDao
|
||||
import io.novafoundation.nova.core_db.dao.LockDao
|
||||
import io.novafoundation.nova.core_db.dao.MetaAccountDao
|
||||
import io.novafoundation.nova.core_db.dao.MultisigOperationsDao
|
||||
import io.novafoundation.nova.core_db.dao.NftDao
|
||||
import io.novafoundation.nova.core_db.dao.NodeDao
|
||||
import io.novafoundation.nova.core_db.dao.OperationDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingAddressDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingSitesDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingDashboardDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingRewardPeriodDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingTotalRewardDao
|
||||
import io.novafoundation.nova.core_db.dao.StorageDao
|
||||
import io.novafoundation.nova.core_db.dao.TinderGovDao
|
||||
import io.novafoundation.nova.core_db.dao.TokenDao
|
||||
import io.novafoundation.nova.core_db.dao.WalletConnectSessionsDao
|
||||
import io.novafoundation.nova.core_db.migrations.AddAdditionalFieldToChains_12_13
|
||||
import io.novafoundation.nova.core_db.migrations.AddBalanceHolds_60_61
|
||||
import io.novafoundation.nova.core_db.migrations.AddBalanceModesToAssets_51_52
|
||||
import io.novafoundation.nova.core_db.migrations.AddBrowserHostSettings_34_35
|
||||
import io.novafoundation.nova.core_db.migrations.AddBrowserTabs_64_65
|
||||
import io.novafoundation.nova.core_db.migrations.AddBuyProviders_7_8
|
||||
import io.novafoundation.nova.core_db.migrations.AddChainColor_4_5
|
||||
import io.novafoundation.nova.core_db.migrations.AddChainForeignKeyForProxy_63_64
|
||||
import io.novafoundation.nova.core_db.migrations.AddConnectionStateToChains_53_54
|
||||
import io.novafoundation.nova.core_db.migrations.AddFieldsToContributions
|
||||
import io.novafoundation.nova.core_db.migrations.AddContributions_23_24
|
||||
import io.novafoundation.nova.core_db.migrations.AddCurrencies_18_19
|
||||
import io.novafoundation.nova.core_db.migrations.AddDAppAuthorizations_1_2
|
||||
import io.novafoundation.nova.core_db.migrations.AddEnabledColumnToChainAssets_30_31
|
||||
import io.novafoundation.nova.core_db.migrations.AddEventIdToOperation_47_48
|
||||
import io.novafoundation.nova.core_db.migrations.AddExternalBalances_45_46
|
||||
import io.novafoundation.nova.core_db.migrations.AddExtrinsicContentField_37_38
|
||||
import io.novafoundation.nova.core_db.migrations.AddFavoriteDAppsOrdering_65_66
|
||||
import io.novafoundation.nova.core_db.migrations.AddFavouriteDApps_9_10
|
||||
import io.novafoundation.nova.core_db.migrations.AddFungibleNfts_55_56
|
||||
import io.novafoundation.nova.core_db.migrations.AddGifts_71_72
|
||||
import io.novafoundation.nova.core_db.migrations.AddGloballyUniqueIdToMetaAccounts_58_59
|
||||
import io.novafoundation.nova.core_db.migrations.AddGovernanceDapps_25_26
|
||||
import io.novafoundation.nova.core_db.migrations.AddGovernanceExternalApiToChain_27_28
|
||||
import io.novafoundation.nova.core_db.migrations.AddGovernanceFlagToChains_24_25
|
||||
import io.novafoundation.nova.core_db.migrations.AddGovernanceNetworkToExternalApi_33_34
|
||||
import io.novafoundation.nova.core_db.migrations.AddLegacyAddressPrefix_66_67
|
||||
import io.novafoundation.nova.core_db.migrations.AddLocalMigratorVersionToChainRuntimes_57_58
|
||||
import io.novafoundation.nova.core_db.migrations.AddLocks_22_23
|
||||
import io.novafoundation.nova.core_db.migrations.AddMetaAccountType_14_15
|
||||
import io.novafoundation.nova.core_db.migrations.AddMultisigCalls_69_70
|
||||
import io.novafoundation.nova.core_db.migrations.AddMultisigSupportFlag_70_71
|
||||
import io.novafoundation.nova.core_db.migrations.AddNfts_5_6
|
||||
import io.novafoundation.nova.core_db.migrations.AddNodeSelectionStrategyField_38_39
|
||||
import io.novafoundation.nova.core_db.migrations.AddPoolIdToOperations_46_47
|
||||
import io.novafoundation.nova.core_db.migrations.AddProxyAccount_54_55
|
||||
import io.novafoundation.nova.core_db.migrations.AddRewardAccountToStakingDashboard_43_44
|
||||
import io.novafoundation.nova.core_db.migrations.AddRuntimeFlagToChains_36_37
|
||||
import io.novafoundation.nova.core_db.migrations.AddSellProviders_67_68
|
||||
import io.novafoundation.nova.core_db.migrations.AddSitePhishing_6_7
|
||||
import io.novafoundation.nova.core_db.migrations.AddSourceToLocalAsset_28_29
|
||||
import io.novafoundation.nova.core_db.migrations.AddStakingDashboardItems_41_42
|
||||
import io.novafoundation.nova.core_db.migrations.AddStakingTypeToTotalRewards_44_45
|
||||
import io.novafoundation.nova.core_db.migrations.AddSwapOption_48_49
|
||||
import io.novafoundation.nova.core_db.migrations.AddTransactionVersionToRuntime_50_51
|
||||
import io.novafoundation.nova.core_db.migrations.AddTransferApisTable_29_30
|
||||
import io.novafoundation.nova.core_db.migrations.AddTypeExtrasToMetaAccount_68_69
|
||||
import io.novafoundation.nova.core_db.migrations.AddVersioningToGovernanceDapps_32_33
|
||||
import io.novafoundation.nova.core_db.migrations.AddWalletConnectSessions_39_40
|
||||
import io.novafoundation.nova.core_db.migrations.AssetTypes_2_3
|
||||
import io.novafoundation.nova.core_db.migrations.BetterChainDiffing_8_9
|
||||
import io.novafoundation.nova.core_db.migrations.ChainNetworkManagement_59_60
|
||||
import io.novafoundation.nova.core_db.migrations.ChainNetworkManagement_61_62
|
||||
import io.novafoundation.nova.core_db.migrations.ChainPushSupport_56_57
|
||||
import io.novafoundation.nova.core_db.migrations.ChangeAsset_3_4
|
||||
import io.novafoundation.nova.core_db.migrations.ChangeChainNodes_20_21
|
||||
import io.novafoundation.nova.core_db.migrations.ChangeDAppAuthorization_10_11
|
||||
import io.novafoundation.nova.core_db.migrations.ChangeSessionTopicToParing_52_53
|
||||
import io.novafoundation.nova.core_db.migrations.ChangeTokens_19_20
|
||||
import io.novafoundation.nova.core_db.migrations.ExtractExternalApiToSeparateTable_35_36
|
||||
import io.novafoundation.nova.core_db.migrations.FixBrokenForeignKeys_31_32
|
||||
import io.novafoundation.nova.core_db.migrations.FixMigrationConflicts_13_14
|
||||
import io.novafoundation.nova.core_db.migrations.GovernanceFlagToEnum_26_27
|
||||
import io.novafoundation.nova.core_db.migrations.NullableSubstrateAccountId_21_22
|
||||
import io.novafoundation.nova.core_db.migrations.NullableSubstratePublicKey_15_16
|
||||
import io.novafoundation.nova.core_db.migrations.RefactorOperations_49_50
|
||||
import io.novafoundation.nova.core_db.migrations.RemoveChainForeignKeyFromChainAccount_11_12
|
||||
import io.novafoundation.nova.core_db.migrations.RemoveColorFromChains_17_18
|
||||
import io.novafoundation.nova.core_db.migrations.StakingRewardPeriods_42_43
|
||||
import io.novafoundation.nova.core_db.migrations.TinderGovBasket_62_63
|
||||
import io.novafoundation.nova.core_db.migrations.TransferFiatAmount_40_41
|
||||
import io.novafoundation.nova.core_db.migrations.WatchOnlyChainAccounts_16_17
|
||||
import io.novafoundation.nova.core_db.model.AccountLocal
|
||||
import io.novafoundation.nova.core_db.model.AccountStakingLocal
|
||||
import io.novafoundation.nova.core_db.model.AssetLocal
|
||||
import io.novafoundation.nova.core_db.model.BalanceHoldLocal
|
||||
import io.novafoundation.nova.core_db.model.BalanceLockLocal
|
||||
import io.novafoundation.nova.core_db.model.BrowserHostSettingsLocal
|
||||
import io.novafoundation.nova.core_db.model.BrowserTabLocal
|
||||
import io.novafoundation.nova.core_db.model.CoinPriceLocal
|
||||
import io.novafoundation.nova.core_db.model.ContributionLocal
|
||||
import io.novafoundation.nova.core_db.model.CurrencyLocal
|
||||
import io.novafoundation.nova.core_db.model.DappAuthorizationLocal
|
||||
import io.novafoundation.nova.core_db.model.ExternalBalanceLocal
|
||||
import io.novafoundation.nova.core_db.model.FavouriteDAppLocal
|
||||
import io.novafoundation.nova.core_db.model.GiftLocal
|
||||
import io.novafoundation.nova.core_db.model.GovernanceDAppLocal
|
||||
import io.novafoundation.nova.core_db.model.MultisigOperationCallLocal
|
||||
import io.novafoundation.nova.core_db.model.NftLocal
|
||||
import io.novafoundation.nova.core_db.model.NodeLocal
|
||||
import io.novafoundation.nova.core_db.model.PhishingAddressLocal
|
||||
import io.novafoundation.nova.core_db.model.PhishingSiteLocal
|
||||
import io.novafoundation.nova.core_db.model.StakingDashboardItemLocal
|
||||
import io.novafoundation.nova.core_db.model.StakingRewardPeriodLocal
|
||||
import io.novafoundation.nova.core_db.model.StorageEntryLocal
|
||||
import io.novafoundation.nova.core_db.model.TinderGovBasketItemLocal
|
||||
import io.novafoundation.nova.core_db.model.TinderGovVotingPowerLocal
|
||||
import io.novafoundation.nova.core_db.model.TokenLocal
|
||||
import io.novafoundation.nova.core_db.model.TotalRewardLocal
|
||||
import io.novafoundation.nova.core_db.model.WalletConnectPairingLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainExplorerLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainExternalApiLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainNodeLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainRuntimeInfoLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.NodeSelectionPreferencesLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.ChainAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.ProxyAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.DirectRewardTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.ExtrinsicTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationBaseLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.PoolRewardTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.SwapTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.TransferTypeLocal
|
||||
|
||||
@Database(
|
||||
version = 73,
|
||||
entities = [
|
||||
AccountLocal::class,
|
||||
NodeLocal::class,
|
||||
AssetLocal::class,
|
||||
TokenLocal::class,
|
||||
PhishingAddressLocal::class,
|
||||
StorageEntryLocal::class,
|
||||
AccountStakingLocal::class,
|
||||
TotalRewardLocal::class,
|
||||
OperationBaseLocal::class,
|
||||
TransferTypeLocal::class,
|
||||
DirectRewardTypeLocal::class,
|
||||
PoolRewardTypeLocal::class,
|
||||
ExtrinsicTypeLocal::class,
|
||||
SwapTypeLocal::class,
|
||||
ChainLocal::class,
|
||||
ChainNodeLocal::class,
|
||||
ChainAssetLocal::class,
|
||||
ChainRuntimeInfoLocal::class,
|
||||
ChainExplorerLocal::class,
|
||||
ChainExternalApiLocal::class,
|
||||
MetaAccountLocal::class,
|
||||
ChainAccountLocal::class,
|
||||
DappAuthorizationLocal::class,
|
||||
NftLocal::class,
|
||||
PhishingSiteLocal::class,
|
||||
FavouriteDAppLocal::class,
|
||||
CurrencyLocal::class,
|
||||
BalanceLockLocal::class,
|
||||
ContributionLocal::class,
|
||||
GovernanceDAppLocal::class,
|
||||
BrowserHostSettingsLocal::class,
|
||||
WalletConnectPairingLocal::class,
|
||||
CoinPriceLocal::class,
|
||||
StakingDashboardItemLocal::class,
|
||||
StakingRewardPeriodLocal::class,
|
||||
ExternalBalanceLocal::class,
|
||||
ProxyAccountLocal::class,
|
||||
BalanceHoldLocal::class,
|
||||
NodeSelectionPreferencesLocal::class,
|
||||
TinderGovBasketItemLocal::class,
|
||||
TinderGovVotingPowerLocal::class,
|
||||
BrowserTabLocal::class,
|
||||
MultisigOperationCallLocal::class,
|
||||
GiftLocal::class
|
||||
],
|
||||
)
|
||||
@TypeConverters(
|
||||
LongMathConverters::class,
|
||||
NetworkTypeConverters::class,
|
||||
OperationConverters::class,
|
||||
CryptoTypeConverters::class,
|
||||
NftConverters::class,
|
||||
MetaAccountTypeConverters::class,
|
||||
CurrencyConverters::class,
|
||||
AssetConverters::class,
|
||||
ExternalApiConverters::class,
|
||||
ChainConverters::class,
|
||||
ExternalBalanceTypeConverters::class,
|
||||
ProxyAccountConverters::class,
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
|
||||
private var instance: AppDatabase? = null
|
||||
|
||||
@Synchronized
|
||||
fun get(
|
||||
context: Context
|
||||
): AppDatabase {
|
||||
if (instance == null) {
|
||||
instance = Room.databaseBuilder(
|
||||
context.applicationContext,
|
||||
AppDatabase::class.java,
|
||||
"app.db"
|
||||
)
|
||||
.addMigrations(AddDAppAuthorizations_1_2, AssetTypes_2_3, ChangeAsset_3_4)
|
||||
.addMigrations(AddChainColor_4_5, AddNfts_5_6, AddSitePhishing_6_7, AddBuyProviders_7_8, BetterChainDiffing_8_9)
|
||||
.addMigrations(AddFavouriteDApps_9_10, ChangeDAppAuthorization_10_11, RemoveChainForeignKeyFromChainAccount_11_12)
|
||||
.addMigrations(AddAdditionalFieldToChains_12_13, FixMigrationConflicts_13_14, AddMetaAccountType_14_15)
|
||||
.addMigrations(NullableSubstratePublicKey_15_16, WatchOnlyChainAccounts_16_17, RemoveColorFromChains_17_18)
|
||||
.addMigrations(AddCurrencies_18_19, ChangeTokens_19_20, ChangeChainNodes_20_21)
|
||||
.addMigrations(NullableSubstrateAccountId_21_22, AddLocks_22_23, AddContributions_23_24)
|
||||
.addMigrations(AddGovernanceFlagToChains_24_25, AddGovernanceDapps_25_26, GovernanceFlagToEnum_26_27)
|
||||
.addMigrations(AddGovernanceExternalApiToChain_27_28)
|
||||
.addMigrations(AddSourceToLocalAsset_28_29, AddTransferApisTable_29_30, AddEnabledColumnToChainAssets_30_31)
|
||||
.addMigrations(FixBrokenForeignKeys_31_32, AddVersioningToGovernanceDapps_32_33)
|
||||
.addMigrations(AddGovernanceNetworkToExternalApi_33_34, AddBrowserHostSettings_34_35)
|
||||
.addMigrations(ExtractExternalApiToSeparateTable_35_36, AddRuntimeFlagToChains_36_37)
|
||||
.addMigrations(AddExtrinsicContentField_37_38, AddNodeSelectionStrategyField_38_39)
|
||||
.addMigrations(AddWalletConnectSessions_39_40, TransferFiatAmount_40_41)
|
||||
.addMigrations(AddStakingDashboardItems_41_42, StakingRewardPeriods_42_43)
|
||||
.addMigrations(AddRewardAccountToStakingDashboard_43_44, AddStakingTypeToTotalRewards_44_45, AddExternalBalances_45_46)
|
||||
.addMigrations(AddPoolIdToOperations_46_47, AddEventIdToOperation_47_48, AddSwapOption_48_49)
|
||||
.addMigrations(RefactorOperations_49_50, AddTransactionVersionToRuntime_50_51, AddBalanceModesToAssets_51_52)
|
||||
.addMigrations(ChangeSessionTopicToParing_52_53, AddConnectionStateToChains_53_54, AddProxyAccount_54_55)
|
||||
.addMigrations(AddFungibleNfts_55_56, ChainPushSupport_56_57)
|
||||
.addMigrations(AddLocalMigratorVersionToChainRuntimes_57_58, AddGloballyUniqueIdToMetaAccounts_58_59)
|
||||
.addMigrations(ChainNetworkManagement_59_60, AddBalanceHolds_60_61, ChainNetworkManagement_61_62)
|
||||
.addMigrations(TinderGovBasket_62_63, AddChainForeignKeyForProxy_63_64, AddBrowserTabs_64_65)
|
||||
.addMigrations(AddFavoriteDAppsOrdering_65_66, AddLegacyAddressPrefix_66_67, AddSellProviders_67_68)
|
||||
.addMigrations(AddTypeExtrasToMetaAccount_68_69, AddMultisigCalls_69_70, AddMultisigSupportFlag_70_71)
|
||||
.addMigrations(AddGifts_71_72, AddFieldsToContributions)
|
||||
.build()
|
||||
}
|
||||
return instance!!
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun nodeDao(): NodeDao
|
||||
|
||||
abstract fun userDao(): AccountDao
|
||||
|
||||
abstract fun assetDao(): AssetDao
|
||||
|
||||
abstract fun operationDao(): OperationDao
|
||||
|
||||
abstract fun phishingAddressesDao(): PhishingAddressDao
|
||||
|
||||
abstract fun storageDao(): StorageDao
|
||||
|
||||
abstract fun tokenDao(): TokenDao
|
||||
|
||||
abstract fun accountStakingDao(): AccountStakingDao
|
||||
|
||||
abstract fun stakingTotalRewardDao(): StakingTotalRewardDao
|
||||
|
||||
abstract fun chainDao(): ChainDao
|
||||
|
||||
abstract fun chainAssetDao(): ChainAssetDao
|
||||
|
||||
abstract fun metaAccountDao(): MetaAccountDao
|
||||
|
||||
abstract fun dAppAuthorizationDao(): DappAuthorizationDao
|
||||
|
||||
abstract fun nftDao(): NftDao
|
||||
|
||||
abstract fun phishingSitesDao(): PhishingSitesDao
|
||||
|
||||
abstract fun favouriteDAppsDao(): FavouriteDAppsDao
|
||||
|
||||
abstract fun currencyDao(): CurrencyDao
|
||||
|
||||
abstract fun lockDao(): LockDao
|
||||
|
||||
abstract fun contributionDao(): ContributionDao
|
||||
|
||||
abstract fun governanceDAppsDao(): GovernanceDAppsDao
|
||||
|
||||
abstract fun browserHostSettingsDao(): BrowserHostSettingsDao
|
||||
|
||||
abstract fun walletConnectSessionsDao(): WalletConnectSessionsDao
|
||||
|
||||
abstract fun stakingDashboardDao(): StakingDashboardDao
|
||||
|
||||
abstract fun coinPriceDao(): CoinPriceDao
|
||||
|
||||
abstract fun stakingRewardPeriodDao(): StakingRewardPeriodDao
|
||||
|
||||
abstract fun externalBalanceDao(): ExternalBalanceDao
|
||||
|
||||
abstract fun holdsDao(): HoldsDao
|
||||
|
||||
abstract fun tinderGovDao(): TinderGovDao
|
||||
|
||||
abstract fun browserTabsDao(): BrowserTabsDao
|
||||
|
||||
abstract fun multisigOperationsDao(): MultisigOperationsDao
|
||||
|
||||
abstract fun giftsDao(): GiftsDao
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.AssetLocal.EDCountingModeLocal
|
||||
import io.novafoundation.nova.core_db.model.AssetLocal.TransferableModeLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.AssetSourceLocal
|
||||
|
||||
class AssetConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromCategory(type: AssetSourceLocal): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toCategory(name: String): AssetSourceLocal {
|
||||
return enumValueOf(name)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromTransferableMode(mode: TransferableModeLocal): Int {
|
||||
return mode.ordinal
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toTransferableMode(index: Int): TransferableModeLocal {
|
||||
return TransferableModeLocal.values()[index]
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromEdCountingMode(mode: EDCountingModeLocal): Int {
|
||||
return mode.ordinal
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toEdCountingMode(index: Int): EDCountingModeLocal {
|
||||
return EDCountingModeLocal.values()[index]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.common.utils.enumValueOfOrNull
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal.ConnectionStateLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal.AutoBalanceStrategyLocal
|
||||
|
||||
class ChainConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromNodeStrategy(strategy: AutoBalanceStrategyLocal): String = strategy.name
|
||||
|
||||
@TypeConverter
|
||||
fun toNodeStrategy(name: String): AutoBalanceStrategyLocal {
|
||||
return enumValueOfOrNull<AutoBalanceStrategyLocal>(name) ?: AutoBalanceStrategyLocal.UNKNOWN
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromConnection(connectionState: ConnectionStateLocal): String = connectionState.name
|
||||
|
||||
@TypeConverter
|
||||
fun toConnection(name: String): ConnectionStateLocal {
|
||||
return enumValueOfOrNull<ConnectionStateLocal>(name) ?: ConnectionStateLocal.LIGHT_SYNC
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core.model.CryptoType
|
||||
|
||||
class CryptoTypeConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun from(cryptoType: CryptoType?): String? = cryptoType?.name
|
||||
|
||||
@TypeConverter
|
||||
fun to(name: String?): CryptoType? = name?.let { enumValueOf<CryptoType>(it) }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.CurrencyLocal
|
||||
|
||||
class CurrencyConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromCategory(type: CurrencyLocal.Category): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toCategory(name: String): CurrencyLocal.Category {
|
||||
return enumValueOf(name)
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.common.utils.enumValueOfOrNull
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainExternalApiLocal.SourceType
|
||||
|
||||
class ExternalApiConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromApiType(apiType: SourceType): String {
|
||||
return apiType.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toApiType(raw: String): SourceType {
|
||||
return enumValueOfOrNull<SourceType>(raw) ?: SourceType.UNKNOWN
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.ExternalBalanceLocal
|
||||
|
||||
class ExternalBalanceTypeConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromType(type: ExternalBalanceLocal.Type): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toType(name: String): ExternalBalanceLocal.Type {
|
||||
return ExternalBalanceLocal.Type.valueOf(name)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
|
||||
class LongMathConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromBigDecimal(balance: BigDecimal?): String? {
|
||||
return balance?.toString()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toBigDecimal(balance: String?): BigDecimal? {
|
||||
return balance?.let { BigDecimal(it) }
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromBigInteger(balance: BigInteger?): String? {
|
||||
return balance?.toString()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toBigInteger(balance: String?): BigInteger? {
|
||||
return balance?.let {
|
||||
// When using aggregates like SUM in SQL queries, SQLite might return the result in a scientific notation especially if aggregation is done
|
||||
// BigInteger, which is stored as a string and SQLite casts it to REAL which causing the scientific notation on big numbers
|
||||
// This can be avoided by adjusting the query but we keep the fallback to BigDecimal parsing here anyways to avoid unpleasant crashes
|
||||
// It doesn't bring much impact since try-catch doesn't have an overhead unless the exception is thrown
|
||||
try {
|
||||
BigInteger(it)
|
||||
} catch (e: NumberFormatException) {
|
||||
BigDecimal(it).toBigInteger()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
|
||||
class MetaAccountTypeConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromEnum(type: MetaAccountLocal.Type): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toEnum(name: String): MetaAccountLocal.Type {
|
||||
return MetaAccountLocal.Type.valueOf(name)
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core.model.Node
|
||||
|
||||
class NetworkTypeConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromNetworkType(networkType: Node.NetworkType): Int {
|
||||
return networkType.ordinal
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toNetworkType(ordinal: Int): Node.NetworkType {
|
||||
return Node.NetworkType.values()[ordinal]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.NftLocal
|
||||
|
||||
class NftConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromNftType(type: NftLocal.Type): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toNftType(name: String): NftLocal.Type {
|
||||
return enumValueOf(name)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun fromNftIssuanceType(type: NftLocal.IssuanceType): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toNftIssuanceType(name: String): NftLocal.IssuanceType {
|
||||
return enumValueOf(name)
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.operation.ExtrinsicTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationBaseLocal
|
||||
|
||||
class OperationConverters {
|
||||
|
||||
@TypeConverter
|
||||
fun fromOperationSource(source: OperationBaseLocal.Source) = source.ordinal
|
||||
|
||||
@TypeConverter
|
||||
fun toOperationSource(ordinal: Int) = OperationBaseLocal.Source.values()[ordinal]
|
||||
|
||||
@TypeConverter
|
||||
fun fromOperationStatus(status: OperationBaseLocal.Status) = status.ordinal
|
||||
|
||||
@TypeConverter
|
||||
fun toOperationStatus(ordinal: Int) = OperationBaseLocal.Status.values()[ordinal]
|
||||
|
||||
@TypeConverter
|
||||
fun fromExtrinsicContentType(type: ExtrinsicTypeLocal.ContentType) = type.name
|
||||
|
||||
@TypeConverter
|
||||
fun toExtrinsicContentType(name: String): ExtrinsicTypeLocal.ContentType = enumValueOf(name)
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package io.novafoundation.nova.core_db.converters
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
|
||||
class ProxyAccountConverters {
|
||||
@TypeConverter
|
||||
fun fromStatusType(type: MetaAccountLocal.Status): String {
|
||||
return type.name
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun toStatusType(name: String): MetaAccountLocal.Status {
|
||||
return MetaAccountLocal.Status.valueOf(name)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.core.model.Node
|
||||
import io.novafoundation.nova.core_db.model.AccountLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class AccountDao {
|
||||
|
||||
@Query("select * from users order by networkType, position")
|
||||
abstract fun accountsFlow(): Flow<List<AccountLocal>>
|
||||
|
||||
@Query("select * from users order by networkType, position")
|
||||
abstract suspend fun getAccounts(): List<AccountLocal>
|
||||
|
||||
@Query("select * from users where address = :address")
|
||||
abstract suspend fun getAccount(address: String): AccountLocal?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
abstract suspend fun insert(account: AccountLocal): Long
|
||||
|
||||
@Query("DELETE FROM users where address = :address")
|
||||
abstract suspend fun remove(address: String)
|
||||
|
||||
@Update
|
||||
abstract suspend fun updateAccount(account: AccountLocal)
|
||||
|
||||
@Update
|
||||
abstract suspend fun updateAccounts(accounts: List<AccountLocal>)
|
||||
|
||||
@Query("SELECT COALESCE(MAX(position), 0) + 1 from users")
|
||||
abstract suspend fun getNextPosition(): Int
|
||||
|
||||
@Query("select * from users where networkType = :networkType")
|
||||
abstract suspend fun getAccountsByNetworkType(networkType: Int): List<AccountLocal>
|
||||
|
||||
@Query("select * from users where (address LIKE '%' || :query || '%') AND networkType = :networkType")
|
||||
abstract suspend fun getAccounts(query: String, networkType: Node.NetworkType): List<AccountLocal>
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM users WHERE address = :accountAddress)")
|
||||
abstract suspend fun accountExists(accountAddress: String): Boolean
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.AccountStakingLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
|
||||
private const val SELECT_QUERY = """
|
||||
SELECT * FROM account_staking_accesses
|
||||
WHERE accountId = :accountId AND chainId = :chainId AND chainAssetId = :chainAssetId
|
||||
"""
|
||||
|
||||
@Dao
|
||||
abstract class AccountStakingDao {
|
||||
|
||||
@Query(SELECT_QUERY)
|
||||
abstract suspend fun get(chainId: String, chainAssetId: Int, accountId: ByteArray): AccountStakingLocal
|
||||
|
||||
@Query(SELECT_QUERY)
|
||||
protected abstract fun observeInternal(chainId: String, chainAssetId: Int, accountId: ByteArray): Flow<AccountStakingLocal?>
|
||||
|
||||
fun observeDistinct(chainId: String, chainAssetId: Int, accountId: ByteArray): Flow<AccountStakingLocal> {
|
||||
return observeInternal(chainId, chainAssetId, accountId)
|
||||
.filterNotNull()
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(accountStaking: AccountStakingLocal)
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.common.utils.flowOfAll
|
||||
import io.novafoundation.nova.common.utils.mapToSet
|
||||
import io.novafoundation.nova.core_db.model.AssetAndChainId
|
||||
import io.novafoundation.nova.core_db.model.AssetLocal
|
||||
import io.novafoundation.nova.core_db.model.AssetWithToken
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
private const val RETRIEVE_ASSET_SQL_META_ID = """
|
||||
SELECT *, ca.chainId as ca_chainId, ca.id as ca_assetId FROM chain_assets AS ca
|
||||
LEFT JOIN assets AS a ON a.assetId = ca.id AND a.chainId = ca.chainId AND a.metaId = :metaId
|
||||
INNER JOIN currencies as currency ON currency.selected = 1
|
||||
LEFT JOIN tokens AS t ON ca.symbol = t.tokenSymbol AND currency.id = t.currencyId
|
||||
WHERE ca.chainId = :chainId AND ca.id = :assetId
|
||||
"""
|
||||
|
||||
private const val RETRIEVE_SYNCED_ACCOUNT_ASSETS_QUERY = """
|
||||
SELECT *, ca.chainId as ca_chainId, ca.id as ca_assetId FROM assets AS a
|
||||
INNER JOIN chain_assets AS ca ON a.assetId = ca.id AND a.chainId = ca.chainId
|
||||
INNER JOIN currencies as currency ON currency.selected = 1
|
||||
LEFT JOIN tokens AS t ON ca.symbol = t.tokenSymbol AND currency.id = t.currencyId
|
||||
WHERE a.metaId = :metaId
|
||||
"""
|
||||
|
||||
private const val RETRIEVE_SUPPORTED_ACCOUNT_ASSETS_QUERY = """
|
||||
SELECT *, ca.chainId as ca_chainId, ca.id as ca_assetId FROM chain_assets AS ca
|
||||
LEFT JOIN assets AS a ON a.assetId = ca.id AND a.chainId = ca.chainId AND a.metaId = :metaId
|
||||
INNER JOIN currencies as currency ON currency.selected = 1
|
||||
LEFT JOIN tokens AS t ON ca.symbol = t.tokenSymbol AND currency.id = t.currencyId
|
||||
"""
|
||||
|
||||
private const val RETRIEVE_ASSETS_SQL_META_ID = """
|
||||
SELECT *, ca.chainId as ca_chainId, ca.id as ca_assetId FROM chain_assets AS ca
|
||||
LEFT JOIN assets AS a ON a.assetId = ca.id AND a.chainId = ca.chainId AND a.metaId = :metaId
|
||||
INNER JOIN currencies as currency ON currency.selected = 1
|
||||
LEFT JOIN tokens AS t ON ca.symbol = t.tokenSymbol AND currency.id = t.currencyId
|
||||
WHERE ca.chainId || ':' || ca.id in (:joinedChainAndAssetIds)
|
||||
"""
|
||||
|
||||
interface AssetReadOnlyCache {
|
||||
|
||||
fun observeSyncedAssets(metaId: Long): Flow<List<AssetWithToken>>
|
||||
|
||||
suspend fun getSyncedAssets(metaId: Long): List<AssetWithToken>
|
||||
|
||||
fun observeSupportedAssets(metaId: Long): Flow<List<AssetWithToken>>
|
||||
|
||||
suspend fun getSupportedAssets(metaId: Long): List<AssetWithToken>
|
||||
|
||||
fun observeAsset(metaId: Long, chainId: String, assetId: Int): Flow<AssetWithToken>
|
||||
|
||||
fun observeAssetOrNull(metaId: Long, chainId: String, assetId: Int): Flow<AssetWithToken?>
|
||||
|
||||
fun observeAssets(metaId: Long, assetIds: Collection<AssetAndChainId>): Flow<List<AssetWithToken>>
|
||||
|
||||
suspend fun getAssetWithToken(metaId: Long, chainId: String, assetId: Int): AssetWithToken?
|
||||
|
||||
suspend fun getAsset(metaId: Long, chainId: String, assetId: Int): AssetLocal?
|
||||
|
||||
suspend fun getAssetsInChain(metaId: Long, chainId: String): List<AssetLocal>
|
||||
|
||||
suspend fun getAllAssets(): List<AssetLocal>
|
||||
|
||||
suspend fun getAssetsById(id: Int): List<AssetLocal>
|
||||
}
|
||||
|
||||
@Dao
|
||||
abstract class AssetDao : AssetReadOnlyCache {
|
||||
|
||||
@Query(RETRIEVE_SYNCED_ACCOUNT_ASSETS_QUERY)
|
||||
abstract override fun observeSyncedAssets(metaId: Long): Flow<List<AssetWithToken>>
|
||||
|
||||
@Query(RETRIEVE_SYNCED_ACCOUNT_ASSETS_QUERY)
|
||||
abstract override suspend fun getSyncedAssets(metaId: Long): List<AssetWithToken>
|
||||
|
||||
@Query(RETRIEVE_SUPPORTED_ACCOUNT_ASSETS_QUERY)
|
||||
abstract override fun observeSupportedAssets(metaId: Long): Flow<List<AssetWithToken>>
|
||||
|
||||
@Query(RETRIEVE_SUPPORTED_ACCOUNT_ASSETS_QUERY)
|
||||
abstract override suspend fun getSupportedAssets(metaId: Long): List<AssetWithToken>
|
||||
|
||||
@Query(RETRIEVE_ASSET_SQL_META_ID)
|
||||
abstract override fun observeAsset(metaId: Long, chainId: String, assetId: Int): Flow<AssetWithToken>
|
||||
|
||||
@Query(RETRIEVE_ASSET_SQL_META_ID)
|
||||
abstract override fun observeAssetOrNull(metaId: Long, chainId: String, assetId: Int): Flow<AssetWithToken?>
|
||||
|
||||
@Query(RETRIEVE_ASSET_SQL_META_ID)
|
||||
abstract override suspend fun getAssetWithToken(metaId: Long, chainId: String, assetId: Int): AssetWithToken?
|
||||
|
||||
@Query("SELECT * FROM assets WHERE metaId = :metaId AND chainId = :chainId AND assetId = :assetId")
|
||||
abstract override suspend fun getAsset(metaId: Long, chainId: String, assetId: Int): AssetLocal?
|
||||
|
||||
@Query("SELECT * FROM assets WHERE metaId = :metaId AND chainId = :chainId")
|
||||
abstract override suspend fun getAssetsInChain(metaId: Long, chainId: String): List<AssetLocal>
|
||||
|
||||
@Query("SELECT * FROM assets")
|
||||
abstract override suspend fun getAllAssets(): List<AssetLocal>
|
||||
|
||||
@Query("SELECT * FROM assets WHERE assetId IS :id")
|
||||
abstract override suspend fun getAssetsById(id: Int): List<AssetLocal>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertAsset(asset: AssetLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertAssets(assets: List<AssetLocal>)
|
||||
|
||||
@Delete(entity = AssetLocal::class)
|
||||
abstract suspend fun clearAssets(assetIds: List<ClearAssetsParams>)
|
||||
|
||||
@Query(RETRIEVE_ASSETS_SQL_META_ID)
|
||||
protected abstract fun observeJoinedAssets(metaId: Long, joinedChainAndAssetIds: Set<String>): Flow<List<AssetWithToken>>
|
||||
|
||||
override fun observeAssets(metaId: Long, assetIds: Collection<AssetAndChainId>): Flow<List<AssetWithToken>> {
|
||||
return flowOfAll {
|
||||
val joinedChainAndAssetIds = assetIds.mapToSet { (chainId, assetId) -> "$chainId:$assetId" }
|
||||
|
||||
observeJoinedAssets(metaId, joinedChainAndAssetIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClearAssetsParams(val chainId: String, val assetId: Int)
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.BrowserHostSettingsLocal
|
||||
|
||||
@Dao
|
||||
abstract class BrowserHostSettingsDao {
|
||||
|
||||
@Query("SELECT * FROM browser_host_settings")
|
||||
abstract suspend fun getBrowserAllHostSettings(): List<BrowserHostSettingsLocal>
|
||||
|
||||
@Query("SELECT * FROM browser_host_settings WHERE hostUrl = :host")
|
||||
abstract suspend fun getBrowserHostSettings(host: String): BrowserHostSettingsLocal?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertBrowserHostSettings(settings: BrowserHostSettingsLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertBrowserHostSettings(settings: List<BrowserHostSettingsLocal>)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.BrowserTabLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class BrowserTabsDao {
|
||||
|
||||
@Query("SELECT id FROM browser_tabs WHERE metaId = :metaId")
|
||||
abstract fun getTabIdsFor(metaId: Long): List<String>
|
||||
|
||||
@Query("SELECT * FROM browser_tabs WHERE metaId = :metaId ORDER BY creationTime DESC")
|
||||
abstract fun observeTabsByMetaId(metaId: Long): Flow<List<BrowserTabLocal>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertTab(tab: BrowserTabLocal)
|
||||
|
||||
@Transaction
|
||||
open suspend fun removeTabsByMetaId(metaId: Long): List<String> {
|
||||
val tabIds = getTabIdsFor(metaId)
|
||||
removeTabsByIds(tabIds)
|
||||
return tabIds
|
||||
}
|
||||
|
||||
@Query("DELETE FROM browser_tabs WHERE id = :tabId")
|
||||
abstract suspend fun removeTab(tabId: String)
|
||||
|
||||
@Query("DELETE FROM browser_tabs WHERE id IN (:tabIds)")
|
||||
abstract suspend fun removeTabsByIds(tabIds: List<String>)
|
||||
|
||||
@Query("UPDATE browser_tabs SET pageName = :pageName, pageIconPath = :pageIconPath, pagePicturePath = :pagePicturePath WHERE id = :tabId")
|
||||
abstract suspend fun updatePageSnapshot(tabId: String, pageName: String?, pageIconPath: String?, pagePicturePath: String?)
|
||||
|
||||
@Query("UPDATE browser_tabs SET currentUrl = :url WHERE id = :tabId")
|
||||
abstract fun updateCurrentUrl(tabId: String, url: String)
|
||||
|
||||
@Query("UPDATE browser_tabs SET dappMetadata_iconLink = :dappIconUrl WHERE id = :tabId")
|
||||
abstract fun updateKnownDAppMetadata(tabId: String, dappIconUrl: String?)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.chain.AssetSourceLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
|
||||
typealias FullAssetIdLocal = Pair<String, Int>
|
||||
|
||||
@Dao
|
||||
abstract class ChainAssetDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateAssets(diff: CollectionDiffer.Diff<ChainAssetLocal>) {
|
||||
insertAssets(diff.newOrUpdated)
|
||||
deleteChainAssets(diff.removed)
|
||||
}
|
||||
|
||||
@Query("SELECT * FROM chain_assets WHERE id = :id AND chainId = :chainId")
|
||||
abstract suspend fun getAsset(id: Int, chainId: String): ChainAssetLocal?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertAsset(asset: ChainAssetLocal)
|
||||
|
||||
@Query("SELECT * FROM chain_assets WHERE source = :source")
|
||||
abstract suspend fun getAssetsBySource(source: AssetSourceLocal): List<ChainAssetLocal>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insertAssets(assets: List<ChainAssetLocal>)
|
||||
|
||||
@Query("UPDATE chain_assets SET enabled = :enabled WHERE chainId = :chainId AND id = :assetId")
|
||||
protected abstract suspend fun setAssetEnabled(enabled: Boolean, chainId: String, assetId: Int)
|
||||
|
||||
@Query("SELECT * FROM chain_assets WHERE enabled=1")
|
||||
abstract suspend fun getEnabledAssets(): List<ChainAssetLocal>
|
||||
|
||||
@Update(entity = ChainAssetLocal::class)
|
||||
abstract suspend fun setAssetsEnabled(params: List<SetAssetEnabledParams>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteChainAssets(assets: List<ChainAssetLocal>)
|
||||
}
|
||||
|
||||
class SetAssetEnabledParams(val enabled: Boolean, val chainId: String, val id: Int)
|
||||
@@ -0,0 +1,245 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainExplorerLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainExternalApiLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainNodeLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainRuntimeInfoLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.JoinedChainInfo
|
||||
import io.novafoundation.nova.core_db.model.chain.NodeSelectionPreferencesLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class ChainDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun applyDiff(
|
||||
chainDiff: CollectionDiffer.Diff<ChainLocal>,
|
||||
assetsDiff: CollectionDiffer.Diff<ChainAssetLocal>,
|
||||
nodesDiff: CollectionDiffer.Diff<ChainNodeLocal>,
|
||||
explorersDiff: CollectionDiffer.Diff<ChainExplorerLocal>,
|
||||
externalApisDiff: CollectionDiffer.Diff<ChainExternalApiLocal>,
|
||||
nodeSelectionPreferencesDiff: CollectionDiffer.Diff<NodeSelectionPreferencesLocal>
|
||||
) {
|
||||
deleteChains(chainDiff.removed)
|
||||
deleteChainAssets(assetsDiff.removed)
|
||||
deleteChainNodes(nodesDiff.removed)
|
||||
deleteChainExplorers(explorersDiff.removed)
|
||||
deleteExternalApis(externalApisDiff.removed)
|
||||
deleteNodePreferences(nodeSelectionPreferencesDiff.removed)
|
||||
|
||||
addChains(chainDiff.added)
|
||||
addChainAssets(assetsDiff.added)
|
||||
addChainNodes(nodesDiff.added)
|
||||
addChainExplorers(explorersDiff.added)
|
||||
addExternalApis(externalApisDiff.added)
|
||||
addNodePreferences(nodeSelectionPreferencesDiff.added)
|
||||
|
||||
updateChains(chainDiff.updated)
|
||||
updateChainAssets(assetsDiff.updated)
|
||||
updateChainNodes(nodesDiff.updated)
|
||||
updateChainExplorers(explorersDiff.updated)
|
||||
updateExternalApis(externalApisDiff.updated)
|
||||
updateNodePreferences(nodeSelectionPreferencesDiff.added)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun addChainOrUpdate(
|
||||
chain: ChainLocal,
|
||||
assets: List<ChainAssetLocal>,
|
||||
nodes: List<ChainNodeLocal>,
|
||||
explorers: List<ChainExplorerLocal>,
|
||||
externalApis: List<ChainExternalApiLocal>,
|
||||
nodeSelectionPreferences: NodeSelectionPreferencesLocal
|
||||
) {
|
||||
addChainOrUpdate(chain)
|
||||
addChainAssetsOrUpdate(assets)
|
||||
addChainNodesOrUpdate(nodes)
|
||||
addChainExplorersOrUpdate(explorers)
|
||||
addExternalApisOrUpdate(externalApis)
|
||||
addNodePreferencesOrUpdate(nodeSelectionPreferences)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun editChain(
|
||||
chainId: String,
|
||||
assetId: Int,
|
||||
chainName: String,
|
||||
symbol: String,
|
||||
explorer: ChainExplorerLocal?,
|
||||
priceId: String?
|
||||
) {
|
||||
updateChainName(chainId, chainName)
|
||||
updateAssetToken(chainId, assetId, symbol, priceId)
|
||||
addChainExplorersOrUpdate(listOfNotNull(explorer))
|
||||
}
|
||||
|
||||
// ------ Delete --------
|
||||
@Delete
|
||||
protected abstract suspend fun deleteChains(chains: List<ChainLocal>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteChainNodes(nodes: List<ChainNodeLocal>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteChainAssets(assets: List<ChainAssetLocal>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteChainExplorers(explorers: List<ChainExplorerLocal>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteExternalApis(apis: List<ChainExternalApiLocal>)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteNodePreferences(apis: List<NodeSelectionPreferencesLocal>)
|
||||
|
||||
// ------ Add --------
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addChains(chains: List<ChainLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addChainNodes(nodes: List<ChainNodeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addChainAssets(assets: List<ChainAssetLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addChainExplorers(explorers: List<ChainExplorerLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addExternalApis(apis: List<ChainExternalApiLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun addChainOrUpdate(node: ChainLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
abstract suspend fun addChainNode(node: ChainNodeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun addNodePreferences(model: List<NodeSelectionPreferencesLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun addNodePreferencesOrUpdate(model: NodeSelectionPreferencesLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun addChainNodesOrUpdate(nodes: List<ChainNodeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun addChainAssetsOrUpdate(assets: List<ChainAssetLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun addChainExplorersOrUpdate(explorers: List<ChainExplorerLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun addExternalApisOrUpdate(apis: List<ChainExternalApiLocal>)
|
||||
|
||||
// ------ Update -----
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateChains(chains: List<ChainLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateChainNodes(nodes: List<ChainNodeLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateChainAssets(assets: List<ChainAssetLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateChainExplorers(explorers: List<ChainExplorerLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateExternalApis(apis: List<ChainExternalApiLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateNodePreferences(apis: List<NodeSelectionPreferencesLocal>)
|
||||
|
||||
// ------- Queries ------
|
||||
|
||||
@Query("SELECT * FROM chains")
|
||||
@Transaction
|
||||
abstract suspend fun getJoinChainInfo(): List<JoinedChainInfo>
|
||||
|
||||
@Query("SELECT id FROM chains")
|
||||
@Transaction
|
||||
abstract suspend fun getAllChainIds(): List<String>
|
||||
|
||||
@Query("SELECT * FROM chains")
|
||||
@Transaction
|
||||
abstract fun joinChainInfoFlow(): Flow<List<JoinedChainInfo>>
|
||||
|
||||
@Query("SELECT orderId FROM chain_nodes WHERE chainId = :chainId ORDER BY orderId DESC LIMIT 1")
|
||||
abstract suspend fun getLastChainNodeOrderId(chainId: String): Int
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM chains WHERE id = :chainId)")
|
||||
abstract suspend fun chainExists(chainId: String): Boolean
|
||||
|
||||
@Query("SELECT * FROM chain_runtimes WHERE chainId = :chainId")
|
||||
abstract suspend fun runtimeInfo(chainId: String): ChainRuntimeInfoLocal?
|
||||
|
||||
@Query("SELECT * FROM chain_runtimes")
|
||||
abstract suspend fun allRuntimeInfos(): List<ChainRuntimeInfoLocal>
|
||||
|
||||
@Query("UPDATE chain_runtimes SET syncedVersion = :syncedVersion, localMigratorVersion = :localMigratorVersion WHERE chainId = :chainId")
|
||||
abstract suspend fun updateSyncedRuntimeVersion(chainId: String, syncedVersion: Int, localMigratorVersion: Int)
|
||||
|
||||
@Query("UPDATE chains SET connectionState = :connectionState WHERE id = :chainId")
|
||||
abstract suspend fun setConnectionState(chainId: String, connectionState: ChainLocal.ConnectionStateLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun setNodePreferences(model: NodeSelectionPreferencesLocal)
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateRemoteRuntimeVersionIfChainExists(
|
||||
chainId: String,
|
||||
runtimeVersion: Int,
|
||||
transactionVersion: Int,
|
||||
) {
|
||||
if (!chainExists(chainId)) return
|
||||
|
||||
if (isRuntimeInfoExists(chainId)) {
|
||||
updateRemoteRuntimeVersionUnsafe(chainId, runtimeVersion, transactionVersion)
|
||||
} else {
|
||||
val runtimeInfoLocal = ChainRuntimeInfoLocal(
|
||||
chainId,
|
||||
syncedVersion = 0,
|
||||
remoteVersion = runtimeVersion,
|
||||
transactionVersion = transactionVersion,
|
||||
localMigratorVersion = 1
|
||||
)
|
||||
insertRuntimeInfo(runtimeInfoLocal)
|
||||
}
|
||||
}
|
||||
|
||||
@Query("UPDATE chain_nodes SET url = :newUrl, name = :name WHERE chainId = :chainId AND url = :oldUrl")
|
||||
abstract suspend fun updateChainNode(chainId: String, oldUrl: String, newUrl: String, name: String)
|
||||
|
||||
@Query("UPDATE chain_runtimes SET remoteVersion = :remoteVersion, transactionVersion = :transactionVersion WHERE chainId = :chainId")
|
||||
protected abstract suspend fun updateRemoteRuntimeVersionUnsafe(chainId: String, remoteVersion: Int, transactionVersion: Int)
|
||||
|
||||
@Query("SELECT EXISTS (SELECT * FROM chain_runtimes WHERE chainId = :chainId)")
|
||||
protected abstract suspend fun isRuntimeInfoExists(chainId: String): Boolean
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insertRuntimeInfo(runtimeInfoLocal: ChainRuntimeInfoLocal)
|
||||
|
||||
@Query("UPDATE chains SET name = :name WHERE id = :chainId")
|
||||
abstract suspend fun updateChainName(chainId: String, name: String)
|
||||
|
||||
@Query("UPDATE chain_assets SET symbol = :symbol, priceId = :priceId WHERE chainId = :chainId and id == :assetId")
|
||||
abstract suspend fun updateAssetToken(chainId: String, assetId: Int, symbol: String, priceId: String?)
|
||||
|
||||
@Query("DELETE FROM chains WHERE id = :chainId")
|
||||
abstract suspend fun deleteChain(chainId: String)
|
||||
|
||||
@Query("DELETE FROM chain_nodes WHERE chainId = :chainId AND url = :url")
|
||||
abstract suspend fun deleteNode(chainId: String, url: String)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.CoinPriceLocal
|
||||
|
||||
@Dao
|
||||
interface CoinPriceDao {
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM coin_prices
|
||||
WHERE priceId = :priceId AND currencyId = :currencyId
|
||||
AND timestamp <= :timestamp
|
||||
ORDER BY timestamp DESC LIMIT 1
|
||||
"""
|
||||
)
|
||||
suspend fun getFloorCoinPriceAtTime(priceId: String, currencyId: String, timestamp: Long): CoinPriceLocal?
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT EXISTS(
|
||||
SELECT * FROM coin_prices
|
||||
WHERE priceId = :priceId AND currencyId = :currencyId
|
||||
AND timestamp >= :timestamp
|
||||
ORDER BY timestamp ASC LIMIT 1
|
||||
)
|
||||
"""
|
||||
)
|
||||
suspend fun hasCeilingCoinPriceAtTime(priceId: String, currencyId: String, timestamp: Long): Boolean
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM coin_prices
|
||||
WHERE priceId = :priceId AND currencyId = :currencyId
|
||||
AND timestamp BETWEEN :fromTimestamp AND :toTimestamp
|
||||
ORDER BY timestamp ASC
|
||||
"""
|
||||
)
|
||||
suspend fun getCoinPriceRange(priceId: String, currencyId: String, fromTimestamp: Long, toTimestamp: Long): List<CoinPriceLocal>
|
||||
|
||||
@Transaction
|
||||
suspend fun updateCoinPrices(priceId: String, currencyId: String, coinRates: List<CoinPriceLocal>) {
|
||||
deleteCoinPrices(priceId, currencyId)
|
||||
setCoinPrices(coinRates)
|
||||
}
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun setCoinPrices(coinPrices: List<CoinPriceLocal>)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
DELETE FROM coin_prices
|
||||
WHERE priceId = :priceId AND currencyId = :currencyId
|
||||
"""
|
||||
)
|
||||
fun deleteCoinPrices(priceId: String, currencyId: String)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.ContributionLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class ContributionDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateContributions(contributions: CollectionDiffer.Diff<ContributionLocal>) {
|
||||
insertContributions(contributions.added)
|
||||
updateContributions(contributions.updated)
|
||||
deleteContributions(contributions.removed)
|
||||
}
|
||||
|
||||
@Query("SELECT * FROM contributions WHERE metaId = :metaId AND chainId = :chainId AND assetId = :assetId")
|
||||
abstract fun observeContributions(metaId: Long, chainId: String, assetId: Int): Flow<List<ContributionLocal>>
|
||||
|
||||
@Query("SELECT * FROM contributions WHERE metaId = :metaId")
|
||||
abstract fun observeContributions(metaId: Long): Flow<List<ContributionLocal>>
|
||||
|
||||
@Query("SELECT * FROM contributions WHERE metaId = :metaId AND chainId = :chainId AND assetId = :assetId AND sourceId = :sourceId")
|
||||
abstract suspend fun getContributions(metaId: Long, chainId: String, assetId: Int, sourceId: String): List<ContributionLocal>
|
||||
|
||||
@Query("DELETE FROM contributions WHERE chainId = :chainId AND assetId = :assetId")
|
||||
abstract suspend fun deleteContributions(chainId: String, assetId: Int)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteContributions(contributions: List<ContributionLocal>)
|
||||
|
||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun updateContributions(contributions: List<ContributionLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insertContributions(contributions: List<ContributionLocal>)
|
||||
|
||||
@Delete(entity = ContributionLocal::class)
|
||||
abstract suspend fun deleteAssetContributions(params: List<DeleteAssetContributionsParams>)
|
||||
}
|
||||
|
||||
class DeleteAssetContributionsParams(val chainId: String, val assetId: Int)
|
||||
@@ -0,0 +1,61 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.CurrencyLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
private const val RETRIEVE_CURRENCIES = "SELECT * FROM currencies"
|
||||
|
||||
private const val RETRIEVE_SELECTED_CURRENCY = "SELECT * FROM currencies WHERE selected = 1"
|
||||
|
||||
@Dao
|
||||
abstract class CurrencyDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateCurrencies(currencies: CollectionDiffer.Diff<CurrencyLocal>) {
|
||||
deleteCurrencies(currencies.removed)
|
||||
insertCurrencies(currencies.added)
|
||||
updateCurrencies(currencies.updated)
|
||||
|
||||
if (getSelectedCurrency() == null) {
|
||||
selectCurrency(0)
|
||||
}
|
||||
}
|
||||
|
||||
@Query("SELECT * FROM currencies WHERE id = 0")
|
||||
abstract fun getFirst(): CurrencyLocal
|
||||
|
||||
@Query(RETRIEVE_CURRENCIES)
|
||||
abstract suspend fun getCurrencies(): List<CurrencyLocal>
|
||||
|
||||
@Query(RETRIEVE_CURRENCIES)
|
||||
abstract fun observeCurrencies(): Flow<List<CurrencyLocal>>
|
||||
|
||||
@Query(RETRIEVE_SELECTED_CURRENCY)
|
||||
abstract suspend fun getSelectedCurrency(): CurrencyLocal?
|
||||
|
||||
@Query(RETRIEVE_SELECTED_CURRENCY)
|
||||
abstract fun observeSelectCurrency(): Flow<CurrencyLocal>
|
||||
|
||||
@Query("UPDATE currencies SET selected = (id = :currencyId)")
|
||||
abstract fun selectCurrency(currencyId: Int)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
abstract suspend fun insert(currency: CurrencyLocal)
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteCurrencies(currencies: List<CurrencyLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
protected abstract suspend fun insertCurrencies(currencies: List<CurrencyLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateCurrencies(currencies: List<CurrencyLocal>)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.DappAuthorizationLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface DappAuthorizationDao {
|
||||
|
||||
@Query("SELECT * FROM dapp_authorizations WHERE baseUrl = :baseUrl AND metaId = :metaId")
|
||||
suspend fun getAuthorization(baseUrl: String, metaId: Long): DappAuthorizationLocal?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun updateAuthorization(dappAuthorization: DappAuthorizationLocal)
|
||||
|
||||
@Query("UPDATE dapp_authorizations SET authorized = 0 WHERE baseUrl = :baseUrl AND metaId = :metaId")
|
||||
suspend fun removeAuthorization(baseUrl: String, metaId: Long)
|
||||
|
||||
@Query("SELECT * FROM dapp_authorizations WHERE metaId = :metaId")
|
||||
fun observeAuthorizations(metaId: Long): Flow<List<DappAuthorizationLocal>>
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.AggregatedExternalBalanceLocal
|
||||
import io.novafoundation.nova.core_db.model.ExternalBalanceLocal
|
||||
import io.novasama.substrate_sdk_android.hash.isPositive
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface ExternalBalanceDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertExternalBalance(externalBalance: ExternalBalanceLocal)
|
||||
|
||||
@Query("DELETE FROM externalBalances WHERE metaId = :metaId AND chainId = :chainId AND assetId = :assetId AND type = :type AND subtype = :subtype")
|
||||
suspend fun removeExternalBalance(
|
||||
metaId: Long,
|
||||
chainId: String,
|
||||
assetId: Int,
|
||||
type: ExternalBalanceLocal.Type,
|
||||
subtype: String?,
|
||||
)
|
||||
|
||||
@Delete(entity = ExternalBalanceLocal::class)
|
||||
suspend fun deleteAssetExternalBalances(params: List<ExternalBalanceAssetDeleteParams>)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT chainId, assetId, type, SUM(amount) as aggregatedAmount
|
||||
FROM externalBalances
|
||||
WHERE metaId = :metaId
|
||||
GROUP BY chainId, assetId, type
|
||||
"""
|
||||
)
|
||||
fun observeAggregatedExternalBalances(metaId: Long): Flow<List<AggregatedExternalBalanceLocal>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT chainId, assetId, type, SUM(amount) as aggregatedAmount
|
||||
FROM externalBalances
|
||||
WHERE metaId = :metaId AND chainId = :chainId AND assetId = :assetId
|
||||
GROUP BY type
|
||||
"""
|
||||
)
|
||||
fun observeChainAggregatedExternalBalances(metaId: Long, chainId: String, assetId: Int): Flow<List<AggregatedExternalBalanceLocal>>
|
||||
}
|
||||
|
||||
suspend fun ExternalBalanceDao.updateExternalBalance(externalBalance: ExternalBalanceLocal) {
|
||||
if (externalBalance.amount.isPositive()) {
|
||||
insertExternalBalance(externalBalance)
|
||||
} else {
|
||||
removeExternalBalance(
|
||||
metaId = externalBalance.metaId,
|
||||
chainId = externalBalance.chainId,
|
||||
assetId = externalBalance.assetId,
|
||||
type = externalBalance.type,
|
||||
subtype = externalBalance.subtype
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ExternalBalanceAssetDeleteParams(val chainId: String, val assetId: Int)
|
||||
@@ -0,0 +1,34 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.core_db.model.FavouriteDAppLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface FavouriteDAppsDao {
|
||||
|
||||
@Query("SELECT * FROM favourite_dapps")
|
||||
fun observeFavouriteDApps(): Flow<List<FavouriteDAppLocal>>
|
||||
|
||||
@Query("SELECT * FROM favourite_dapps")
|
||||
suspend fun getFavouriteDApps(): List<FavouriteDAppLocal>
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM favourite_dapps WHERE url = :dAppUrl)")
|
||||
fun observeIsFavourite(dAppUrl: String): Flow<Boolean>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertFavouriteDApp(dApp: FavouriteDAppLocal)
|
||||
|
||||
@Query("DELETE FROM favourite_dapps WHERE url = :dAppUrl")
|
||||
suspend fun deleteFavouriteDApp(dAppUrl: String)
|
||||
|
||||
@Update(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun updateFavourites(dapps: List<FavouriteDAppLocal>)
|
||||
|
||||
@Query("SELECT MAX(orderingIndex) FROM favourite_dapps")
|
||||
suspend fun getMaxOrderingIndex(): Int
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.GiftLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface GiftsDao {
|
||||
|
||||
@Query("SELECT * from gifts WHERE id = :id")
|
||||
suspend fun getGiftById(id: Long): GiftLocal
|
||||
|
||||
@Query("SELECT * from gifts")
|
||||
suspend fun getAllGifts(): List<GiftLocal>
|
||||
|
||||
@Query("SELECT * from gifts WHERE id = :id")
|
||||
fun observeGiftById(id: Long): Flow<GiftLocal>
|
||||
|
||||
@Query("SELECT * from gifts")
|
||||
fun observeAllGifts(): Flow<List<GiftLocal>>
|
||||
|
||||
@Query("SELECT * from gifts WHERE chainId = :chainId AND assetId = :assetId")
|
||||
fun observeGiftsByAsset(chainId: String, assetId: Int): Flow<List<GiftLocal>>
|
||||
|
||||
@Insert
|
||||
suspend fun createNewGift(giftLocal: GiftLocal): Long
|
||||
|
||||
@Query("UPDATE gifts SET status = :status WHERE id = :id")
|
||||
suspend fun setGiftState(id: Long, status: GiftLocal.Status)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.GovernanceDAppLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class GovernanceDAppsDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun update(newDapps: List<GovernanceDAppLocal>) {
|
||||
val oldDapps = getAll()
|
||||
val dappDiffs = CollectionDiffer.findDiff(newDapps, oldDapps, false)
|
||||
|
||||
deleteDapps(dappDiffs.removed)
|
||||
updateDapps(dappDiffs.updated)
|
||||
insertDapps(dappDiffs.added)
|
||||
}
|
||||
|
||||
@Query("SELECT * FROM governance_dapps")
|
||||
abstract fun getAll(): List<GovernanceDAppLocal>
|
||||
|
||||
@Query("SELECT * FROM governance_dapps WHERE chainId = :chainId")
|
||||
abstract fun observeChainDapps(chainId: String): Flow<List<GovernanceDAppLocal>>
|
||||
|
||||
@Delete
|
||||
abstract suspend fun deleteDapps(dapps: List<GovernanceDAppLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.ABORT)
|
||||
abstract suspend fun insertDapps(dapps: List<GovernanceDAppLocal>)
|
||||
|
||||
@Update
|
||||
abstract suspend fun updateDapps(dapps: List<GovernanceDAppLocal>)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.BalanceHoldLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class HoldsDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateHolds(
|
||||
holds: List<BalanceHoldLocal>,
|
||||
metaId: Long,
|
||||
chainId: String,
|
||||
chainAssetId: Int
|
||||
) {
|
||||
deleteHolds(metaId, chainId, chainAssetId)
|
||||
|
||||
insert(holds)
|
||||
}
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract fun insert(holds: List<BalanceHoldLocal>)
|
||||
|
||||
@Query("DELETE FROM holds WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId")
|
||||
protected abstract fun deleteHolds(metaId: Long, chainId: String, chainAssetId: Int)
|
||||
|
||||
@Query("SELECT * FROM holds WHERE metaId = :metaId")
|
||||
abstract fun observeHoldsForMetaAccount(metaId: Long): Flow<List<BalanceHoldLocal>>
|
||||
|
||||
@Query("SELECT * FROM holds WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId")
|
||||
abstract fun observeBalanceHolds(metaId: Long, chainId: String, chainAssetId: Int): Flow<List<BalanceHoldLocal>>
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.BalanceLockLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class LockDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateLocks(
|
||||
locks: List<BalanceLockLocal>,
|
||||
metaId: Long,
|
||||
chainId: String,
|
||||
chainAssetId: Int
|
||||
) {
|
||||
deleteLocks(metaId, chainId, chainAssetId)
|
||||
|
||||
insert(locks)
|
||||
}
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract fun insert(locks: List<BalanceLockLocal>)
|
||||
|
||||
@Query("DELETE FROM locks WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId")
|
||||
abstract fun deleteLocks(metaId: Long, chainId: String, chainAssetId: Int)
|
||||
|
||||
@Query("SELECT * FROM locks WHERE metaId = :metaId")
|
||||
abstract fun observeLocksForMetaAccount(metaId: Long): Flow<List<BalanceLockLocal>>
|
||||
|
||||
@Query("SELECT * FROM locks WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId")
|
||||
abstract fun observeBalanceLocks(metaId: Long, chainId: String, chainAssetId: Int): Flow<List<BalanceLockLocal>>
|
||||
|
||||
@Query("SELECT * FROM locks WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId")
|
||||
abstract suspend fun getBalanceLocks(metaId: Long, chainId: String, chainAssetId: Int): List<BalanceLockLocal>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM locks
|
||||
WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId
|
||||
ORDER BY amount DESC
|
||||
LIMIT 1
|
||||
"""
|
||||
)
|
||||
abstract suspend fun getBiggestBalanceLock(metaId: Long, chainId: String, chainAssetId: Int): BalanceLockLocal?
|
||||
|
||||
@Query("SELECT * FROM locks WHERE metaId = :metaId AND chainId = :chainId AND assetId = :chainAssetId AND type = :lockId")
|
||||
abstract fun observeBalanceLock(metaId: Long, chainId: String, chainAssetId: Int, lockId: String): Flow<BalanceLockLocal?>
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.core_db.model.chain.account.ChainAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountIdWithType
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountPositionUpdate
|
||||
import io.novafoundation.nova.core_db.model.chain.account.ProxyAccountLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.account.RelationJoinedMetaAccountInfo
|
||||
import io.novasama.substrate_sdk_android.runtime.AccountId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.intellij.lang.annotations.Language
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
/**
|
||||
* Fetch meta account where either
|
||||
* 1. chain account for specified chain is present and its accountId matches
|
||||
* 2. chain account for specified is missing but one of base accountIds matches
|
||||
*
|
||||
* Note that if both chain account and base accounts are present than we should filter out entries where chain account matches but base accounts does not
|
||||
*/
|
||||
@Language("RoomSql")
|
||||
private const val FIND_BY_ADDRESS_WHERE_CLAUSE = """
|
||||
LEFT JOIN chain_accounts as c ON m.id = c.metaId AND c.chainId = :chainId
|
||||
WHERE
|
||||
(c.accountId IS NOT NULL AND c.accountId = :accountId)
|
||||
OR (c.accountId IS NULL AND (substrateAccountId = :accountId OR ethereumAddress = :accountId))
|
||||
ORDER BY (CASE WHEN isSelected THEN 0 ELSE 1 END)
|
||||
"""
|
||||
|
||||
@Language("RoomSql")
|
||||
private const val FIND_ACCOUNT_BY_ADDRESS_QUERY = """
|
||||
SELECT * FROM meta_accounts as m
|
||||
$FIND_BY_ADDRESS_WHERE_CLAUSE
|
||||
"""
|
||||
|
||||
@Language("RoomSql")
|
||||
private const val FIND_NAME_BY_ADDRESS_QUERY = """
|
||||
SELECT name FROM meta_accounts as m
|
||||
$FIND_BY_ADDRESS_WHERE_CLAUSE
|
||||
"""
|
||||
|
||||
@Language("RoomSql")
|
||||
private const val META_ACCOUNTS_WITH_BALANCE_PART = """
|
||||
SELECT
|
||||
m.id,
|
||||
a.freeInPlanks,
|
||||
a.reservedInPlanks,
|
||||
(SELECT SUM(amountInPlanks) FROM contributions WHERE chainId = a.chainId AND assetId = a.assetId AND metaId = m.id) offChainBalance,
|
||||
ca.precision,
|
||||
t.rate
|
||||
FROM meta_accounts as m
|
||||
INNER JOIN assets as a ON a.metaId = m.id
|
||||
INNER JOIN chain_assets AS ca ON a.assetId = ca.id AND a.chainId = ca.chainId
|
||||
INNER JOIN currencies as currency ON currency.selected = 1
|
||||
INNER JOIN tokens as t ON t.tokenSymbol = ca.symbol AND t.currencyId = currency.id
|
||||
"""
|
||||
|
||||
@Language("RoomSql")
|
||||
private const val META_ACCOUNTS_WITH_BALANCE_QUERY = """
|
||||
$META_ACCOUNTS_WITH_BALANCE_PART
|
||||
ORDER BY m.position
|
||||
"""
|
||||
|
||||
@Language("RoomSql")
|
||||
private const val META_ACCOUNT_WITH_BALANCE_QUERY = """
|
||||
$META_ACCOUNTS_WITH_BALANCE_PART
|
||||
WHERE m.id == :metaId
|
||||
"""
|
||||
|
||||
@Dao
|
||||
interface MetaAccountDao {
|
||||
|
||||
@Transaction
|
||||
suspend fun insertProxiedMetaAccount(
|
||||
metaAccount: MetaAccountLocal,
|
||||
chainAccount: (metaId: Long) -> ChainAccountLocal,
|
||||
proxyAccount: (metaId: Long) -> ProxyAccountLocal
|
||||
): Long {
|
||||
val metaId = insertMetaAccount(metaAccount)
|
||||
insertChainAccount(chainAccount(metaId))
|
||||
insertProxy(proxyAccount(metaId))
|
||||
|
||||
return metaId
|
||||
}
|
||||
|
||||
@Transaction
|
||||
suspend fun runInTransaction(action: suspend () -> Unit) {
|
||||
action()
|
||||
}
|
||||
|
||||
@Insert
|
||||
suspend fun insertMetaAccount(metaAccount: MetaAccountLocal): Long
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun updateMetaAccount(metaAccount: MetaAccountLocal): Long
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertChainAccount(chainAccount: ChainAccountLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertChainAccounts(chainAccounts: List<ChainAccountLocal>)
|
||||
|
||||
@Delete
|
||||
suspend fun deleteChainAccounts(chainAccounts: List<ChainAccountLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertProxy(proxyLocal: ProxyAccountLocal)
|
||||
|
||||
@Query("SELECT * FROM meta_accounts")
|
||||
suspend fun getMetaAccounts(): List<MetaAccountLocal>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE id IN (:metaIds)")
|
||||
suspend fun getMetaAccountsByIds(metaIds: List<Long>): List<RelationJoinedMetaAccountInfo>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE id = :id")
|
||||
suspend fun getMetaAccount(id: Long): MetaAccountLocal?
|
||||
|
||||
@Query("SELECT COUNT(*) FROM meta_accounts WHERE status = :status")
|
||||
@Transaction
|
||||
suspend fun getMetaAccountsQuantityByStatus(status: MetaAccountLocal.Status): Int
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE status = :status")
|
||||
@Transaction
|
||||
suspend fun getMetaAccountsByStatus(status: MetaAccountLocal.Status): List<RelationJoinedMetaAccountInfo>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts")
|
||||
@Transaction
|
||||
suspend fun getFullMetaAccounts(): List<RelationJoinedMetaAccountInfo>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts")
|
||||
fun getJoinedMetaAccountsInfoFlow(): Flow<List<RelationJoinedMetaAccountInfo>>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE status = :status")
|
||||
fun getJoinedMetaAccountsInfoByStatusFlow(status: MetaAccountLocal.Status): Flow<List<RelationJoinedMetaAccountInfo>>
|
||||
|
||||
@Query("SELECT id FROM meta_accounts WHERE status = :status")
|
||||
fun getMetaAccountsIdsByStatus(status: MetaAccountLocal.Status): List<Long>
|
||||
|
||||
@Query(META_ACCOUNTS_WITH_BALANCE_QUERY)
|
||||
fun metaAccountsWithBalanceFlow(): Flow<List<MetaAccountWithBalanceLocal>>
|
||||
|
||||
@Query(META_ACCOUNT_WITH_BALANCE_QUERY)
|
||||
fun metaAccountWithBalanceFlow(metaId: Long): Flow<List<MetaAccountWithBalanceLocal>>
|
||||
|
||||
@Query("UPDATE meta_accounts SET isSelected = (id = :metaId)")
|
||||
suspend fun selectMetaAccount(metaId: Long)
|
||||
|
||||
@Update(entity = MetaAccountLocal::class)
|
||||
suspend fun updatePositions(updates: List<MetaAccountPositionUpdate>)
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE id = :metaId")
|
||||
@Transaction
|
||||
suspend fun getJoinedMetaAccountInfo(metaId: Long): RelationJoinedMetaAccountInfo
|
||||
|
||||
@Query("SELECT type FROM meta_accounts WHERE id = :metaId")
|
||||
suspend fun getMetaAccountType(metaId: Long): MetaAccountLocal.Type?
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE isSelected = 1")
|
||||
@Transaction
|
||||
fun selectedMetaAccountInfoFlow(): Flow<RelationJoinedMetaAccountInfo?>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE id = :metaId")
|
||||
@Transaction
|
||||
fun metaAccountInfoFlow(metaId: Long): Flow<RelationJoinedMetaAccountInfo?>
|
||||
|
||||
@Query("SELECT EXISTS ($FIND_ACCOUNT_BY_ADDRESS_QUERY)")
|
||||
fun isMetaAccountExists(accountId: AccountId, chainId: String): Boolean
|
||||
|
||||
@Query(FIND_ACCOUNT_BY_ADDRESS_QUERY)
|
||||
@Transaction
|
||||
fun getMetaAccountInfo(accountId: AccountId, chainId: String): RelationJoinedMetaAccountInfo?
|
||||
|
||||
@Query(FIND_NAME_BY_ADDRESS_QUERY)
|
||||
fun metaAccountNameFor(accountId: AccountId, chainId: String): String?
|
||||
|
||||
@Query("UPDATE meta_accounts SET name = :newName WHERE id = :metaId")
|
||||
suspend fun updateName(metaId: Long, newName: String)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
WITH RECURSIVE accounts_to_delete AS (
|
||||
SELECT id, parentMetaId, type FROM meta_accounts WHERE id IN (:metaIds)
|
||||
UNION ALL
|
||||
SELECT m.id, m.parentMetaId, m.type
|
||||
FROM meta_accounts m
|
||||
JOIN accounts_to_delete r ON m.parentMetaId = r.id
|
||||
)
|
||||
SELECT id, type FROM accounts_to_delete
|
||||
"""
|
||||
)
|
||||
suspend fun findAffectedMetaIdsOnDelete(metaIds: List<Long>): List<MetaAccountIdWithType>
|
||||
|
||||
@Query("DELETE FROM meta_accounts WHERE id IN (:ids)")
|
||||
suspend fun deleteByIds(ids: List<Long>)
|
||||
|
||||
@Transaction
|
||||
suspend fun delete(vararg metaId: Long): List<MetaAccountIdWithType> {
|
||||
val affectingMetaAccounts = findAffectedMetaIdsOnDelete(metaId.toList())
|
||||
if (affectingMetaAccounts.isNotEmpty()) {
|
||||
val ids = affectingMetaAccounts.map { it.id }
|
||||
deleteByIds(ids)
|
||||
}
|
||||
return affectingMetaAccounts
|
||||
}
|
||||
|
||||
@Transaction
|
||||
suspend fun delete(metaIds: List<Long>): List<MetaAccountIdWithType> {
|
||||
return delete(*metaIds.toLongArray())
|
||||
}
|
||||
|
||||
@Query("SELECT COALESCE(MAX(position), 0) + 1 FROM meta_accounts")
|
||||
suspend fun nextAccountPosition(): Int
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE isSelected = 1")
|
||||
suspend fun selectedMetaAccount(): RelationJoinedMetaAccountInfo?
|
||||
|
||||
@Query("SELECT EXISTS(SELECT id FROM meta_accounts WHERE type = :type)")
|
||||
fun hasMetaAccountsCountOfTypeFlow(type: MetaAccountLocal.Type): Flow<Boolean>
|
||||
|
||||
@Query("SELECT * FROM meta_accounts WHERE type = :type")
|
||||
fun observeMetaAccountsByTypeFlow(type: MetaAccountLocal.Type): Flow<List<RelationJoinedMetaAccountInfo>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
DELETE FROM meta_accounts
|
||||
WHERE id IN (
|
||||
SELECT proxiedMetaId
|
||||
FROM proxy_accounts
|
||||
WHERE chainId = :chainId
|
||||
)
|
||||
"""
|
||||
)
|
||||
fun deleteProxiedMetaAccountsByChain(chainId: String)
|
||||
|
||||
@Transaction
|
||||
suspend fun insertMetaAndChainAccounts(
|
||||
metaAccount: MetaAccountLocal,
|
||||
createChainAccounts: suspend (metaId: Long) -> List<ChainAccountLocal>
|
||||
): Long {
|
||||
val metaId = insertMetaAccount(metaAccount)
|
||||
|
||||
insertChainAccounts(createChainAccounts(metaId))
|
||||
|
||||
return metaId
|
||||
}
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM meta_accounts WHERE status = :status)")
|
||||
suspend fun hasMetaAccountsByStatus(status: MetaAccountLocal.Status): Boolean
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM meta_accounts WHERE type = :type)")
|
||||
suspend fun hasMetaAccountsByType(type: MetaAccountLocal.Type): Boolean
|
||||
|
||||
@Query("SELECT EXISTS(SELECT * FROM meta_accounts WHERE id IN (:metaIds) AND type = :type)")
|
||||
suspend fun hasMetaAccountsByType(metaIds: Set<Long>, type: MetaAccountLocal.Type): Boolean
|
||||
|
||||
@Query("UPDATE meta_accounts SET status = :status WHERE id IN (:metaIds)")
|
||||
suspend fun changeAccountsStatus(metaIds: List<Long>, status: MetaAccountLocal.Status)
|
||||
|
||||
@Query("DELETE FROM meta_accounts WHERE status = :status ")
|
||||
fun removeMetaAccountsByStatus(status: MetaAccountLocal.Status)
|
||||
}
|
||||
|
||||
suspend inline fun <T : Any> MetaAccountDao.withTransaction(crossinline action: suspend () -> T): T {
|
||||
var result: T? = null
|
||||
|
||||
runInTransaction {
|
||||
result = action()
|
||||
}
|
||||
|
||||
return result!!
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
suspend fun MetaAccountDao.updateMetaAccount(metaId: Long, updateClosure: (MetaAccountLocal) -> MetaAccountLocal) {
|
||||
contract {
|
||||
callsInPlace(updateClosure, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val metaAccount = requireNotNull(getMetaAccount(metaId)) {
|
||||
"Meta account $metaId was not found"
|
||||
}
|
||||
|
||||
val updated = updateClosure(metaAccount)
|
||||
require(updated.id == metaId) {
|
||||
"Cannot modify metaId"
|
||||
}
|
||||
|
||||
updateMetaAccount(updated)
|
||||
}
|
||||
|
||||
class MetaAccountWithBalanceLocal(
|
||||
val id: Long,
|
||||
val freeInPlanks: BigInteger,
|
||||
val reservedInPlanks: BigInteger,
|
||||
val offChainBalance: BigInteger?,
|
||||
val precision: Int,
|
||||
val rate: BigDecimal?
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.MultisigOperationCallLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class MultisigOperationsDao {
|
||||
|
||||
@Query("SELECT * FROM multisig_operation_call")
|
||||
abstract fun observeOperations(): Flow<List<MultisigOperationCallLocal>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertOperation(operation: MultisigOperationCallLocal)
|
||||
|
||||
@Query("DELETE FROM multisig_operation_call WHERE metaId = :metaId AND chainId = :chainId AND callHash NOT IN (:excludedCallHashes)")
|
||||
abstract fun removeOperationsExclude(metaId: Long, chainId: String, excludedCallHashes: List<String>)
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.NftLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class NftDao {
|
||||
|
||||
@Query("SELECT * FROM nfts WHERE metaId = :metaId")
|
||||
abstract fun nftsFlow(metaId: Long): Flow<List<NftLocal>>
|
||||
|
||||
@Query("SELECT * FROM nfts WHERE metaId = :metaId AND type = :type AND chainId = :chainId")
|
||||
abstract suspend fun getNfts(chainId: String, metaId: Long, type: NftLocal.Type): List<NftLocal>
|
||||
|
||||
@Delete
|
||||
protected abstract suspend fun deleteNfts(nfts: List<NftLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insertNfts(nfts: List<NftLocal>)
|
||||
|
||||
@Update
|
||||
protected abstract suspend fun updateNft(nft: NftLocal)
|
||||
|
||||
@Query("SELECT * FROM nfts WHERE identifier = :nftIdentifier")
|
||||
abstract suspend fun getNft(nftIdentifier: String): NftLocal
|
||||
|
||||
@Query("SELECT type FROM nfts WHERE identifier = :nftIdentifier")
|
||||
abstract suspend fun getNftType(nftIdentifier: String): NftLocal.Type
|
||||
|
||||
@Query("UPDATE nfts SET wholeDetailsLoaded = 1 WHERE identifier = :nftIdentifier")
|
||||
abstract suspend fun markFullSynced(nftIdentifier: String)
|
||||
|
||||
@Transaction
|
||||
open suspend fun insertNftsDiff(
|
||||
nftType: NftLocal.Type,
|
||||
chainId: String,
|
||||
metaId: Long,
|
||||
newNfts: List<NftLocal>,
|
||||
forceOverwrite: Boolean
|
||||
) {
|
||||
val oldNfts = getNfts(chainId, metaId, nftType)
|
||||
|
||||
val diff = CollectionDiffer.findDiff(newNfts, oldNfts, forceUseNewItems = forceOverwrite)
|
||||
|
||||
deleteNfts(diff.removed)
|
||||
insertNfts(diff.newOrUpdated)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun updateNft(nftIdentifier: String, update: (NftLocal) -> NftLocal) {
|
||||
val nft = getNft(nftIdentifier)
|
||||
|
||||
val updated = update(nft)
|
||||
|
||||
updateNft(updated)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.NodeLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class NodeDao {
|
||||
|
||||
@Query("select * from nodes")
|
||||
abstract fun nodesFlow(): Flow<List<NodeLocal>>
|
||||
|
||||
@Query("select * from nodes")
|
||||
abstract suspend fun getNodes(): List<NodeLocal>
|
||||
|
||||
@Query("select * from nodes where link = :link")
|
||||
abstract suspend fun getNode(link: String): NodeLocal
|
||||
|
||||
@Query("select * from nodes where id = :id")
|
||||
abstract suspend fun getNodeById(id: Int): NodeLocal
|
||||
|
||||
@Query("select count(*) from nodes where link = :nodeHost")
|
||||
abstract suspend fun getNodesCountByHost(nodeHost: String): Int
|
||||
|
||||
@Query("select exists (select * from nodes where link = :nodeHost)")
|
||||
abstract suspend fun checkNodeExists(nodeHost: String): Boolean
|
||||
|
||||
@Query("DELETE FROM nodes where link = :link")
|
||||
abstract suspend fun remove(link: String)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(nodes: List<NodeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(nodes: NodeLocal): Long
|
||||
|
||||
@Query("update nodes set name = :newName, link = :newHost, networkType = :networkType where id = :id")
|
||||
abstract suspend fun updateNode(id: Int, newName: String, newHost: String, networkType: Int)
|
||||
|
||||
@Query("SELECT * from nodes where isDefault = 1 AND networkType = :networkType")
|
||||
abstract suspend fun getDefaultNodeFor(networkType: Int): NodeLocal
|
||||
|
||||
@Query("select * from nodes limit 1")
|
||||
abstract suspend fun getFirstNode(): NodeLocal
|
||||
|
||||
@Query("delete from nodes where id = :nodeId")
|
||||
abstract suspend fun deleteNode(nodeId: Int)
|
||||
|
||||
@Query("UPDATE nodes SET isActive = 1 WHERE id = :newActiveNodeId")
|
||||
protected abstract suspend fun makeActive(newActiveNodeId: Int)
|
||||
|
||||
@Query("UPDATE nodes SET isActive = 0 WHERE isActive = 1")
|
||||
protected abstract suspend fun inactiveCurrentNode()
|
||||
|
||||
@Query("SELECT * FROM nodes WHERE isActive = 1")
|
||||
abstract fun activeNodeFlow(): Flow<NodeLocal?>
|
||||
|
||||
@Transaction
|
||||
open suspend fun switchActiveNode(newNodeId: Int) {
|
||||
inactiveCurrentNode()
|
||||
|
||||
makeActive(newNodeId)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.common.utils.mapNotNullToSet
|
||||
import io.novafoundation.nova.core_db.model.operation.DirectRewardTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.ExtrinsicTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationBaseLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationJoin
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.OperationTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.PoolRewardTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.SwapTypeLocal
|
||||
import io.novafoundation.nova.core_db.model.operation.TransferTypeLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
private const val ID_FILTER = "address = :address AND chainId = :chainId AND assetId = :chainAssetId"
|
||||
|
||||
@Dao
|
||||
abstract class OperationDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertOperationBase(operation: OperationBaseLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertTransferType(type: TransferTypeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertDirectRewardType(type: DirectRewardTypeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertPoolRewardType(type: PoolRewardTypeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertExtrinsicType(type: ExtrinsicTypeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertSwapType(type: SwapTypeLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertOperationsBase(operations: List<OperationBaseLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertTransferTypes(types: List<TransferTypeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertDirectRewardTypes(types: List<DirectRewardTypeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertPoolRewardTypes(types: List<PoolRewardTypeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertExtrinsicTypes(types: List<ExtrinsicTypeLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertSwapTypes(types: List<SwapTypeLocal>)
|
||||
|
||||
@Transaction
|
||||
open suspend fun insert(operation: OperationLocal) {
|
||||
insertOperationBase(operation.base)
|
||||
insertOperationType(operation.type)
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun insertAll(operations: List<OperationLocal>) {
|
||||
insertAllInternal(operations)
|
||||
}
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT
|
||||
o.assetId as o_assetId, o.chainId o_chainId, o.id as o_id, o.address as o_address, o.time o_time, o.status as o_status, o.source o_source, o.hash as o_hash,
|
||||
t.amount as t_amount, t.fee as t_fee, t.sender as t_sender, t.receiver as t_receiver,
|
||||
e.contentType as e_contentType, e.module as e_module, e.call as e_call, e.fee as e_fee,
|
||||
rd.isReward as rd_isReward, rd.amount as rd_amount, rd.validator as rd_validator, rd.era as rd_era, rd.eventId as rd_eventId,
|
||||
rp.isReward as rp_isReward, rp.amount as rp_amount, rp.poolId as rp_poolId, rp.eventId as rp_eventId,
|
||||
s.fee_chainId as s_fee_chainId, s.fee_assetId as s_fee_assetId, s.fee_amount as s_fee_amount,
|
||||
s.assetIn_chainId as s_assetIn_chainId, s.assetIn_assetId as s_assetIn_assetId, s.assetIn_amount as s_assetIn_amount,
|
||||
s.assetOut_chainId as s_assetOut_chainId, s.assetOut_assetId as s_assetOut_assetId, s.assetOut_amount as s_assetOut_amount
|
||||
FROM operations as o
|
||||
LEFT JOIN operation_transfers as t ON t.operationId = o.id AND t.assetId = o.assetId AND t.chainId = o.chainId AND t.address = o.address
|
||||
LEFT JOIN operation_extrinsics as e ON e.operationId = o.id AND e.assetId = o.assetId AND e.chainId = o.chainId AND e.address = o.address
|
||||
LEFT JOIN operation_rewards_direct as rd ON rd.operationId = o.id AND rd.assetId = o.assetId AND rd.chainId = o.chainId AND rd.address = o.address
|
||||
LEFT JOIN operation_rewards_pool as rp ON rp.operationId = o.id AND rp.assetId = o.assetId AND rp.chainId = o.chainId AND rp.address = o.address
|
||||
LEFT JOIN operation_swaps as s ON s.operationId = o.id AND s.assetId = o.assetId AND s.chainId = o.chainId AND s.address = o.address
|
||||
WHERE o.address = :address AND o.chainId = :chainId AND o.assetId = :chainAssetId
|
||||
ORDER BY (case when o.status = :statusUp then 0 else 1 end), o.time DESC
|
||||
"""
|
||||
)
|
||||
abstract fun observe(
|
||||
address: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
statusUp: OperationBaseLocal.Status = OperationBaseLocal.Status.PENDING
|
||||
): Flow<List<OperationJoin>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM operation_transfers
|
||||
WHERE address = :address AND chainId = :chainId AND assetId = :chainAssetId AND operationId = :operationId
|
||||
"""
|
||||
)
|
||||
abstract suspend fun getTransferType(
|
||||
operationId: String,
|
||||
address: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int
|
||||
): TransferTypeLocal?
|
||||
|
||||
@Transaction
|
||||
open suspend fun insertFromRemote(
|
||||
accountAddress: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
operations: List<OperationLocal>
|
||||
) {
|
||||
clearBySource(accountAddress, chainId, chainAssetId, OperationBaseLocal.Source.REMOTE)
|
||||
|
||||
val operationsWithHashes = operations.mapNotNullToSet { it.base.hash }
|
||||
if (operationsWithHashes.isNotEmpty()) {
|
||||
clearByHashes(accountAddress, chainId, chainAssetId, operationsWithHashes)
|
||||
}
|
||||
|
||||
val oldestTime = operations.minOfOrNull { it.base.time }
|
||||
oldestTime?.let {
|
||||
clearOld(accountAddress, chainId, chainAssetId, oldestTime)
|
||||
}
|
||||
|
||||
insertAllInternal(operations)
|
||||
}
|
||||
|
||||
@Query("DELETE FROM operations WHERE $ID_FILTER AND source = :source")
|
||||
protected abstract suspend fun clearBySource(
|
||||
address: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
source: OperationBaseLocal.Source
|
||||
): Int
|
||||
|
||||
@Query("DELETE FROM operations WHERE time < :minTime AND $ID_FILTER")
|
||||
protected abstract suspend fun clearOld(
|
||||
address: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
minTime: Long
|
||||
): Int
|
||||
|
||||
@Query("DELETE FROM operations WHERE $ID_FILTER AND hash in (:hashes)")
|
||||
protected abstract suspend fun clearByHashes(
|
||||
address: String,
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
hashes: Set<String>
|
||||
): Int
|
||||
|
||||
private suspend fun insertOperationType(type: OperationTypeLocal) {
|
||||
when (type) {
|
||||
is ExtrinsicTypeLocal -> insertExtrinsicType(type)
|
||||
is DirectRewardTypeLocal -> insertDirectRewardType(type)
|
||||
is PoolRewardTypeLocal -> insertPoolRewardType(type)
|
||||
is SwapTypeLocal -> insertSwapType(type)
|
||||
is TransferTypeLocal -> insertTransferType(type)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun insertAllInternal(operations: List<OperationLocal>) {
|
||||
insertOperationsBase(operations.map { it.base })
|
||||
insertOperationTypes(operations.map { it.type })
|
||||
}
|
||||
|
||||
private suspend fun insertOperationTypes(types: List<OperationTypeLocal>) {
|
||||
val transfers = types.filterIsInstance<TransferTypeLocal>()
|
||||
val extrinsics = types.filterIsInstance<ExtrinsicTypeLocal>()
|
||||
val directRewards = types.filterIsInstance<DirectRewardTypeLocal>()
|
||||
val poolRewards = types.filterIsInstance<PoolRewardTypeLocal>()
|
||||
val swaps = types.filterIsInstance<SwapTypeLocal>()
|
||||
|
||||
insertTransferTypes(transfers)
|
||||
insertExtrinsicTypes(extrinsics)
|
||||
insertDirectRewardTypes(directRewards)
|
||||
insertPoolRewardTypes(poolRewards)
|
||||
insertSwapTypes(swaps)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.PhishingAddressLocal
|
||||
|
||||
@Dao
|
||||
interface PhishingAddressDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(addresses: List<PhishingAddressLocal>)
|
||||
|
||||
@Query("delete from phishing_addresses")
|
||||
suspend fun clearTable()
|
||||
|
||||
@Query("select publicKey from phishing_addresses")
|
||||
suspend fun getAllAddresses(): List<String>
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.PhishingSiteLocal
|
||||
|
||||
@Dao
|
||||
abstract class PhishingSitesDao {
|
||||
|
||||
@Query("SELECT EXISTS (SELECT * FROM phishing_sites WHERE host in (:hostSuffixes))")
|
||||
abstract suspend fun isPhishing(hostSuffixes: List<String>): Boolean
|
||||
|
||||
@Transaction
|
||||
open suspend fun updatePhishingSites(newSites: List<PhishingSiteLocal>) {
|
||||
clearPhishingSites()
|
||||
|
||||
insertPhishingSites(newSites)
|
||||
}
|
||||
|
||||
@Query("DELETE FROM phishing_sites")
|
||||
protected abstract suspend fun clearPhishingSites()
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insertPhishingSites(sites: List<PhishingSiteLocal>)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.StakingDashboardAccountsView
|
||||
import io.novafoundation.nova.core_db.model.StakingDashboardItemLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface StakingDashboardDao {
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM staking_dashboard_items WHERE
|
||||
metaId = :metaId
|
||||
AND chainId = :chainId
|
||||
AND chainAssetId = :chainAssetId
|
||||
AND stakingType = :stakingType
|
||||
"""
|
||||
)
|
||||
suspend fun getDashboardItem(
|
||||
chainId: String,
|
||||
chainAssetId: Int,
|
||||
stakingType: String,
|
||||
metaId: Long,
|
||||
): StakingDashboardItemLocal?
|
||||
|
||||
@Query("SELECT * FROM staking_dashboard_items WHERE metaId = :metaId")
|
||||
fun dashboardItemsFlow(metaId: Long): Flow<List<StakingDashboardItemLocal>>
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM staking_dashboard_items
|
||||
WHERE metaId = :metaId AND chainId = :chainId AND chainAssetId = :assetId AND stakingType IN (:assetTypes)
|
||||
"""
|
||||
)
|
||||
fun dashboardItemsFlow(metaId: Long, chainId: String, assetId: Int, assetTypes: List<String>): Flow<List<StakingDashboardItemLocal>>
|
||||
|
||||
@Query("SELECT chainId, chainAssetId, stakingType, stakeStatusAccount, rewardsAccount FROM staking_dashboard_items WHERE metaId = :metaId")
|
||||
fun stakingAccountsViewFlow(metaId: Long): Flow<List<StakingDashboardAccountsView>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertItem(dashboardItemLocal: StakingDashboardItemLocal)
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.StakingRewardPeriodLocal
|
||||
import io.novasama.substrate_sdk_android.runtime.AccountId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface StakingRewardPeriodDao {
|
||||
|
||||
@Query("SELECT * FROM staking_reward_period WHERE accountId = :accountId AND chainId = :chainId AND assetId = :assetId AND stakingType = :stakingType")
|
||||
suspend fun getStakingRewardPeriod(accountId: AccountId, chainId: String, assetId: Int, stakingType: String): StakingRewardPeriodLocal?
|
||||
|
||||
@Query("SELECT * FROM staking_reward_period WHERE accountId = :accountId AND chainId = :chainId AND assetId = :assetId AND stakingType = :stakingType")
|
||||
fun observeStakingRewardPeriod(accountId: AccountId, chainId: String, assetId: Int, stakingType: String): Flow<StakingRewardPeriodLocal?>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertStakingRewardPeriod(stakingRewardPeriodLocal: StakingRewardPeriodLocal)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.TotalRewardLocal
|
||||
import io.novasama.substrate_sdk_android.runtime.AccountId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract class StakingTotalRewardDao {
|
||||
|
||||
@Query(
|
||||
"""
|
||||
SELECT * FROM total_reward
|
||||
WHERE accountId = :accountId AND chainId = :chainId AND chainAssetId = :chainAssetId and stakingType = :stakingType
|
||||
"""
|
||||
)
|
||||
abstract fun observeTotalRewards(accountId: AccountId, chainId: String, chainAssetId: Int, stakingType: String): Flow<TotalRewardLocal>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(totalRewardLocal: TotalRewardLocal)
|
||||
|
||||
@Query("DELETE FROM total_reward")
|
||||
abstract suspend fun deleteAll()
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import io.novafoundation.nova.core_db.model.StorageEntryLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
private const val SELECT_FULL_KEY_QUERY = "SELECT * from storage WHERE chainId = :chainId AND storageKey = :fullKey"
|
||||
private const val SELECT_PREFIX_KEY_QUERY = "SELECT * from storage WHERE chainId = :chainId AND storageKey LIKE :keyPrefix || '%'"
|
||||
|
||||
@Dao
|
||||
abstract class StorageDao {
|
||||
|
||||
@Query("SELECT EXISTS($SELECT_PREFIX_KEY_QUERY)")
|
||||
abstract suspend fun isPrefixInCache(chainId: String, keyPrefix: String): Boolean
|
||||
|
||||
@Query("SELECT EXISTS($SELECT_FULL_KEY_QUERY)")
|
||||
abstract suspend fun isFullKeyInCache(chainId: String, fullKey: String): Boolean
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(entry: StorageEntryLocal)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insert(entries: List<StorageEntryLocal>)
|
||||
|
||||
@Query("DELETE FROM storage WHERE chainId = :chainId AND storageKey LIKE :prefix || '%'")
|
||||
abstract suspend fun removeByPrefix(prefix: String, chainId: String)
|
||||
|
||||
@Query(
|
||||
"""
|
||||
DELETE FROM storage WHERE chainId = :chainId
|
||||
AND storageKey LIKE :prefix || '%'
|
||||
AND storageKey NOT IN (:exceptionFullKeys)
|
||||
"""
|
||||
)
|
||||
abstract suspend fun removeByPrefixExcept(prefix: String, exceptionFullKeys: List<String>, chainId: String)
|
||||
|
||||
@Query(SELECT_FULL_KEY_QUERY)
|
||||
abstract fun observeEntry(chainId: String, fullKey: String): Flow<StorageEntryLocal?>
|
||||
|
||||
@Query(SELECT_PREFIX_KEY_QUERY)
|
||||
abstract fun observeEntries(chainId: String, keyPrefix: String): Flow<List<StorageEntryLocal>>
|
||||
|
||||
@Query("SELECT storageKey from storage WHERE chainId = :chainId AND storageKey LIKE :keyPrefix || '%'")
|
||||
abstract suspend fun getKeys(chainId: String, keyPrefix: String): List<String>
|
||||
|
||||
@Query("SELECT * from storage WHERE chainId = :chainId AND storageKey in (:fullKeys)")
|
||||
abstract fun observeEntries(chainId: String, fullKeys: List<String>): Flow<List<StorageEntryLocal>>
|
||||
|
||||
@Query("SELECT storageKey from storage WHERE chainId = :chainId AND storageKey in (:keys)")
|
||||
abstract suspend fun filterKeysInCache(chainId: String, keys: List<String>): List<String>
|
||||
|
||||
@Transaction
|
||||
open suspend fun insertPrefixedEntries(entries: List<StorageEntryLocal>, prefix: String, chainId: String) {
|
||||
removeByPrefix(prefix, chainId)
|
||||
|
||||
insert(entries)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.TinderGovBasketItemLocal
|
||||
import io.novafoundation.nova.core_db.model.TinderGovVotingPowerLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface TinderGovDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun setVotingPower(item: TinderGovVotingPowerLocal)
|
||||
|
||||
@Query("SELECT * FROM tinder_gov_voting_power WHERE metaId = :metaId AND chainId = :chainId")
|
||||
suspend fun getVotingPower(metaId: Long, chainId: String): TinderGovVotingPowerLocal?
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun addToBasket(item: TinderGovBasketItemLocal)
|
||||
|
||||
@Delete
|
||||
suspend fun removeFromBasket(item: TinderGovBasketItemLocal)
|
||||
|
||||
@Delete
|
||||
suspend fun removeFromBasket(items: List<TinderGovBasketItemLocal>)
|
||||
|
||||
@Query("SELECT * FROM tinder_gov_basket WHERE metaId = :metaId AND chainId == :chainId")
|
||||
suspend fun getBasket(metaId: Long, chainId: String): List<TinderGovBasketItemLocal>
|
||||
|
||||
@Query("SELECT * FROM tinder_gov_basket WHERE metaId = :metaId AND chainId == :chainId")
|
||||
fun observeBasket(metaId: Long, chainId: String): Flow<List<TinderGovBasketItemLocal>>
|
||||
|
||||
@Query("SELECT COUNT(*) FROM tinder_gov_basket WHERE metaId = :metaId AND chainId == :chainId")
|
||||
fun basketSize(metaId: Long, chainId: String): Int
|
||||
|
||||
@Query("DELETE FROM tinder_gov_basket WHERE metaId = :metaId AND chainId == :chainId")
|
||||
fun clearBasket(metaId: Long, chainId: String)
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import androidx.room.Update
|
||||
import io.novafoundation.nova.common.utils.CollectionDiffer
|
||||
import io.novafoundation.nova.core_db.model.TokenLocal
|
||||
import io.novafoundation.nova.core_db.model.TokenWithCurrency
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
private const val RETRIEVE_TOKEN_WITH_CURRENCY = """
|
||||
SELECT * FROM currencies AS currency
|
||||
LEFT OUTER JOIN tokens AS token ON token.currencyId = currency.id AND token.tokenSymbol = :symbol
|
||||
WHERE currency.selected = 1
|
||||
"""
|
||||
|
||||
private const val RETRIEVE_TOKENS_WITH_CURRENCY = """
|
||||
SELECT * FROM currencies AS currency
|
||||
LEFT OUTER JOIN tokens AS token ON token.currencyId = currency.id AND token.tokenSymbol in (:symbols)
|
||||
WHERE currency.selected = 1
|
||||
"""
|
||||
|
||||
private const val INSERT_TOKEN_WITH_SELECTED_CURRENCY = """
|
||||
INSERT OR IGNORE INTO tokens (tokenSymbol, rate, currencyId, recentRateChange)
|
||||
VALUES(:symbol, NULL, (SELECT id FROM currencies WHERE selected = 1), NULL)
|
||||
"""
|
||||
|
||||
@Dao
|
||||
abstract class TokenDao {
|
||||
|
||||
@Transaction
|
||||
open suspend fun applyDiff(diff: CollectionDiffer.Diff<TokenLocal>) {
|
||||
deleteTokens(diff.removed)
|
||||
insertTokens(diff.added)
|
||||
updateTokens(diff.updated)
|
||||
}
|
||||
|
||||
@Query(RETRIEVE_TOKEN_WITH_CURRENCY)
|
||||
abstract suspend fun getTokenWithCurrency(symbol: String): TokenWithCurrency?
|
||||
|
||||
@Query(RETRIEVE_TOKENS_WITH_CURRENCY)
|
||||
abstract fun observeTokensWithCurrency(symbols: List<String>): Flow<List<TokenWithCurrency>>
|
||||
|
||||
@Query(RETRIEVE_TOKENS_WITH_CURRENCY)
|
||||
abstract fun getTokensWithCurrency(symbols: List<String>): List<TokenWithCurrency>
|
||||
|
||||
@Query(RETRIEVE_TOKEN_WITH_CURRENCY)
|
||||
abstract fun observeTokenWithCurrency(symbol: String): Flow<TokenWithCurrency>
|
||||
|
||||
@Query("SELECT * FROM tokens")
|
||||
abstract suspend fun getTokens(): List<TokenLocal>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertTokens(tokens: List<TokenLocal>)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
abstract suspend fun insertToken(token: TokenLocal)
|
||||
|
||||
@Query(INSERT_TOKEN_WITH_SELECTED_CURRENCY)
|
||||
abstract suspend fun insertTokenWithSelectedCurrency(symbol: String)
|
||||
|
||||
@Update
|
||||
abstract suspend fun updateTokens(chains: List<TokenLocal>)
|
||||
|
||||
@Delete
|
||||
abstract suspend fun deleteTokens(tokens: List<TokenLocal>)
|
||||
|
||||
@Query("DELETE FROM tokens")
|
||||
abstract suspend fun deleteAll()
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.novafoundation.nova.core_db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import io.novafoundation.nova.core_db.model.WalletConnectPairingLocal
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface WalletConnectSessionsDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insertPairing(pairing: WalletConnectPairingLocal)
|
||||
|
||||
@Query("DELETE FROM wallet_connect_pairings WHERE pairingTopic = :pairingTopic")
|
||||
suspend fun deletePairing(pairingTopic: String)
|
||||
|
||||
@Query("SELECT * FROM wallet_connect_pairings WHERE pairingTopic = :pairingTopic")
|
||||
suspend fun getPairing(pairingTopic: String): WalletConnectPairingLocal?
|
||||
|
||||
@Query("SELECT * FROM wallet_connect_pairings WHERE pairingTopic = :pairingTopic")
|
||||
fun pairingFlow(pairingTopic: String): Flow<WalletConnectPairingLocal?>
|
||||
|
||||
@Query("DELETE FROM wallet_connect_pairings WHERE pairingTopic NOT IN (:pairingTopics)")
|
||||
suspend fun removeAllPairingsOtherThan(pairingTopics: List<String>)
|
||||
|
||||
@Query("SELECT * FROM wallet_connect_pairings")
|
||||
fun allPairingsFlow(): Flow<List<WalletConnectPairingLocal>>
|
||||
|
||||
@Query("SELECT * FROM wallet_connect_pairings WHERE metaId = :metaId")
|
||||
fun pairingsByMetaIdFlow(metaId: Long): Flow<List<WalletConnectPairingLocal>>
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package io.novafoundation.nova.core_db.di
|
||||
|
||||
import io.novafoundation.nova.core_db.AppDatabase
|
||||
import io.novafoundation.nova.core_db.dao.AccountDao
|
||||
import io.novafoundation.nova.core_db.dao.AccountStakingDao
|
||||
import io.novafoundation.nova.core_db.dao.AssetDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserHostSettingsDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserTabsDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainAssetDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainDao
|
||||
import io.novafoundation.nova.core_db.dao.CoinPriceDao
|
||||
import io.novafoundation.nova.core_db.dao.ContributionDao
|
||||
import io.novafoundation.nova.core_db.dao.CurrencyDao
|
||||
import io.novafoundation.nova.core_db.dao.DappAuthorizationDao
|
||||
import io.novafoundation.nova.core_db.dao.ExternalBalanceDao
|
||||
import io.novafoundation.nova.core_db.dao.FavouriteDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.GiftsDao
|
||||
import io.novafoundation.nova.core_db.dao.GovernanceDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.HoldsDao
|
||||
import io.novafoundation.nova.core_db.dao.LockDao
|
||||
import io.novafoundation.nova.core_db.dao.MetaAccountDao
|
||||
import io.novafoundation.nova.core_db.dao.MultisigOperationsDao
|
||||
import io.novafoundation.nova.core_db.dao.NftDao
|
||||
import io.novafoundation.nova.core_db.dao.NodeDao
|
||||
import io.novafoundation.nova.core_db.dao.OperationDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingAddressDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingSitesDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingDashboardDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingRewardPeriodDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingTotalRewardDao
|
||||
import io.novafoundation.nova.core_db.dao.StorageDao
|
||||
import io.novafoundation.nova.core_db.dao.TinderGovDao
|
||||
import io.novafoundation.nova.core_db.dao.TokenDao
|
||||
import io.novafoundation.nova.core_db.dao.WalletConnectSessionsDao
|
||||
|
||||
interface DbApi {
|
||||
|
||||
val phishingSitesDao: PhishingSitesDao
|
||||
|
||||
val favouritesDAppsDao: FavouriteDAppsDao
|
||||
|
||||
val currencyDao: CurrencyDao
|
||||
|
||||
val walletConnectSessionsDao: WalletConnectSessionsDao
|
||||
|
||||
val stakingDashboardDao: StakingDashboardDao
|
||||
|
||||
val externalBalanceDao: ExternalBalanceDao
|
||||
|
||||
val holdsDao: HoldsDao
|
||||
|
||||
fun provideDatabase(): AppDatabase
|
||||
|
||||
fun provideLockDao(): LockDao
|
||||
|
||||
fun provideAccountDao(): AccountDao
|
||||
|
||||
fun contributionDao(): ContributionDao
|
||||
|
||||
fun provideNodeDao(): NodeDao
|
||||
|
||||
fun provideAssetDao(): AssetDao
|
||||
|
||||
fun provideOperationDao(): OperationDao
|
||||
|
||||
fun providePhishingAddressDao(): PhishingAddressDao
|
||||
|
||||
fun storageDao(): StorageDao
|
||||
|
||||
fun tokenDao(): TokenDao
|
||||
|
||||
fun accountStakingDao(): AccountStakingDao
|
||||
|
||||
fun stakingTotalRewardDao(): StakingTotalRewardDao
|
||||
|
||||
fun chainDao(): ChainDao
|
||||
|
||||
fun chainAssetDao(): ChainAssetDao
|
||||
|
||||
fun metaAccountDao(): MetaAccountDao
|
||||
|
||||
fun dappAuthorizationDao(): DappAuthorizationDao
|
||||
|
||||
fun nftDao(): NftDao
|
||||
|
||||
fun governanceDAppsDao(): GovernanceDAppsDao
|
||||
|
||||
fun browserHostSettingsDao(): BrowserHostSettingsDao
|
||||
|
||||
fun coinPriceDao(): CoinPriceDao
|
||||
|
||||
fun stakingRewardPeriodDao(): StakingRewardPeriodDao
|
||||
|
||||
fun tinderGovDao(): TinderGovDao
|
||||
|
||||
fun browserTabsDao(): BrowserTabsDao
|
||||
|
||||
fun multisigOperationsDao(): MultisigOperationsDao
|
||||
|
||||
fun giftsDao(): GiftsDao
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.di
|
||||
|
||||
import dagger.Component
|
||||
import io.novafoundation.nova.common.di.CommonApi
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
|
||||
@Component(
|
||||
modules = [
|
||||
DbModule::class
|
||||
],
|
||||
dependencies = [
|
||||
DbDependencies::class
|
||||
]
|
||||
)
|
||||
@ApplicationScope
|
||||
abstract class DbComponent : DbApi {
|
||||
|
||||
@Component(
|
||||
dependencies = [
|
||||
CommonApi::class
|
||||
]
|
||||
)
|
||||
interface DbDependenciesComponent : DbDependencies
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.novafoundation.nova.core_db.di
|
||||
|
||||
import android.content.Context
|
||||
import com.google.gson.Gson
|
||||
import io.novafoundation.nova.common.data.secrets.v1.SecretStoreV1
|
||||
import io.novafoundation.nova.common.data.secrets.v2.SecretStoreV2
|
||||
import io.novafoundation.nova.common.data.storage.Preferences
|
||||
|
||||
interface DbDependencies {
|
||||
|
||||
fun gson(): Gson
|
||||
|
||||
fun preferences(): Preferences
|
||||
|
||||
fun context(): Context
|
||||
|
||||
fun secretStoreV1(): SecretStoreV1
|
||||
|
||||
fun secretStoreV2(): SecretStoreV2
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.novafoundation.nova.core_db.di
|
||||
|
||||
import io.novafoundation.nova.common.di.FeatureApiHolder
|
||||
import io.novafoundation.nova.common.di.FeatureContainer
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import javax.inject.Inject
|
||||
|
||||
@ApplicationScope
|
||||
class DbHolder @Inject constructor(
|
||||
featureContainer: FeatureContainer
|
||||
) : FeatureApiHolder(featureContainer) {
|
||||
|
||||
override fun initializeDependencies(): Any {
|
||||
val dbDependencies = DaggerDbComponent_DbDependenciesComponent.builder()
|
||||
.commonApi(commonApi())
|
||||
.build()
|
||||
return DaggerDbComponent.builder()
|
||||
.dbDependencies(dbDependencies)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package io.novafoundation.nova.core_db.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.novafoundation.nova.common.di.scope.ApplicationScope
|
||||
import io.novafoundation.nova.core_db.AppDatabase
|
||||
import io.novafoundation.nova.core_db.dao.AccountDao
|
||||
import io.novafoundation.nova.core_db.dao.AccountStakingDao
|
||||
import io.novafoundation.nova.core_db.dao.AssetDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserHostSettingsDao
|
||||
import io.novafoundation.nova.core_db.dao.BrowserTabsDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainAssetDao
|
||||
import io.novafoundation.nova.core_db.dao.ChainDao
|
||||
import io.novafoundation.nova.core_db.dao.CoinPriceDao
|
||||
import io.novafoundation.nova.core_db.dao.ContributionDao
|
||||
import io.novafoundation.nova.core_db.dao.CurrencyDao
|
||||
import io.novafoundation.nova.core_db.dao.DappAuthorizationDao
|
||||
import io.novafoundation.nova.core_db.dao.ExternalBalanceDao
|
||||
import io.novafoundation.nova.core_db.dao.FavouriteDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.GiftsDao
|
||||
import io.novafoundation.nova.core_db.dao.GovernanceDAppsDao
|
||||
import io.novafoundation.nova.core_db.dao.HoldsDao
|
||||
import io.novafoundation.nova.core_db.dao.LockDao
|
||||
import io.novafoundation.nova.core_db.dao.MetaAccountDao
|
||||
import io.novafoundation.nova.core_db.dao.MultisigOperationsDao
|
||||
import io.novafoundation.nova.core_db.dao.NftDao
|
||||
import io.novafoundation.nova.core_db.dao.NodeDao
|
||||
import io.novafoundation.nova.core_db.dao.OperationDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingAddressDao
|
||||
import io.novafoundation.nova.core_db.dao.PhishingSitesDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingDashboardDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingRewardPeriodDao
|
||||
import io.novafoundation.nova.core_db.dao.StakingTotalRewardDao
|
||||
import io.novafoundation.nova.core_db.dao.StorageDao
|
||||
import io.novafoundation.nova.core_db.dao.TinderGovDao
|
||||
import io.novafoundation.nova.core_db.dao.TokenDao
|
||||
import io.novafoundation.nova.core_db.dao.WalletConnectSessionsDao
|
||||
|
||||
@Module
|
||||
class DbModule {
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideAppDatabase(
|
||||
context: Context
|
||||
): AppDatabase {
|
||||
return AppDatabase.get(context)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideUserDao(appDatabase: AppDatabase): AccountDao {
|
||||
return appDatabase.userDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideNodeDao(appDatabase: AppDatabase): NodeDao {
|
||||
return appDatabase.nodeDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideAssetDao(appDatabase: AppDatabase): AssetDao {
|
||||
return appDatabase.assetDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideLockDao(appDatabase: AppDatabase): LockDao {
|
||||
return appDatabase.lockDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideContributionDao(appDatabase: AppDatabase): ContributionDao {
|
||||
return appDatabase.contributionDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideOperationHistoryDao(appDatabase: AppDatabase): OperationDao {
|
||||
return appDatabase.operationDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePhishingAddressDao(appDatabase: AppDatabase): PhishingAddressDao {
|
||||
return appDatabase.phishingAddressesDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStorageDao(appDatabase: AppDatabase): StorageDao {
|
||||
return appDatabase.storageDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideTokenDao(appDatabase: AppDatabase): TokenDao {
|
||||
return appDatabase.tokenDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideAccountStakingDao(appDatabase: AppDatabase): AccountStakingDao {
|
||||
return appDatabase.accountStakingDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStakingTotalRewardDao(appDatabase: AppDatabase): StakingTotalRewardDao {
|
||||
return appDatabase.stakingTotalRewardDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideChainDao(appDatabase: AppDatabase): ChainDao {
|
||||
return appDatabase.chainDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideChainAssetDao(appDatabase: AppDatabase): ChainAssetDao {
|
||||
return appDatabase.chainAssetDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideMetaAccountDao(appDatabase: AppDatabase): MetaAccountDao {
|
||||
return appDatabase.metaAccountDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideDappAuthorizationDao(appDatabase: AppDatabase): DappAuthorizationDao {
|
||||
return appDatabase.dAppAuthorizationDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideNftDao(appDatabase: AppDatabase): NftDao {
|
||||
return appDatabase.nftDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun providePhishingSitesDao(appDatabase: AppDatabase): PhishingSitesDao {
|
||||
return appDatabase.phishingSitesDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideFavouriteDappsDao(appDatabase: AppDatabase): FavouriteDAppsDao {
|
||||
return appDatabase.favouriteDAppsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideCurrencyDao(appDatabase: AppDatabase): CurrencyDao {
|
||||
return appDatabase.currencyDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideGovernanceDAppDao(appDatabase: AppDatabase): GovernanceDAppsDao {
|
||||
return appDatabase.governanceDAppsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideBrowserHostSettingsDao(appDatabase: AppDatabase): BrowserHostSettingsDao {
|
||||
return appDatabase.browserHostSettingsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideWalletConnectSessionsDao(appDatabase: AppDatabase): WalletConnectSessionsDao {
|
||||
return appDatabase.walletConnectSessionsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStakingDashboardDao(appDatabase: AppDatabase): StakingDashboardDao {
|
||||
return appDatabase.stakingDashboardDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideCoinPriceDao(appDatabase: AppDatabase): CoinPriceDao {
|
||||
return appDatabase.coinPriceDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideStakingRewardPeriodDao(appDatabase: AppDatabase): StakingRewardPeriodDao {
|
||||
return appDatabase.stakingRewardPeriodDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideExternalBalanceDao(appDatabase: AppDatabase): ExternalBalanceDao {
|
||||
return appDatabase.externalBalanceDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideHoldsDao(appDatabase: AppDatabase): HoldsDao {
|
||||
return appDatabase.holdsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideTinderGovDao(appDatabase: AppDatabase): TinderGovDao {
|
||||
return appDatabase.tinderGovDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideBrowserTabsDao(appDatabase: AppDatabase): BrowserTabsDao {
|
||||
return appDatabase.browserTabsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideMultisigOperationsDao(appDatabase: AppDatabase): MultisigOperationsDao {
|
||||
return appDatabase.multisigOperationsDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ApplicationScope
|
||||
fun provideGiftsDao(appDatabase: AppDatabase): GiftsDao {
|
||||
return appDatabase.giftsDao()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.novafoundation.nova.core_db.ext
|
||||
|
||||
import io.novafoundation.nova.core_db.dao.FullAssetIdLocal
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
|
||||
fun ChainAssetLocal.fullId(): FullAssetIdLocal {
|
||||
return FullAssetIdLocal(this.chainId, this.id)
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ChangeDAppAuthorization_10_11 = object : Migration(10, 11) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE dapp_authorizations")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `dapp_authorizations` (
|
||||
`baseUrl` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`dAppTitle` TEXT, `authorized` INTEGER,
|
||||
PRIMARY KEY(`baseUrl`, `metaId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val RemoveChainForeignKeyFromChainAccount_11_12 = object : Migration(11, 12) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_chainId`")
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_metaId`")
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_accountId`")
|
||||
database.execSQL("ALTER TABLE chain_accounts RENAME TO chain_accounts_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_accounts` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`publicKey` BLOB NOT NULL,
|
||||
`accountId` BLOB NOT NULL,
|
||||
`cryptoType` TEXT NOT NULL,
|
||||
PRIMARY KEY(`metaId`, `chainId`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_chainId` ON `chain_accounts` (`chainId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_metaId` ON `chain_accounts` (`metaId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_accountId` ON `chain_accounts` (`accountId`)")
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_accounts
|
||||
SELECT *
|
||||
FROM chain_accounts_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE chain_accounts_old")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
// used on master for Astar hotfix
|
||||
val AddAdditionalFieldToChains_12_13 = object : Migration(12, 13) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN additional TEXT DEFAULT null")
|
||||
}
|
||||
}
|
||||
|
||||
// used on develop for parachainStaking rewards
|
||||
val AddChainToTotalRewards_12_13 = object : Migration(12, 13) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE total_reward")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `total_reward` (
|
||||
`accountAddress` TEXT NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`chainAssetId` INTEGER NOT NULL,
|
||||
`totalReward` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`, `chainAssetId`, `accountAddress`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val FixMigrationConflicts_13_14 = object : Migration(13, 14) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
if (isMigratingFromMaster(database)) {
|
||||
// migrating from master -> execute missing develop migration
|
||||
AddChainToTotalRewards_12_13.migrate(database)
|
||||
} else {
|
||||
// migrating from develop -> execute missing master migration
|
||||
AddAdditionalFieldToChains_12_13.migrate(database)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isMigratingFromMaster(database: SupportSQLiteDatabase): Boolean {
|
||||
return runCatching {
|
||||
// check for column added in astar hotfix (master)
|
||||
database.query("SELECT additional FROM chains LIMIT 1")
|
||||
}.fold(
|
||||
onSuccess = { true },
|
||||
onFailure = { false }
|
||||
)
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.converters.MetaAccountTypeConverters
|
||||
import io.novafoundation.nova.core_db.model.chain.account.MetaAccountLocal
|
||||
|
||||
val AddMetaAccountType_14_15 = object : Migration(14, 15) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
val converters = MetaAccountTypeConverters()
|
||||
|
||||
// all accounts that exist till now are added via secrets
|
||||
val defaultType = MetaAccountLocal.Type.SECRETS
|
||||
val typeRepresentationInDb = converters.fromEnum(defaultType)
|
||||
|
||||
database.execSQL("ALTER TABLE meta_accounts ADD COLUMN type TEXT NOT NULL DEFAULT '$typeRepresentationInDb'")
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val NullableSubstratePublicKey_15_16 = object : Migration(15, 16) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("DROP INDEX `index_meta_accounts_substrateAccountId`")
|
||||
database.execSQL("DROP INDEX `index_meta_accounts_ethereumAddress`")
|
||||
database.execSQL("ALTER TABLE meta_accounts RENAME TO meta_accounts_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `meta_accounts` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`substratePublicKey` BLOB,
|
||||
`substrateCryptoType` TEXT,
|
||||
`substrateAccountId` BLOB NOT NULL,
|
||||
`ethereumPublicKey` BLOB,
|
||||
`ethereumAddress` BLOB,
|
||||
`name` TEXT NOT NULL,
|
||||
`isSelected` INTEGER NOT NULL,
|
||||
`position` INTEGER NOT NULL,
|
||||
`type` TEXT NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_meta_accounts_substrateAccountId` ON `meta_accounts` (`substrateAccountId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_meta_accounts_ethereumAddress` ON `meta_accounts` (`ethereumAddress`)")
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO meta_accounts
|
||||
SELECT *
|
||||
FROM meta_accounts_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE meta_accounts_old")
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val WatchOnlyChainAccounts_16_17 = object : Migration(16, 17) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_chainId`")
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_metaId`")
|
||||
database.execSQL("DROP INDEX `index_chain_accounts_accountId`")
|
||||
database.execSQL("ALTER TABLE chain_accounts RENAME TO chain_accounts_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_accounts` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`publicKey` BLOB,
|
||||
`accountId` BLOB NOT NULL,
|
||||
`cryptoType` TEXT,
|
||||
PRIMARY KEY(`metaId`, `chainId`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_chainId` ON `chain_accounts` (`chainId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_metaId` ON `chain_accounts` (`metaId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_accountId` ON `chain_accounts` (`accountId`)")
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_accounts
|
||||
SELECT *
|
||||
FROM chain_accounts_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE chain_accounts_old")
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val RemoveColorFromChains_17_18 = object : Migration(17, 18) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("ALTER TABLE chains RENAME TO chains_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chains` (
|
||||
`id` TEXT NOT NULL,
|
||||
`parentId` TEXT,
|
||||
`name` TEXT NOT NULL,
|
||||
`icon` TEXT NOT NULL,
|
||||
`prefix` INTEGER NOT NULL,
|
||||
`isEthereumBased` INTEGER NOT NULL,
|
||||
`isTestNet` INTEGER NOT NULL,
|
||||
`hasCrowdloans` INTEGER NOT NULL,
|
||||
`additional` TEXT,
|
||||
`url` TEXT,
|
||||
`overridesCommon` INTEGER,
|
||||
`staking_url` TEXT,
|
||||
`staking_type` TEXT,
|
||||
`history_url` TEXT,
|
||||
`history_type` TEXT,
|
||||
`crowdloans_url` TEXT,
|
||||
`crowdloans_type` TEXT,
|
||||
PRIMARY KEY(`id`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
// select all but color
|
||||
"""
|
||||
INSERT INTO chains
|
||||
SELECT id, parentId, name, icon, prefix, isEthereumBased, isTestNet, hasCrowdloans, additional, url, overridesCommon,
|
||||
staking_url, staking_type, history_url, history_type, crowdloans_url, crowdloans_type
|
||||
FROM chains_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE chains_old")
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddCurrencies_18_19 = object : Migration(18, 19) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `currencies` (
|
||||
`code` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`symbol` TEXT,
|
||||
`category` TEXT NOT NULL,
|
||||
`popular` INTEGER NOT NULL,
|
||||
`id` INTEGER NOT NULL,
|
||||
`coingeckoId` TEXT NOT NULL,
|
||||
`selected` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ChangeTokens_19_20 = object : Migration(19, 20) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename table
|
||||
database.execSQL("ALTER TABLE tokens RENAME TO tokens_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `tokens` (
|
||||
`tokenSymbol` TEXT NOT NULL,
|
||||
`rate` TEXT,
|
||||
`recentRateChange` TEXT,
|
||||
`currencyId` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`tokenSymbol`, `currencyId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO tokens (tokenSymbol, rate, recentRateChange, currencyId)
|
||||
SELECT symbol, dollarRate, recentRateChange, 0
|
||||
FROM tokens_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE tokens_old")
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddDAppAuthorizations_1_2 = object : Migration(1, 2) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `dapp_authorizations` (
|
||||
`baseUrl` TEXT NOT NULL,
|
||||
`authorized` INTEGER,
|
||||
PRIMARY KEY(`baseUrl`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ChangeChainNodes_20_21 = object : Migration(20, 21) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chain_nodes ADD `orderId` INTEGER NOT NULL DEFAULT 0")
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val NullableSubstrateAccountId_21_22 = object : Migration(21, 22) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("DROP INDEX `index_meta_accounts_substrateAccountId`")
|
||||
database.execSQL("DROP INDEX `index_meta_accounts_ethereumAddress`")
|
||||
database.execSQL("ALTER TABLE meta_accounts RENAME TO meta_accounts_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `meta_accounts` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
`substratePublicKey` BLOB,
|
||||
`substrateCryptoType` TEXT,
|
||||
`substrateAccountId` BLOB,
|
||||
`ethereumPublicKey` BLOB,
|
||||
`ethereumAddress` BLOB,
|
||||
`name` TEXT NOT NULL,
|
||||
`isSelected` INTEGER NOT NULL,
|
||||
`position` INTEGER NOT NULL,
|
||||
`type` TEXT NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_meta_accounts_substrateAccountId` ON `meta_accounts` (`substrateAccountId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_meta_accounts_ethereumAddress` ON `meta_accounts` (`ethereumAddress`)")
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO meta_accounts
|
||||
SELECT *
|
||||
FROM meta_accounts_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE meta_accounts_old")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddLocks_22_23 = object : Migration(22, 23) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `locks` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`type` TEXT NOT NULL,
|
||||
`amount` TEXT NOT NULL,
|
||||
PRIMARY KEY(`metaId`, `chainId`, `assetId`, `type`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
|
||||
FOREIGN KEY(`assetId`, `chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddContributions_23_24 = object : Migration(23, 24) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `contributions` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`paraId` TEXT NOT NULL,
|
||||
`amountInPlanks` TEXT NOT NULL,
|
||||
`sourceId` TEXT NOT NULL,
|
||||
PRIMARY KEY(`metaId`, `chainId`, `assetId`, `paraId`, `sourceId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddGovernanceFlagToChains_24_25 = object : Migration(24, 25) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN hasGovernance INTEGER NOT NULL DEFAULT 0")
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddGovernanceDapps_25_26 = object : Migration(25, 26) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `governance_dapps` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`referendumUrl` TEXT NOT NULL,
|
||||
`iconUrl` TEXT NOT NULL,
|
||||
`details` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`, `name`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val GovernanceFlagToEnum_26_27 = object : Migration(26, 27) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("ALTER TABLE chains RENAME TO chains_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chains` (
|
||||
`id` TEXT NOT NULL,
|
||||
`parentId` TEXT,
|
||||
`name` TEXT NOT NULL,
|
||||
`icon` TEXT NOT NULL,
|
||||
`prefix` INTEGER NOT NULL,
|
||||
`isEthereumBased` INTEGER NOT NULL,
|
||||
`isTestNet` INTEGER NOT NULL,
|
||||
`hasCrowdloans` INTEGER NOT NULL,
|
||||
`governance` TEXT NOT NULL,
|
||||
`additional` TEXT,
|
||||
`url` TEXT,
|
||||
`overridesCommon` INTEGER,
|
||||
`staking_url` TEXT,
|
||||
`staking_type` TEXT,
|
||||
`history_url` TEXT,
|
||||
`history_type` TEXT,
|
||||
`crowdloans_url` TEXT,
|
||||
`crowdloans_type` TEXT,
|
||||
PRIMARY KEY(`id`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val governanceDefault = "NONE"
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
// select all but color
|
||||
"""
|
||||
INSERT INTO chains
|
||||
SELECT id, parentId, name, icon, prefix, isEthereumBased, isTestNet, hasCrowdloans, "$governanceDefault", additional, url, overridesCommon,
|
||||
staking_url, staking_type, history_url, history_type, crowdloans_url, crowdloans_type
|
||||
FROM chains_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE chains_old")
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddGovernanceExternalApiToChain_27_28 = object : Migration(27, 28) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// new columns
|
||||
database.execSQL("ALTER TABLE `chains` ADD COLUMN `governance_url` TEXT")
|
||||
database.execSQL("ALTER TABLE `chains` ADD COLUMN `governance_type` TEXT")
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
|
||||
val AddSourceToLocalAsset_28_29 = object : Migration(28, 29) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE `chain_assets` ADD COLUMN `source` TEXT NOT NULL DEFAULT '${ChainAssetLocal.SOURCE_DEFAULT}'")
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddTransferApisTable_29_30 = object : Migration(29, 30) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
removeTransferApiFieldsFromChains(database)
|
||||
|
||||
addTransferApiTable(database)
|
||||
|
||||
clearOperationsCache(database)
|
||||
}
|
||||
|
||||
private fun clearOperationsCache(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DELETE FROM operations")
|
||||
}
|
||||
|
||||
private fun addTransferApiTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_transfer_history_apis` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetType` TEXT NOT NULL,
|
||||
`apiType` TEXT NOT NULL,
|
||||
`url` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`, `url`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE INDEX IF NOT EXISTS `index_chain_transfer_history_apis_chainId` ON `chain_transfer_history_apis` (`chainId`)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun removeTransferApiFieldsFromChains(database: SupportSQLiteDatabase) {
|
||||
// rename
|
||||
database.execSQL("ALTER TABLE chains RENAME TO chains_old")
|
||||
|
||||
// new table
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chains` (
|
||||
`id` TEXT NOT NULL,
|
||||
`parentId` TEXT,
|
||||
`name` TEXT NOT NULL,
|
||||
`icon` TEXT NOT NULL,
|
||||
`prefix` INTEGER NOT NULL,
|
||||
`isEthereumBased` INTEGER NOT NULL,
|
||||
`isTestNet` INTEGER NOT NULL,
|
||||
`hasCrowdloans` INTEGER NOT NULL,
|
||||
`governance` TEXT NOT NULL,
|
||||
`additional` TEXT,
|
||||
`url` TEXT,
|
||||
`overridesCommon` INTEGER,
|
||||
`staking_url` TEXT,
|
||||
`staking_type` TEXT,
|
||||
`crowdloans_url` TEXT,
|
||||
`crowdloans_type` TEXT,
|
||||
`governance_url` TEXT,
|
||||
`governance_type` TEXT,
|
||||
PRIMARY KEY(`id`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// insert to new from old
|
||||
database.execSQL(
|
||||
// select all but color
|
||||
"""
|
||||
INSERT INTO chains
|
||||
SELECT id, parentId, name, icon, prefix, isEthereumBased, isTestNet, hasCrowdloans, governance,
|
||||
additional, url, overridesCommon, staking_url, staking_type, crowdloans_url, crowdloans_type, governance_url, governance_type
|
||||
FROM chains_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
// delete old
|
||||
database.execSQL("DROP TABLE chains_old")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AssetTypes_2_3 = object : Migration(2, 3) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chain_assets ADD COLUMN type TEXT DEFAULT NULL")
|
||||
database.execSQL("ALTER TABLE chain_assets ADD COLUMN typeExtras TEXT DEFAULT NULL")
|
||||
database.execSQL("ALTER TABLE chain_assets ADD COLUMN icon TEXT DEFAULT NULL")
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
|
||||
val AddEnabledColumnToChainAssets_30_31 = object : Migration(30, 31) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE `chain_assets` ADD COLUMN `enabled` INTEGER NOT NULL DEFAULT ${ChainAssetLocal.ENABLED_DEFAULT_STR}")
|
||||
}
|
||||
}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainAssetLocal
|
||||
|
||||
/**
|
||||
* Due to previous migration of chain & meta account tables by means of rename-create-insert-delete strategy
|
||||
* foreign keys to these tables got renamed and now points to wrong table which causes crashes for subset of users
|
||||
* This migration recreates all affected tables
|
||||
*/
|
||||
val FixBrokenForeignKeys_31_32 = object : Migration(31, 32) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// foreign key to ChainLocal
|
||||
recreateChainAssets(database)
|
||||
|
||||
// foreign key to ChainAssetLocal which was recreated above
|
||||
recreateAssets(database)
|
||||
|
||||
// foreign key to MetaAccountLocal
|
||||
recreateChainAccount(database)
|
||||
|
||||
// foreign key to ChainLocal
|
||||
recreateChainRuntimeInfo(database)
|
||||
|
||||
// foreign key to ChainLocal
|
||||
recreateChainExplorers(database)
|
||||
|
||||
// foreign key to ChainLocal
|
||||
recreateChainNodes(database)
|
||||
|
||||
// foreign key to ChainLocal, ChainAssetLocal, MetaAccount
|
||||
recreateBalanceLocks(database)
|
||||
}
|
||||
|
||||
private fun recreateChainAssets(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_assets_chainId`")
|
||||
|
||||
database.execSQL("ALTER TABLE chain_assets RENAME TO chain_assets_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_assets` (
|
||||
`id` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`symbol` TEXT NOT NULL,
|
||||
`priceId` TEXT,
|
||||
`staking` TEXT NOT NULL,
|
||||
`precision` INTEGER NOT NULL,
|
||||
`icon` TEXT,
|
||||
`type` TEXT,
|
||||
`source` TEXT NOT NULL DEFAULT '${ChainAssetLocal.SOURCE_DEFAULT}',
|
||||
`buyProviders` TEXT,
|
||||
`typeExtras` TEXT,
|
||||
`enabled` INTEGER NOT NULL DEFAULT ${ChainAssetLocal.ENABLED_DEFAULT_STR},
|
||||
PRIMARY KEY(`chainId`,`id`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_assets
|
||||
SELECT
|
||||
id, chainId, name, symbol, priceId,
|
||||
staking, precision, icon, type, source,
|
||||
buyProviders, typeExtras, enabled
|
||||
FROM chain_assets_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_assets_chainId` ON `chain_assets` (`chainId`)")
|
||||
|
||||
database.execSQL("DROP TABLE chain_assets_old")
|
||||
}
|
||||
|
||||
private fun recreateAssets(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_assets_metaId`")
|
||||
database.execSQL("ALTER TABLE assets RENAME TO assets_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `assets` (
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`freeInPlanks` TEXT NOT NULL,
|
||||
`frozenInPlanks` TEXT NOT NULL,
|
||||
`reservedInPlanks` TEXT NOT NULL,
|
||||
`bondedInPlanks` TEXT NOT NULL,
|
||||
`redeemableInPlanks` TEXT NOT NULL,
|
||||
`unbondingInPlanks` TEXT NOT NULL,
|
||||
PRIMARY KEY(`assetId`,`chainId`,`metaId`),
|
||||
FOREIGN KEY(`assetId`,`chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO assets
|
||||
SELECT
|
||||
assetId, chainId, metaId,
|
||||
freeInPlanks, frozenInPlanks, reservedInPlanks,
|
||||
bondedInPlanks, redeemableInPlanks, unbondingInPlanks
|
||||
FROM assets_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_assets_metaId` ON `assets` (`metaId`)")
|
||||
|
||||
database.execSQL("DROP TABLE assets_old")
|
||||
}
|
||||
|
||||
private fun recreateChainAccount(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_accounts_chainId`")
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_accounts_metaId`")
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_accounts_accountId`")
|
||||
|
||||
database.execSQL("ALTER TABLE chain_accounts RENAME TO chain_accounts_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_accounts` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`publicKey` BLOB,
|
||||
`accountId` BLOB NOT NULL,
|
||||
`cryptoType` TEXT,
|
||||
PRIMARY KEY(`metaId`, `chainId`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_accounts
|
||||
SELECT metaId, chainId, publicKey, accountId, cryptoType
|
||||
FROM chain_accounts_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_chainId` ON `chain_accounts` (`chainId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_metaId` ON `chain_accounts` (`metaId`)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_accounts_accountId` ON `chain_accounts` (`accountId`)")
|
||||
|
||||
database.execSQL("DROP TABLE chain_accounts_old")
|
||||
}
|
||||
|
||||
private fun recreateChainRuntimeInfo(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_runtimes_chainId`")
|
||||
|
||||
database.execSQL("ALTER TABLE chain_runtimes RENAME TO chain_runtimes_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_runtimes` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`syncedVersion` INTEGER NOT NULL,
|
||||
`remoteVersion` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`chainId`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_runtimes
|
||||
SELECT chainId, syncedVersion, remoteVersion FROM chain_runtimes_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_runtimes_chainId` ON `chain_runtimes` (`chainId`)")
|
||||
|
||||
database.execSQL("DROP TABLE chain_runtimes_old")
|
||||
}
|
||||
|
||||
private fun recreateChainExplorers(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_explorers_chainId`")
|
||||
|
||||
database.execSQL("ALTER TABLE chain_explorers RENAME TO chain_explorers_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_explorers` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`extrinsic` TEXT,
|
||||
`account` TEXT,
|
||||
`event` TEXT,
|
||||
PRIMARY KEY(`chainId`, `name`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_explorers
|
||||
SELECT chainId, name, extrinsic, account, event FROM chain_explorers_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_explorers_chainId` ON `chain_explorers` (`chainId`)")
|
||||
|
||||
database.execSQL("DROP TABLE chain_explorers_old")
|
||||
}
|
||||
|
||||
private fun recreateChainNodes(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_chain_nodes_chainId`")
|
||||
|
||||
database.execSQL("ALTER TABLE chain_nodes RENAME TO chain_nodes_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_nodes` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`url` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`orderId` INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(`chainId`, `url`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chain_nodes
|
||||
SELECT chainId, url, name, orderId FROM chain_nodes_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_nodes_chainId` ON `chain_nodes` (`chainId`)")
|
||||
|
||||
database.execSQL("DROP TABLE chain_nodes_old")
|
||||
}
|
||||
|
||||
private fun recreateBalanceLocks(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE locks RENAME TO locks_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `locks` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`type` TEXT NOT NULL,
|
||||
`amount` TEXT NOT NULL,
|
||||
PRIMARY KEY(`metaId`, `chainId`, `assetId`, `type`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
|
||||
FOREIGN KEY(`assetId`, `chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO locks
|
||||
SELECT metaId, chainId, assetId, type, amount FROM locks_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("DROP TABLE locks_old")
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddVersioningToGovernanceDapps_32_33 = object : Migration(32, 33) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE `governance_dapps`")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `governance_dapps` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`name` TEXT NOT NULL,
|
||||
`referendumUrlV1` TEXT,
|
||||
`referendumUrlV2` TEXT,
|
||||
`iconUrl` TEXT NOT NULL,
|
||||
`details` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`, `name`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddGovernanceNetworkToExternalApi_33_34 = object : Migration(33, 34) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN `governance_parameters` TEXT")
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddBrowserHostSettings_34_35 = object : Migration(34, 35) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `browser_host_settings` (
|
||||
`hostUrl` TEXT NOT NULL,
|
||||
`isDesktopModeEnabled` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`hostUrl`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ExtractExternalApiToSeparateTable_35_36 = object : Migration(35, 36) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
removeExternalApisColumnsFromChains(database)
|
||||
|
||||
migrateExternalApisTable(database)
|
||||
|
||||
// recreating chainId causes broken foreign keys to appear on some devices
|
||||
// so we run this migration again to fix it
|
||||
FixBrokenForeignKeys_31_32.migrate(database)
|
||||
}
|
||||
|
||||
private fun migrateExternalApisTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE chain_transfer_history_apis")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chain_external_apis` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`sourceType` TEXT NOT NULL,
|
||||
`apiType` TEXT NOT NULL,
|
||||
`parameters` TEXT,
|
||||
`url` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`, `url`, `apiType`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_chain_external_apis_chainId` ON `chain_external_apis` (`chainId`)")
|
||||
}
|
||||
|
||||
private fun removeExternalApisColumnsFromChains(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains RENAME TO chains_old")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `chains` (
|
||||
`id` TEXT NOT NULL,
|
||||
`parentId` TEXT,
|
||||
`name` TEXT NOT NULL,
|
||||
`icon` TEXT NOT NULL,
|
||||
`prefix` INTEGER NOT NULL,
|
||||
`isEthereumBased` INTEGER NOT NULL,
|
||||
`isTestNet` INTEGER NOT NULL,
|
||||
`hasCrowdloans` INTEGER NOT NULL,
|
||||
`governance` TEXT NOT NULL,
|
||||
`additional` TEXT,
|
||||
`url` TEXT,
|
||||
`overridesCommon` INTEGER,
|
||||
PRIMARY KEY(`id`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
INSERT INTO chains
|
||||
SELECT
|
||||
id, parentId, name, icon, prefix,
|
||||
isEthereumBased, isTestNet, hasCrowdloans, governance, additional,
|
||||
url, overridesCommon
|
||||
FROM chains_old
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("DROP TABLE chains_old")
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
|
||||
val AddRuntimeFlagToChains_36_37 = object : Migration(36, 37) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
val default = ChainLocal.Default.HAS_SUBSTRATE_RUNTIME
|
||||
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN `hasSubstrateRuntime` INTEGER NOT NULL DEFAULT $default")
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddExtrinsicContentField_37_38 = object : Migration(37, 38) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE operations")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `operations` (
|
||||
`id` TEXT NOT NULL,
|
||||
`address` TEXT NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`chainAssetId` INTEGER NOT NULL,
|
||||
`time` INTEGER NOT NULL,
|
||||
`status` INTEGER NOT NULL,
|
||||
`source` INTEGER NOT NULL,
|
||||
`operationType` INTEGER NOT NULL,
|
||||
`amount` TEXT,
|
||||
`sender` TEXT,
|
||||
`receiver` TEXT,
|
||||
`hash` TEXT,
|
||||
`fee` TEXT,
|
||||
`isReward` INTEGER,
|
||||
`era` INTEGER,
|
||||
`validator` TEXT,
|
||||
`extrinsicContent_type` TEXT,
|
||||
`extrinsicContent_module` TEXT,
|
||||
`extrinsicContent_call` TEXT,
|
||||
PRIMARY KEY(`id`, `address`, `chainId`, `chainAssetId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
|
||||
val AddNodeSelectionStrategyField_38_39 = object : Migration(38, 39) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
val default = ChainLocal.Default.NODE_SELECTION_STRATEGY_DEFAULT
|
||||
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN `nodeSelectionStrategy` TEXT NOT NULL DEFAULT '$default'")
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddWalletConnectSessions_39_40 = object : Migration(39, 40) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `wallet_connect_sessions` (
|
||||
`sessionTopic` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`sessionTopic`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_wallet_connect_sessions_metaId` ON `wallet_connect_sessions` (`metaId`)")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ChangeAsset_3_4 = object : Migration(3, 4) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE assets")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `assets` (
|
||||
`tokenSymbol` TEXT NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`freeInPlanks` TEXT NOT NULL,
|
||||
`frozenInPlanks` TEXT NOT NULL,
|
||||
`reservedInPlanks` TEXT NOT NULL,
|
||||
`bondedInPlanks` TEXT NOT NULL,
|
||||
`redeemableInPlanks` TEXT NOT NULL,
|
||||
`unbondingInPlanks` TEXT NOT NULL,
|
||||
PRIMARY KEY(`tokenSymbol`, `chainId`, `metaId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_assets_metaId` ON `assets` (`metaId`)")
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddStakingDashboardItems_41_42 = object : Migration(41, 42) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `staking_dashboard_items` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`chainAssetId` INTEGER NOT NULL,
|
||||
`stakingType` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`hasStake` INTEGER NOT NULL,
|
||||
`stake` TEXT,
|
||||
`status` TEXT,
|
||||
`rewards` TEXT,
|
||||
`estimatedEarnings` REAL,
|
||||
`primaryStakingAccountId` BLOB,
|
||||
PRIMARY KEY(`chainId`, `chainAssetId`, `stakingType`, `metaId`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`chainAssetId`, `chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE ,
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_staking_dashboard_items_metaId` ON `staking_dashboard_items` (`metaId`)")
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val TransferFiatAmount_40_41 = object : Migration(40, 41) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
createCoinPriceTable(database)
|
||||
}
|
||||
|
||||
private fun createCoinPriceTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `coin_prices` (
|
||||
`priceId` TEXT NOT NULL,
|
||||
`currencyId` TEXT NOT NULL,
|
||||
`timestamp` INTEGER NOT NULL,
|
||||
`rate` TEXT NOT NULL,
|
||||
PRIMARY KEY(`priceId`, `currencyId`, `timestamp`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val StakingRewardPeriods_42_43 = object : Migration(42, 43) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
createCoinPriceTable(database)
|
||||
}
|
||||
|
||||
private fun createCoinPriceTable(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `staking_reward_period` (
|
||||
`accountId` BLOB NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`stakingType` TEXT NOT NULL,
|
||||
`periodType` TEXT NOT NULL,
|
||||
`customPeriodStart` INTEGER,
|
||||
`customPeriodEnd` INTEGER,
|
||||
PRIMARY KEY(`accountId`, `chainId`, `assetId`, `stakingType`))
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddRewardAccountToStakingDashboard_43_44 = object : Migration(43, 44) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE `staking_dashboard_items`")
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_staking_dashboard_items_metaId`")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `staking_dashboard_items` (
|
||||
`chainId` TEXT NOT NULL,
|
||||
`chainAssetId` INTEGER NOT NULL,
|
||||
`stakingType` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`hasStake` INTEGER NOT NULL,
|
||||
`stake` TEXT,
|
||||
`status` TEXT,
|
||||
`rewards` TEXT,
|
||||
`estimatedEarnings` REAL,
|
||||
`stakeStatusAccount` BLOB,
|
||||
`rewardsAccount` BLOB,
|
||||
PRIMARY KEY(`chainId`, `chainAssetId`, `stakingType`, `metaId`),
|
||||
FOREIGN KEY(`chainId`) REFERENCES `chains`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`chainAssetId`, `chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_staking_dashboard_items_metaId` ON `staking_dashboard_items` (`metaId`)")
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddStakingTypeToTotalRewards_44_45 = object : Migration(44, 45) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE total_reward")
|
||||
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `total_reward` (
|
||||
`accountId` BLOB NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`chainAssetId` INTEGER NOT NULL,
|
||||
`stakingType` TEXT NOT NULL,
|
||||
`totalReward` TEXT NOT NULL,
|
||||
PRIMARY KEY(`chainId`,`chainAssetId`,`stakingType`, `accountId`)
|
||||
)
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddExternalBalances_45_46 = object : Migration(45, 46) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `externalBalances` (
|
||||
`metaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`assetId` INTEGER NOT NULL,
|
||||
`type` TEXT NOT NULL,
|
||||
`subtype` TEXT NOT NULL,
|
||||
`amount` TEXT NOT NULL,
|
||||
PRIMARY KEY(`metaId`, `chainId`, `assetId`, `type`, `subtype`),
|
||||
FOREIGN KEY(`assetId`, `chainId`) REFERENCES `chain_assets`(`id`, `chainId`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddPoolIdToOperations_46_47 = object : Migration(46, 47) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE operations ADD COLUMN poolId INTEGER")
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddEventIdToOperation_47_48 = object : Migration(47, 48) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE operations ADD COLUMN eventId TEXT")
|
||||
|
||||
database.execSQL("DELETE FROM operations")
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddSwapOption_48_49 = object : Migration(48, 49) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN `swap` TEXT NOT NULL DEFAULT ''")
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
@file:Suppress("ktlint")
|
||||
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val RefactorOperations_49_50 = object : Migration(49, 50) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE operations")
|
||||
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operations` (`id` TEXT NOT NULL, `address` TEXT NOT NULL, `time` INTEGER NOT NULL, `status` INTEGER NOT NULL, `source` INTEGER NOT NULL, `hash` TEXT, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, PRIMARY KEY(`id`, `address`, `chainId`, `assetId`))")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operations_hash` ON `operations` (`hash`)")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operation_transfers` (`amount` TEXT NOT NULL, `sender` TEXT NOT NULL, `receiver` TEXT NOT NULL, `fee` TEXT, `operationId` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, PRIMARY KEY(`operationId`, `address`, `chainId`, `assetId`), FOREIGN KEY(`operationId`, `address`, `chainId`, `assetId`) REFERENCES `operations`(`id`, `address`, `chainId`, `assetId`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operation_transfers_operationId_address_chainId_assetId` ON `operation_transfers` (`operationId`, `address`, `chainId`, `assetId`)")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operation_rewards_direct` (`isReward` INTEGER NOT NULL, `amount` TEXT NOT NULL, `eventId` TEXT NOT NULL, `era` INTEGER, `validator` TEXT, `operationId` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, PRIMARY KEY(`operationId`, `address`, `chainId`, `assetId`), FOREIGN KEY(`operationId`, `address`, `chainId`, `assetId`) REFERENCES `operations`(`id`, `address`, `chainId`, `assetId`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operation_rewards_direct_operationId_address_chainId_assetId` ON `operation_rewards_direct` (`operationId`, `address`, `chainId`, `assetId`)")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operation_rewards_pool` (`isReward` INTEGER NOT NULL, `amount` TEXT NOT NULL, `eventId` TEXT NOT NULL, `poolId` INTEGER NOT NULL, `operationId` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, PRIMARY KEY(`operationId`, `address`, `chainId`, `assetId`), FOREIGN KEY(`operationId`, `address`, `chainId`, `assetId`) REFERENCES `operations`(`id`, `address`, `chainId`, `assetId`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operation_rewards_pool_operationId_address_chainId_assetId` ON `operation_rewards_pool` (`operationId`, `address`, `chainId`, `assetId`)")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operation_extrinsics` (`contentType` TEXT NOT NULL, `module` TEXT NOT NULL, `call` TEXT, `fee` TEXT NOT NULL, `operationId` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, PRIMARY KEY(`operationId`, `address`, `chainId`, `assetId`), FOREIGN KEY(`operationId`, `address`, `chainId`, `assetId`) REFERENCES `operations`(`id`, `address`, `chainId`, `assetId`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operation_extrinsics_operationId_address_chainId_assetId` ON `operation_extrinsics` (`operationId`, `address`, `chainId`, `assetId`)")
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS `operation_swaps` (`operationId` TEXT NOT NULL, `address` TEXT NOT NULL, `chainId` TEXT NOT NULL, `assetId` INTEGER NOT NULL, `fee_amount` TEXT NOT NULL, `fee_chainId` TEXT NOT NULL, `fee_assetId` INTEGER NOT NULL, `assetIn_amount` TEXT NOT NULL, `assetIn_chainId` TEXT NOT NULL, `assetIn_assetId` INTEGER NOT NULL, `assetOut_amount` TEXT NOT NULL, `assetOut_chainId` TEXT NOT NULL, `assetOut_assetId` INTEGER NOT NULL, PRIMARY KEY(`operationId`, `address`, `chainId`, `assetId`), FOREIGN KEY(`operationId`, `address`, `chainId`, `assetId`) REFERENCES `operations`(`id`, `address`, `chainId`, `assetId`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)")
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_operation_swaps_operationId_address_chainId_assetId` ON `operation_swaps` (`operationId`, `address`, `chainId`, `assetId`)")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddChainColor_4_5 = object : Migration(4, 5) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN color TEXT DEFAULT NULL")
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddTransactionVersionToRuntime_50_51 = object : Migration(50, 51) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("ALTER TABLE chain_runtimes ADD COLUMN transactionVersion INTEGER DEFAULT NULL")
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.converters.AssetConverters
|
||||
import io.novafoundation.nova.core_db.model.AssetLocal
|
||||
|
||||
val AddBalanceModesToAssets_51_52 = object : Migration(51, 52) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
val assetsConverters = AssetConverters()
|
||||
val defaultTransferableMode = assetsConverters.fromTransferableMode(AssetLocal.defaultTransferableMode())
|
||||
val defaultEdCountingMode = assetsConverters.fromEdCountingMode(AssetLocal.defaultEdCountingMode())
|
||||
|
||||
database.execSQL("ALTER TABLE assets ADD COLUMN transferableMode INTEGER NOT NULL DEFAULT $defaultTransferableMode")
|
||||
database.execSQL("ALTER TABLE assets ADD COLUMN edCountingMode INTEGER NOT NULL DEFAULT $defaultEdCountingMode")
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val ChangeSessionTopicToParing_52_53 = object : Migration(52, 53) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE wallet_connect_sessions")
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `wallet_connect_pairings` (
|
||||
`pairingTopic` TEXT NOT NULL,
|
||||
`metaId` INTEGER NOT NULL,
|
||||
PRIMARY KEY(`pairingTopic`),
|
||||
FOREIGN KEY(`metaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE
|
||||
)
|
||||
"""
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_wallet_connect_pairings_metaId` ON `wallet_connect_pairings` (`metaId`)")
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import io.novafoundation.nova.core_db.model.chain.ChainLocal
|
||||
|
||||
val AddConnectionStateToChains_53_54 = object : Migration(53, 54) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
val defaultConnectionState = ChainLocal.Default.CONNECTION_STATE_DEFAULT
|
||||
|
||||
database.execSQL("ALTER TABLE chains ADD COLUMN connectionState TEXT NOT NULL DEFAULT '$defaultConnectionState'")
|
||||
|
||||
// Enable full for chains that have some balance synced
|
||||
database.execSQL(
|
||||
"""
|
||||
UPDATE chains SET connectionState = 'FULL_SYNC'
|
||||
WHERE id IN (
|
||||
SELECT DISTINCT chainId
|
||||
FROM assets
|
||||
WHERE freeInPlanks > 0 OR frozenInPlanks > 0 OR reservedInPlanks > 0
|
||||
) OR hasSubstrateRuntime = 0
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddProxyAccount_54_55 = object : Migration(54, 55) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS `proxy_accounts` (
|
||||
`proxiedMetaId` INTEGER NOT NULL,
|
||||
`proxyMetaId` INTEGER NOT NULL,
|
||||
`chainId` TEXT NOT NULL,
|
||||
`proxiedAccountId` BLOB NOT NULL,
|
||||
`proxyType` TEXT NOT NULL,
|
||||
PRIMARY KEY(`proxyMetaId`, `proxiedAccountId`, `chainId`, `proxyType`),
|
||||
FOREIGN KEY(`proxiedMetaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE,
|
||||
FOREIGN KEY(`proxyMetaId`) REFERENCES `meta_accounts`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )
|
||||
""".trimMargin()
|
||||
)
|
||||
|
||||
database.execSQL("ALTER TABLE `meta_accounts` ADD COLUMN `status` TEXT NOT NULL DEFAULT 'ACTIVE'")
|
||||
database.execSQL("ALTER TABLE `meta_accounts` ADD COLUMN `parentMetaId` INTEGER")
|
||||
database.execSQL("ALTER TABLE `chains` ADD COLUMN `supportProxy` INTEGER NOT NULL DEFAULT 0")
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package io.novafoundation.nova.core_db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
val AddFungibleNfts_55_56 = object : Migration(55, 56) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP INDEX IF EXISTS `index_nfts_metaId`")
|
||||
database.execSQL("DROP TABLE nfts")
|
||||
|
||||
/* ktlint-disable max-line-length */
|
||||
database.execSQL(
|
||||
"CREATE TABLE IF NOT EXISTS `nfts` (`identifier` TEXT NOT NULL, `metaId` INTEGER NOT NULL, `chainId` TEXT NOT NULL, `collectionId` TEXT NOT NULL, `instanceId` TEXT, `metadata` BLOB, `type` TEXT NOT NULL, `wholeDetailsLoaded` INTEGER NOT NULL, `name` TEXT, `label` TEXT, `media` TEXT, `issuanceType` TEXT NOT NULL, `issuanceTotal` TEXT, `issuanceMyEdition` TEXT, `issuanceMyAmount` TEXT, `price` TEXT, `pricedUnits` TEXT, PRIMARY KEY(`identifier`))"
|
||||
)
|
||||
database.execSQL("CREATE INDEX IF NOT EXISTS `index_nfts_metaId` ON `nfts` (`metaId`)")
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user