@@ -5,9 +5,53 @@ import com.attafitamim.kabin.specs.dao.DataTypeSpec
5
5
import com.squareup.kotlinpoet.CodeBlock
6
6
import com.squareup.kotlinpoet.FunSpec
7
7
8
+
8
9
const val EXECUTE_FUNCTION = " execute"
9
10
const val EXECUTE_QUERY_FUNCTION = " executeQuery"
10
11
12
+ private val generatedIds = HashMap <String , Int >()
13
+ private val generatedHashCodes = HashMap <Int , String >()
14
+
15
+ private const val MAX_UNIQUE_CYCLES = 100
16
+ private const val CYCLES_START_INDEX = 0
17
+ private const val HASH_CODE_INTERVAL = 31
18
+
19
+ fun SQLQuery.getQueryIdentifier (): Int? = when (this ) {
20
+ is SQLQuery .Columns -> value.getUniqueQueryIdentifier()
21
+ is SQLQuery .Parameters -> value.getUniqueQueryIdentifier()
22
+ is SQLQuery .Raw -> null
23
+ }
24
+
25
+ // TODO: optimize this
26
+ fun String.getUniqueQueryIdentifier (): Int? {
27
+ val generatedId = generatedIds[this ]
28
+ if (generatedId != null ) {
29
+ return generatedId
30
+ }
31
+
32
+ var cycle = CYCLES_START_INDEX
33
+ while (cycle <= MAX_UNIQUE_CYCLES ) {
34
+ val originalHashCode = hashCode()
35
+ val hashCode = if (cycle == CYCLES_START_INDEX ) {
36
+ originalHashCode
37
+ } else {
38
+ originalHashCode * (cycle * HASH_CODE_INTERVAL )
39
+ }
40
+
41
+ val valueLinkedToHashCode = generatedHashCodes[hashCode]
42
+ if (valueLinkedToHashCode == null || valueLinkedToHashCode == this ) {
43
+ generatedIds[this ] = hashCode
44
+ generatedHashCodes[hashCode] = this
45
+ return hashCode
46
+ }
47
+
48
+ cycle++
49
+ }
50
+
51
+ return null
52
+ }
53
+
54
+
11
55
fun FunSpec.Builder.addDriverQueryCode (
12
56
query : SQLQuery ,
13
57
function : String = EXECUTE_QUERY_FUNCTION ,
@@ -56,21 +100,22 @@ fun FunSpec.Builder.addDriverRawQueryCode(
56
100
function : String ,
57
101
binderCode : (CodeBlock .Builder .() -> Unit )? = null
58
102
): FunSpec .Builder = apply {
103
+ val identifier = query.getQueryIdentifier()
59
104
val logic = if (function == EXECUTE_QUERY_FUNCTION ) {
60
105
"""
61
106
|val result = driver.executeQuery(
62
- | null ,
63
- | %L,
64
- | mapper,
65
- | 0
107
+ | identifier = $identifier ,
108
+ | sql = %L,
109
+ | mapper = mapper ,
110
+ | parameters = 0
66
111
|)
67
112
""" .trimMargin()
68
113
} else {
69
114
"""
70
115
|driver.execute(
71
- | null ,
72
- | %L,
73
- | 0
116
+ | identifier = $identifier ,
117
+ | sql = %L,
118
+ | parameters = 0
74
119
|)
75
120
""" .trimMargin()
76
121
}
@@ -142,30 +187,31 @@ fun FunSpec.Builder.addDriverQueryCode(
142
187
143
188
sizeExpression.append(simpleParametersSize)
144
189
val codeBlockBuilder = CodeBlock .builder()
145
- .addStatement(" val kabinQuery = %P" , query.value)
146
- .addStatement(" val kabinParametersCount = $sizeExpression " )
190
+ .addStatement(" val internalQuerySql = %P" , query.value)
191
+ .addStatement(" val internalQueryParametersCount = $sizeExpression " )
147
192
193
+ val originalIdentifier = query.getQueryIdentifier()
148
194
val identifier = if (addedConstants.isEmpty()) {
149
- query.value.hashCode()
195
+ originalIdentifier
150
196
} else {
151
- " kabinQuery.hashCode() "
197
+ null
152
198
}
153
199
154
200
val logic = if (function == " executeQuery" ) {
155
201
"""
156
202
|val result = driver.executeQuery(
157
- | $identifier ,
158
- | kabinQuery ,
159
- | mapper,
160
- | kabinParametersCount
203
+ | identifier = $identifier ,
204
+ | sql = internalQuerySql ,
205
+ | mapper = mapper ,
206
+ | parameters = internalQueryParametersCount
161
207
|)
162
208
""" .trimMargin()
163
209
} else {
164
210
"""
165
211
|driver.execute(
166
- | $identifier ,
167
- | kabinQuery ,
168
- | kabinParametersCount
212
+ | identifier = $identifier ,
213
+ | sql = internalQuerySql ,
214
+ | parameters = internalQueryParametersCount
169
215
|)
170
216
""" .trimMargin()
171
217
}
@@ -177,7 +223,8 @@ fun FunSpec.Builder.addDriverQueryCode(
177
223
}
178
224
179
225
if (query.mutatedKeys.isNotEmpty()) {
180
- codeBlockBuilder.beginControlFlow(" notifyQueries($identifier ) { emit ->" )
226
+ val notifyIdentifier = identifier ? : - 1
227
+ codeBlockBuilder.beginControlFlow(" notifyQueries($notifyIdentifier ) { emit ->" )
181
228
182
229
query.mutatedKeys.forEach { key ->
183
230
codeBlockBuilder.addStatement(" emit(%S)" , key)
@@ -200,22 +247,22 @@ fun FunSpec.Builder.addDriverQueryCode(
200
247
) = apply {
201
248
val codeBlockBuilder = CodeBlock .builder()
202
249
203
- val identifier = query.hashCode ()
250
+ val identifier = query.getQueryIdentifier ()
204
251
val logic = if (function == EXECUTE_QUERY_FUNCTION ) {
205
252
"""
206
253
|val result = driver.executeQuery(
207
- | $identifier ,
208
- | %P,
209
- | mapper,
210
- | ${query.parametersSize}
254
+ | identifier = $identifier ,
255
+ | sql = %P,
256
+ | mapper = mapper ,
257
+ | parameters = ${query.parametersSize}
211
258
|)
212
259
""" .trimMargin()
213
260
} else {
214
261
"""
215
262
|driver.execute(
216
- | $identifier ,
217
- | %P,
218
- | ${query.parametersSize}
263
+ | identifier = $identifier ,
264
+ | sql = %P,
265
+ | parameters = ${query.parametersSize}
219
266
|)
220
267
""" .trimMargin()
221
268
}
0 commit comments