@@ -25,12 +25,13 @@ class CoinStorage(val marketDatabase: MarketDatabase) {
2525 fun fullCoins (filter : String , limit : Int ): List <FullCoin > {
2626 val sql = """
2727 SELECT * FROM Coin
28- WHERE ${filterWhereStatement(filter )}
29- ORDER BY ${filterOrderByStatement(filter )}
30- LIMIT $limit
28+ WHERE ${filterWhereStatement()}
29+ ORDER BY ${filterOrderByStatement()}
30+ LIMIT ?
3131 """ .trimIndent()
3232
33- return coinDao.getFullCoins(SimpleSQLiteQuery (sql)).map { it.fullCoin }
33+ val args = filterArgs(filter) + limit.toString()
34+ return coinDao.getFullCoins(SimpleSQLiteQuery (sql, args)).map { it.fullCoin }
3435 }
3536
3637 fun fullCoin (uid : String ): FullCoin ? =
@@ -40,39 +41,48 @@ class CoinStorage(val marketDatabase: MarketDatabase) {
4041 coinDao.getFullCoins(uids).map { it.fullCoin }
4142
4243 fun getToken (query : TokenQuery ): Token ? {
43- val sql = " SELECT * FROM TokenEntity WHERE ${filterByTokenQuery(query)} LIMIT 1"
44-
45- return coinDao.getToken(SimpleSQLiteQuery (sql))?.token
44+ val (sql, args) = buildTokenQuerySql(query, limit = 1 )
45+ return coinDao.getToken(SimpleSQLiteQuery (sql, args))?.token
4646 }
4747
4848 fun getTokens (queries : List <TokenQuery >): List <Token > {
4949 if (queries.isEmpty()) return listOf ()
5050
51- val queriesStr = queries.toSet().toList().map { filterByTokenQuery(it) }.joinToString(" OR " )
52- val sql = " SELECT * FROM TokenEntity WHERE $queriesStr "
51+ val uniqueQueries = queries.toSet().toList()
52+ val whereClauses = mutableListOf<String >()
53+ val args = mutableListOf<Any >()
54+
55+ uniqueQueries.forEach { query ->
56+ val (clause, queryArgs) = buildTokenQueryClause(query)
57+ whereClauses.add(clause)
58+ args.addAll(queryArgs)
59+ }
60+
61+ val sql = " SELECT * FROM TokenEntity WHERE ${whereClauses.joinToString(" OR " )} "
5362
54- return coinDao.getTokens(SimpleSQLiteQuery (sql)).map { it.token }
63+ return coinDao.getTokens(SimpleSQLiteQuery (sql, args.toTypedArray() )).map { it.token }
5564 }
5665
5766 fun getTokens (reference : String ): List <Token > {
58- val queriesStr = " `TokenEntity`.`reference` LIKE '% $reference ' "
59- val sql = " SELECT * FROM TokenEntity WHERE $queriesStr "
67+ val sql = " SELECT * FROM TokenEntity WHERE `TokenEntity`.`reference` LIKE ? "
68+ val args = arrayOf( " % $reference " )
6069
61- return coinDao.getTokens(SimpleSQLiteQuery (sql)).map { it.token }
70+ return coinDao.getTokens(SimpleSQLiteQuery (sql, args )).map { it.token }
6271 }
6372
6473 fun getTokens (blockchainType : BlockchainType , filter : String , limit : Int ): List <Token > {
6574 val sql = """
6675 SELECT * FROM TokenEntity
6776 JOIN Coin ON `Coin`.`uid` = `TokenEntity`.`coinUid`
6877 WHERE
69- `TokenEntity`.`blockchainUid` = ' ${blockchainType.uid} '
70- AND (${filterWhereStatement(filter )} )
71- ORDER BY ${filterOrderByStatement(filter )}
72- LIMIT $limit
78+ `TokenEntity`.`blockchainUid` = ?
79+ AND (${filterWhereStatement()} )
80+ ORDER BY ${filterOrderByStatement()}
81+ LIMIT ?
7382 """ .trimIndent()
7483
75- return coinDao.getTokens(SimpleSQLiteQuery (sql)).map { it.token }
84+ val args = arrayOf(blockchainType.uid) + filterArgs(filter) + limit.toString()
85+ return coinDao.getTokens(SimpleSQLiteQuery (sql, args)).map { it.token }
7686 }
7787
7888 fun getBlockchain (uid : String ): Blockchain ? =
@@ -84,30 +94,43 @@ class CoinStorage(val marketDatabase: MarketDatabase) {
8494 fun getAllBlockchains (): List <Blockchain > =
8595 coinDao.getAllBlockchains().map { it.blockchain }
8696
87- private fun filterByTokenQuery (query : TokenQuery ): String {
97+ private fun buildTokenQuerySql (query : TokenQuery , limit : Int? = null): Pair <String , Array <Any >> {
98+ val (clause, args) = buildTokenQueryClause(query)
99+ val sql = " SELECT * FROM TokenEntity WHERE $clause " +
100+ (if (limit != null ) " LIMIT $limit " else " " )
101+ return Pair (sql, args.toTypedArray())
102+ }
103+
104+ private fun buildTokenQueryClause (query : TokenQuery ): Pair <String , List <Any >> {
88105 val (type, reference) = query.tokenType.values
89106
90- val conditions = mutableListOf (
91- " `TokenEntity`.`blockchainUid` = '${query.blockchainType.uid} '" ,
92- " `TokenEntity`.`type` = '$type '"
93- )
107+ val conditions = mutableListOf<String >()
108+ val args = mutableListOf<Any >()
109+
110+ conditions.add(" `TokenEntity`.`blockchainUid` = ?" )
111+ args.add(query.blockchainType.uid)
112+
113+ conditions.add(" `TokenEntity`.`type` = ?" )
114+ args.add(type)
94115
95116 if (reference.isNotBlank()) {
96- conditions.add(" `TokenEntity`.`reference` LIKE '%$reference '" )
117+ conditions.add(" `TokenEntity`.`reference` LIKE ?" )
118+ args.add(" %$reference " )
97119 }
98120
99- return conditions.joinToString(" AND " , " (" , " )" )
121+ val clause = conditions.joinToString(" AND " , " (" , " )" )
122+ return Pair (clause, args)
100123 }
101124
102- private fun filterWhereStatement (filter : String ) =
103- " `Coin`.`name` LIKE '% $filter %' OR `Coin`.`code` LIKE '% $filter %' "
125+ private fun filterWhereStatement () =
126+ " `Coin`.`name` LIKE ? OR `Coin`.`code` LIKE ? "
104127
105- private fun filterOrderByStatement (filter : String ) = """
128+ private fun filterOrderByStatement () = """
106129 priority ASC,
107130 CASE
108- WHEN `Coin`.`code` LIKE ' $filter ' THEN 1
109- WHEN `Coin`.`code` LIKE ' $filter %' THEN 2
110- WHEN `Coin`.`name` LIKE ' $filter %' THEN 3
131+ WHEN `Coin`.`code` LIKE ? THEN 1
132+ WHEN `Coin`.`code` LIKE ? THEN 2
133+ WHEN `Coin`.`name` LIKE ? THEN 3
111134 ELSE 4
112135 END,
113136 CASE
@@ -118,6 +141,17 @@ class CoinStorage(val marketDatabase: MarketDatabase) {
118141 `Coin`.`name` ASC
119142 """
120143
144+ private fun filterArgs (filter : String ): Array <String > {
145+ val filterParam = " %$filter %"
146+ val filterStartParam = " $filter %"
147+ return arrayOf(
148+ // For WHERE conditions
149+ filterParam, filterParam,
150+ // For ORDER BY conditions
151+ filter, filterStartParam, filterStartParam
152+ )
153+ }
154+
121155 fun update (coins : List <Coin >, blockchainEntities : List <BlockchainEntity >, tokenEntities : List <TokenEntity >) {
122156 marketDatabase.runInTransaction {
123157 // TODO It's not good solution for update information
@@ -129,5 +163,4 @@ class CoinStorage(val marketDatabase: MarketDatabase) {
129163 tokenEntities.forEach { coinDao.insert(it) }
130164 }
131165 }
132-
133- }
166+ }
0 commit comments