@@ -9,10 +9,6 @@ import io.provenance.explorer.config.ExplorerProperties
9
9
import io.provenance.explorer.domain.core.logger
10
10
import io.provenance.explorer.domain.core.sql.jsonb
11
11
import io.provenance.explorer.domain.core.sql.toProcedureObject
12
- import io.provenance.explorer.domain.entities.FeeType.BASE_FEE_OVERAGE
13
- import io.provenance.explorer.domain.entities.FeeType.BASE_FEE_USED
14
- import io.provenance.explorer.domain.entities.FeeType.CUSTOM_FEE
15
- import io.provenance.explorer.domain.entities.FeeType.MSG_BASED_FEE
16
12
import io.provenance.explorer.domain.extensions.CUSTOM_FEE_MSG_TYPE
17
13
import io.provenance.explorer.domain.extensions.exec
18
14
import io.provenance.explorer.domain.extensions.execAndMap
@@ -43,6 +39,7 @@ import io.provenance.explorer.model.TxAssociatedValues
43
39
import io.provenance.explorer.model.TxFeepayer
44
40
import io.provenance.explorer.model.TxGasVolume
45
41
import io.provenance.explorer.model.TxStatus
42
+ import io.provenance.explorer.model.base.PagedResults
46
43
import io.provenance.explorer.model.base.stringfy
47
44
import io.provenance.explorer.service.AssetService
48
45
import org.jetbrains.exposed.dao.IntEntity
@@ -69,6 +66,7 @@ import org.jetbrains.exposed.sql.selectAll
69
66
import org.jetbrains.exposed.sql.transactions.TransactionManager
70
67
import org.jetbrains.exposed.sql.transactions.transaction
71
68
import java.math.BigDecimal
69
+ import java.time.LocalDate
72
70
import java.time.LocalDateTime
73
71
import java.time.format.DateTimeFormatter
74
72
@@ -151,19 +149,19 @@ class TxCacheRecord(id: EntityID<Int>) : IntEntity(id) {
151
149
var join: ColumnSet = TxCacheTable
152
150
153
151
if (tqp.msgTypes.isNotEmpty()) {
154
- join = join.innerJoin(TxMsgTypeQueryTable , { TxCacheTable .id }, { TxMsgTypeQueryTable . txHashId })
152
+ join = join.innerJoin(TxMsgTypeQueryTable , { TxCacheTable .id }, { txHashId })
155
153
}
156
154
if ((tqp.addressId != null && tqp.addressType != null ) || tqp.address != null ) {
157
- join = join.innerJoin(TxAddressJoinTable , { TxCacheTable .id }, { TxAddressJoinTable . txHashId })
155
+ join = join.innerJoin(TxAddressJoinTable , { TxCacheTable .id }, { txHashId })
158
156
}
159
157
if (tqp.markerId != null || tqp.denom != null ) {
160
- join = join.innerJoin(TxMarkerJoinTable , { TxCacheTable .id }, { TxMarkerJoinTable . txHashId })
158
+ join = join.innerJoin(TxMarkerJoinTable , { TxCacheTable .id }, { txHashId })
161
159
}
162
160
if (tqp.nftId != null ) {
163
- join = join.innerJoin(TxNftJoinTable , { TxCacheTable .id }, { TxNftJoinTable . txHashId })
161
+ join = join.innerJoin(TxNftJoinTable , { TxCacheTable .id }, { txHashId })
164
162
}
165
163
if (tqp.ibcChannelIds.isNotEmpty()) {
166
- join = join.innerJoin(TxIbcTable , { TxCacheTable .id }, { TxIbcTable . txHashId })
164
+ join = join.innerJoin(TxIbcTable , { TxCacheTable .id }, { txHashId })
167
165
}
168
166
169
167
val query = if (distinctQuery != null ) join.slice(distinctQuery).selectAll() else join.selectAll()
@@ -206,7 +204,79 @@ class TxCacheRecord(id: EntityID<Int>) : IntEntity(id) {
206
204
207
205
query
208
206
}
209
- }
207
+
208
+ fun countForDates (daysPrior : Int ): List <Pair <LocalDate , Long >> = transaction {
209
+ val query = """
210
+ select sum(daily_tx_cnt.cnt) as count, ds
211
+ from (select count(*) cnt, tx_timestamp ts, date_trunc('day', tx_timestamp) ds
212
+ from tx_cache
213
+ where tx_timestamp > current_timestamp - interval '$daysPrior days'
214
+ group by ts, ds) as daily_tx_cnt
215
+ group by ds
216
+ order by ds;
217
+ """ .trimIndent()
218
+ query.execAndMap {
219
+ Pair (
220
+ it.getTimestamp(" ds" ).toLocalDateTime().toLocalDate(),
221
+ it.getLong(" count" )
222
+ )
223
+ }
224
+ }
225
+
226
+ fun pulseTransactionsWithValue (denom : String , afterDateTime : LocalDateTime , page : Int , count : Int ): PagedResults <Map <String , kotlin.Any ?>> = transaction {
227
+ val query = """
228
+ select tx.id as tx_id,
229
+ tx.hash,
230
+ tx.height,
231
+ tx.tx_timestamp,
232
+ mtype.category,
233
+ mtype.type,
234
+ mtype.proto_type,
235
+ mtype.module,
236
+ tme.event_type,
237
+ attr.attr_key,
238
+ attr.attr_value
239
+ from tx_cache tx
240
+ join tx_msg_event as tme on tx.id = tme.tx_hash_id
241
+ join tx_msg_event_attr as attr on tme.id = attr.tx_msg_event_id
242
+ join tx_message_type as mtype on mtype.id = tme.tx_msg_type_id
243
+ join tx_marker_join as denom on denom.tx_hash_id = tx.id
244
+ where tme.tx_msg_type_id IN
245
+ (select id from tx_message_type where module in ('exchange', 'bank'))
246
+ and tx.tx_timestamp > ?
247
+ and tx.error_code is null
248
+ and tx.codespace is null
249
+ and denom.denom = ?
250
+ and event_type = 'coin_spent'
251
+ and attr_key = 'amount'
252
+ and attr_value like ?
253
+ order by height desc, tx_id
254
+ """ .trimIndent()
255
+ val arguments = mutableListOf<Pair <ColumnType , * >>(
256
+ Pair (JavaLocalDateTimeColumnType (), afterDateTime),
257
+ Pair (TextColumnType (), denom),
258
+ Pair (TextColumnType (), " %$denom %" ),
259
+ )
260
+
261
+ val countQuery = " select count(*) from ($query ) as count"
262
+ val rowCount = countQuery.execAndMap(arguments) {
263
+ it.getLong(1 )
264
+ }.first()
265
+
266
+ arguments.add(Pair (IntegerColumnType (), count))
267
+ arguments.add(Pair (IntegerColumnType (), page * count))
268
+
269
+ " $query limit ? offset ?" .execAndMap(arguments) {
270
+ val map = mutableMapOf<String , kotlin.Any ?>()
271
+ (1 .. it.metaData.columnCount).forEach { index ->
272
+ map[it.metaData.getColumnName(index)] = it.getObject(index)
273
+ }
274
+ map // return a list of map because i like to party
275
+ }.let {
276
+ PagedResults (rowCount.div(count).toInt(), it, rowCount, emptyMap())
277
+ }
278
+ }
279
+ }
210
280
211
281
var hash by TxCacheTable .hash
212
282
var height by TxCacheTable .height
@@ -364,7 +434,7 @@ class TxMessageRecord(id: EntityID<Int>) : IntEntity(id) {
364
434
365
435
fun findByHashIdPaginated (hashId : Int , msgTypes : List <Int >, limit : Int , offset : Int ) = transaction {
366
436
val query = TxMessageTable
367
- .innerJoin(TxMsgTypeSubtypeTable , { TxMessageTable .id }, { TxMsgTypeSubtypeTable . txMsgId })
437
+ .innerJoin(TxMsgTypeSubtypeTable , { TxMessageTable .id }, { txMsgId })
368
438
.slice(tableColSet)
369
439
.select { TxMessageTable .txHashId eq hashId }
370
440
if (msgTypes.isNotEmpty()) {
@@ -416,17 +486,17 @@ class TxMessageRecord(id: EntityID<Int>) : IntEntity(id) {
416
486
417
487
if (tqp.msgTypes.isNotEmpty())
418
488
join = if (tqp.primaryTypesOnly)
419
- join.innerJoin(TxMsgTypeSubtypeTable , { TxMessageTable .txHashId }, { TxMsgTypeSubtypeTable . txHashId })
489
+ join.innerJoin(TxMsgTypeSubtypeTable , { TxMessageTable .txHashId }, { txHashId })
420
490
else
421
- join.innerJoin(TxMsgTypeQueryTable , { TxMessageTable .txHashId }, { TxMsgTypeQueryTable . txHashId })
491
+ join.innerJoin(TxMsgTypeQueryTable , { TxMessageTable .txHashId }, { txHashId })
422
492
if (tqp.txStatus != null )
423
493
join = join.innerJoin(TxCacheTable , { TxMessageTable .txHashId }, { TxCacheTable .id })
424
494
if ((tqp.addressId != null && tqp.addressType != null ) || tqp.address != null )
425
- join = join.innerJoin(TxAddressJoinTable , { TxMessageTable .txHashId }, { TxAddressJoinTable . txHashId })
495
+ join = join.innerJoin(TxAddressJoinTable , { TxMessageTable .txHashId }, { txHashId })
426
496
if (tqp.smCodeId != null )
427
- join = join.innerJoin(TxSmCodeTable , { TxMessageTable .txHashId }, { TxSmCodeTable . txHashId })
497
+ join = join.innerJoin(TxSmCodeTable , { TxMessageTable .txHashId }, { txHashId })
428
498
if (tqp.smContractAddrId != null )
429
- join = join.innerJoin(TxSmContractTable , { TxMessageTable .txHashId }, { TxSmContractTable . txHashId })
499
+ join = join.innerJoin(TxSmContractTable , { TxMessageTable .txHashId }, { txHashId })
430
500
431
501
val query = if (distinctQuery != null ) join.slice(distinctQuery).selectAll() else join.selectAll()
432
502
@@ -772,13 +842,13 @@ class TxFeeRecord(id: EntityID<Int>) : IntEntity(id) {
772
842
}.let { (baseFeeOverage, baseFeeUsed) ->
773
843
val nhash = assetService.getAssetRaw(ExplorerProperties .UTILITY_TOKEN ).second
774
844
// insert used fee
775
- feeList.add(buildInsert(txInfo, BASE_FEE_USED .name, nhash.id.value, nhash.denom, baseFeeUsed))
845
+ feeList.add(buildInsert(txInfo, FeeType . BASE_FEE_USED .name, nhash.id.value, nhash.denom, baseFeeUsed))
776
846
// insert paid too much fee if > 0
777
847
if (baseFeeOverage > BigDecimal .ZERO ) {
778
848
feeList.add(
779
849
buildInsert(
780
850
txInfo,
781
- BASE_FEE_OVERAGE .name,
851
+ FeeType . BASE_FEE_OVERAGE .name,
782
852
nhash.id.value,
783
853
nhash.denom,
784
854
baseFeeOverage
@@ -789,7 +859,7 @@ class TxFeeRecord(id: EntityID<Int>) : IntEntity(id) {
789
859
if (tx.success()) {
790
860
msgBasedFeeList.forEach { fee ->
791
861
val feeType =
792
- if (fee.msgType == CUSTOM_FEE_MSG_TYPE ) CUSTOM_FEE .name else MSG_BASED_FEE .name
862
+ if (fee.msgType == CUSTOM_FEE_MSG_TYPE ) FeeType . CUSTOM_FEE .name else FeeType . MSG_BASED_FEE .name
793
863
feeList.add(
794
864
buildInsert(
795
865
txInfo,
0 commit comments