@@ -21,8 +21,6 @@ namespace Blockcore.Features.Wallet.Database
2121{
2222 public class WalletStore : IWalletStore , IDisposable
2323 {
24- private readonly SqliteConnection sqliteConnection ;
25-
2624 private const int WalletVersion = 1 ;
2725
2826 /// <summary>
@@ -34,6 +32,9 @@ public class WalletStore : IWalletStore, IDisposable
3432
3533 private readonly Network network ;
3634
35+ private readonly string dbPath ;
36+ private readonly string dbConnection ;
37+
3738 public WalletData WalletData { get ; private set ; }
3839
3940 /// <summary>
@@ -42,10 +43,10 @@ public class WalletStore : IWalletStore, IDisposable
4243 public WalletStore ( Network network , Types . Wallet wallet )
4344 {
4445 var tmpconn = Guid . NewGuid ( ) . ToString ( ) ;
45- this . inmemorySqliteConnection = new SqliteConnection ( $ "Data Source={ tmpconn } ;Mode=Memory;Cache=Shared") ;
46- this . inmemorySqliteConnection . Open ( ) ;
4746
48- this . sqliteConnection = new SqliteConnection ( $ "Data Source={ tmpconn } ;Mode=Memory;Cache=Shared") ;
47+ this . dbConnection = $ "Data Source={ tmpconn } ;Mode=Memory;Cache=Shared";
48+ this . inmemorySqliteConnection = new SqliteConnection ( this . dbConnection ) ;
49+ this . inmemorySqliteConnection . Open ( ) ;
4950
5051 this . CreateDatabase ( ) ;
5152
@@ -55,16 +56,15 @@ public WalletStore(Network network, Types.Wallet wallet)
5556
5657 public WalletStore ( Network network , DataFolder dataFolder , Types . Wallet wallet )
5758 {
58- var dbPath = Path . Combine ( dataFolder . WalletFolderPath , $ "{ wallet . Name } .db") ;
59+ this . dbPath = Path . Combine ( dataFolder . WalletFolderPath , $ "{ wallet . Name } .db") ;
60+ this . dbConnection = "Data Source=" + this . dbPath ;
5961
6062 if ( ! Directory . Exists ( dataFolder . WalletFolderPath ) )
6163 {
6264 Directory . CreateDirectory ( dataFolder . WalletFolderPath ) ;
6365 }
6466
65- this . sqliteConnection = new SqliteConnection ( "Data Source=" + dbPath ) ;
66-
67- if ( ! File . Exists ( dbPath ) )
67+ if ( ! File . Exists ( this . dbPath ) )
6868 {
6969 this . CreateDatabase ( ) ;
7070 }
@@ -73,7 +73,12 @@ public WalletStore(Network network, DataFolder dataFolder, Types.Wallet wallet)
7373 // Attempt to access the user version, this will crash if the loaded database is V5 and we use V4 packages.
7474 try
7575 {
76- var walletVersion = this . sqliteConnection . QueryFirst < int > ( "SELECT WalletVersion FROM WalletData" ) ;
76+ var walletVersion = - 1 ;
77+
78+ using ( var conn = this . GetDbConnection ( ) )
79+ {
80+ walletVersion = conn . QueryFirst < int > ( "SELECT WalletVersion FROM WalletData" ) ;
81+ }
7782
7883 if ( walletVersion != WalletVersion )
7984 {
@@ -92,7 +97,7 @@ public WalletStore(Network network, DataFolder dataFolder, Types.Wallet wallet)
9297 var dbBackupPath = Path . Combine ( dataFolder . WalletFolderPath , $ "{ wallet . Name } .error.db") ;
9398
9499 // Move the problematic database file, which might be a V5 database.
95- File . Move ( dbPath , dbBackupPath ) ;
100+ File . Move ( this . dbPath , dbBackupPath ) ;
96101
97102 this . CreateDatabase ( ) ;
98103 }
@@ -103,6 +108,11 @@ public WalletStore(Network network, DataFolder dataFolder, Types.Wallet wallet)
103108 this . Init ( wallet ) ;
104109 }
105110
111+ protected SqliteConnection GetDbConnection ( )
112+ {
113+ return new SqliteConnection ( this . dbConnection ) ;
114+ }
115+
106116 private void Init ( Types . Wallet wallet )
107117 {
108118 SqlMapper . AddTypeHandler ( new DateTimeOffsetHandler ( ) ) ;
@@ -141,7 +151,8 @@ public WalletData GetData()
141151 {
142152 if ( this . WalletData == null )
143153 {
144- this . WalletData = this . sqliteConnection . QueryFirstOrDefault < WalletData > ( "SELECT *, Id AS Key FROM WalletData WHERE Id = 'Key'" ) ;
154+ using var conn = this . GetDbConnection ( ) ;
155+ this . WalletData = conn . QueryFirstOrDefault < WalletData > ( "SELECT *, Id AS Key FROM WalletData WHERE Id = 'Key'" ) ;
145156 }
146157
147158 return this . WalletData ;
@@ -155,7 +166,8 @@ public void SetData(WalletData data)
155166 ON CONFLICT(Id) DO UPDATE SET
156167 EncryptedSeed = @EncryptedSeed, WalletTip = @WalletTip, BlockLocator = @BlockLocator;" ;
157168
158- this . sqliteConnection . Execute ( sql , data ) ;
169+ using var conn = this . GetDbConnection ( ) ;
170+ conn . Execute ( sql , data ) ;
159171
160172 this . WalletData = data ;
161173 }
@@ -170,12 +182,14 @@ public void InsertOrUpdate(TransactionOutputData item)
170182 ON CONFLICT(OutPoint) DO UPDATE SET
171183 IndexInTransaction = @IndexInTransaction, BlockHeight = @BlockHeight, BlockHash = @BlockHash, BlockIndex = @BlockIndex, CreationTime = @CreationTime, IsPropagated = @IsPropagated, IsColdCoinStake = @IsColdCoinStake, AccountIndex = @AccountIndex, MerkleProof = @MerkleProof, Hex = @Hex, SpendingDetailsTransactionId = @SpendingDetailsTransactionId, SpendingDetailsBlockHeight = @SpendingDetailsBlockHeight, SpendingDetailsBlockIndex = @SpendingDetailsBlockIndex, SpendingDetailsIsCoinStake = @SpendingDetailsIsCoinStake, SpendingDetailsCreationTime = @SpendingDetailsCreationTime, SpendingDetailsPayments = @SpendingDetailsPayments, SpendingDetailsHex = @SpendingDetailsHex;" ;
172184
173- this . sqliteConnection . Execute ( sql , insert ) ;
185+ using var conn = this . GetDbConnection ( ) ;
186+ conn . Execute ( sql , insert ) ;
174187 }
175188
176189 public int CountForAddress ( string address )
177190 {
178- var count = this . sqliteConnection . ExecuteScalar < int > ( "SELECT COUNT(*) FROM TransactionData WHERE Address = @address" , new { address } ) ;
191+ using var conn = this . GetDbConnection ( ) ;
192+ var count = conn . ExecuteScalar < int > ( "SELECT COUNT(*) FROM TransactionData WHERE Address = @address" , new { address } ) ;
179193
180194 return count ;
181195 }
@@ -185,6 +199,8 @@ public IEnumerable<WalletHistoryData> GetAccountHistory(int accountIndex, bool e
185199 // The result of this method is not guaranteed to be the length
186200 // of the 'take' param. In case some of the inputs we have are
187201 // in the same trx they will be grouped in to a single entry.
202+ using var conn = this . GetDbConnection ( ) ;
203+ conn . Open ( ) ;
188204
189205 var sql = @$ "SELECT * FROM TransactionData
190206 WHERE AccountIndex == @accountIndex
@@ -193,7 +209,7 @@ AND SpendingDetailsTransactionId IS NOT NULL
193209 ORDER BY SpendingDetailsCreationTime DESC
194210 LIMIT @take OFFSET @skip " ;
195211
196- var historySpentResult = this . sqliteConnection . Query < TransactionData > ( sql , new { accountIndex , skip , take } ) . ToList ( ) ;
212+ var historySpentResult = conn . Query < TransactionData > ( sql , new { accountIndex , skip , take } ) . ToList ( ) ;
197213 var historySpent = historySpentResult . Select ( this . Convert ) ;
198214
199215 sql = @$ "SELECT * FROM TransactionData
@@ -202,7 +218,10 @@ ORDER BY SpendingDetailsCreationTime DESC
202218 ORDER BY CreationTime DESC
203219 LIMIT @take OFFSET @skip" ;
204220
205- var historyUnspentResult = this . sqliteConnection . Query < TransactionData > ( sql , new { accountIndex , skip , take } ) . ToList ( ) ;
221+ var historyUnspentResult = conn . Query < TransactionData > ( sql , new { accountIndex , skip , take } ) . ToList ( ) ;
222+
223+ conn . Close ( ) ;
224+
206225 var historyUnspent = historyUnspentResult . Select ( this . Convert ) ;
207226
208227 var items = new List < WalletHistoryData > ( ) ;
@@ -282,7 +301,8 @@ ORDER BY CreationTime DESC
282301
283302 public IEnumerable < TransactionOutputData > GetForAddress ( string address )
284303 {
285- var trxs = this . sqliteConnection . Query < TransactionData > (
304+ using var conn = this . GetDbConnection ( ) ;
305+ var trxs = conn . Query < TransactionData > (
286306 "SELECT * FROM TransactionData " +
287307 "WHERE Address = @address" ,
288308 new { address } ) ;
@@ -292,7 +312,8 @@ public IEnumerable<TransactionOutputData> GetForAddress(string address)
292312
293313 public IEnumerable < TransactionOutputData > GetUnspentForAddress ( string address )
294314 {
295- var trxs = this . sqliteConnection . Query < TransactionData > (
315+ using var conn = this . GetDbConnection ( ) ;
316+ var trxs = conn . Query < TransactionData > (
296317 "SELECT * FROM 'TransactionData' " +
297318 "WHERE Address = @address " +
298319 "AND SpendingDetailsTransactionId IS NULL" ,
@@ -313,7 +334,8 @@ FROM TransactionData
313334 { excludeColdStakeSql }
314335 GROUP BY BlockHeight IS NOT NULL" ;
315336
316- var result = this . sqliteConnection . Query ( sql , new { address } ) ;
337+ using var conn = this . GetDbConnection ( ) ;
338+ var result = conn . Query ( sql , new { address } ) ;
317339
318340 var walletBalanceResult = new WalletBalanceResult ( ) ;
319341
@@ -338,7 +360,8 @@ FROM TransactionData
338360 { excludeColdStakeSql }
339361 GROUP BY BlockHeight IS NOT NULL" ;
340362
341- var result = this . sqliteConnection . Query ( sql , new { accountIndex } ) ;
363+ using var conn = this . GetDbConnection ( ) ;
364+ var result = conn . Query ( sql , new { accountIndex } ) ;
342365
343366 var walletBalanceResult = new WalletBalanceResult ( ) ;
344367
@@ -353,8 +376,10 @@ FROM TransactionData
353376
354377 public TransactionOutputData GetForOutput ( OutPoint outPoint )
355378 {
356- var trx = this . sqliteConnection . QueryFirstOrDefault < TransactionData > (
357- "SELECT * FROM TransactionData WHERE OutPoint = @outPoint" , new { outPoint } ) ;
379+ TransactionData trx = null ;
380+
381+ using var conn = this . GetDbConnection ( ) ;
382+ trx = conn . QueryFirstOrDefault < TransactionData > ( "SELECT * FROM TransactionData WHERE OutPoint = @outPoint" , new { outPoint } ) ;
358383
359384 if ( trx == null )
360385 {
@@ -368,8 +393,8 @@ public TransactionOutputData GetForOutput(OutPoint outPoint)
368393
369394 public bool Remove ( OutPoint outPoint )
370395 {
371- var ret = this . sqliteConnection . ExecuteScalar < int > ( "DELETE FROM TransactionData WHERE OutPoint = @outPoint" , new { outPoint } ) ;
372-
396+ using var conn = this . GetDbConnection ( ) ;
397+ var ret = conn . ExecuteScalar < int > ( "DELETE FROM TransactionData WHERE OutPoint = @outPoint" , new { outPoint } ) ;
373398 return ret > 0 ;
374399 }
375400
@@ -380,17 +405,21 @@ private void UpgradeDatabase(int oldVersion)
380405
381406 private void CreateDatabase ( )
382407 {
383- this . sqliteConnection . Execute (
384- @$ "CREATE TABLE WalletData(
408+ using ( var conn = GetDbConnection ( ) )
409+ {
410+ conn . Open ( ) ;
411+
412+ conn . Execute (
413+ @$ "CREATE TABLE WalletData(
385414 Id VARCHAR(3) NOT NULL PRIMARY KEY,
386415 EncryptedSeed VARCHAR(500) NULL,
387416 WalletName VARCHAR(100) NOT NULL,
388417 WalletTip VARCHAR(75) NOT NULL,
389418 WalletVersion INTEGER NOT NULL,
390419 BlockLocator TEXT NULL)" ) ;
391420
392- this . sqliteConnection . Execute (
393- @$ "CREATE TABLE TransactionData(
421+ conn . Execute (
422+ @$ "CREATE TABLE TransactionData(
394423 OutPoint VARCHAR(66) NOT NULL PRIMARY KEY,
395424 Address VARCHAR(34) NOT NULL,
396425 Id VARCHAR(64) NOT NULL,
@@ -416,15 +445,17 @@ SpendingDetailsTransactionId VARCHAR(64) NULL,
416445 SpendingDetailsPayments TEXT NULL,
417446 SpendingDetailsHex TEXT NULL)" ) ;
418447
419- this . sqliteConnection . Execute ( "CREATE INDEX 'address_index' ON 'TransactionData' ('Address')" ) ;
420- this . sqliteConnection . Execute ( "CREATE INDEX 'blockheight_index' ON 'TransactionData' ('BlockHeight')" ) ;
421- this . sqliteConnection . Execute ( "CREATE UNIQUE INDEX 'outpoint_index' ON 'TransactionData' ('OutPoint')" ) ;
422- this . sqliteConnection . Execute ( "CREATE UNIQUE INDEX 'key_index' ON 'WalletData' ('Id')" ) ;
448+ conn . Execute ( "CREATE INDEX 'address_index' ON 'TransactionData' ('Address')" ) ;
449+ conn . Execute ( "CREATE INDEX 'blockheight_index' ON 'TransactionData' ('BlockHeight')" ) ;
450+ conn . Execute ( "CREATE UNIQUE INDEX 'outpoint_index' ON 'TransactionData' ('OutPoint')" ) ;
451+ conn . Execute ( "CREATE UNIQUE INDEX 'key_index' ON 'WalletData' ('Id')" ) ;
452+
453+ conn . Close ( ) ;
454+ }
423455 }
424456
425457 public void Dispose ( )
426458 {
427- this . sqliteConnection ? . Dispose ( ) ;
428459 this . inmemorySqliteConnection ? . Dispose ( ) ;
429460 }
430461
0 commit comments