-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bf39b2d
commit 390dd53
Showing
6 changed files
with
504 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
grails-app/services/io/xh/hoist/track/TrackLogAdminService.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package io.xh.hoist.track | ||
|
||
import grails.gorm.transactions.ReadOnly | ||
import io.xh.hoist.BaseService; | ||
import io.xh.hoist.config.ConfigService | ||
import io.xh.hoist.data.filter.Filter | ||
import io.xh.hoist.exception.DataNotAvailableException | ||
import org.hibernate.Criteria | ||
import org.hibernate.SessionFactory | ||
import java.time.LocalDate; | ||
|
||
import static io.xh.hoist.util.DateTimeUtils.appEndOfDay | ||
import static io.xh.hoist.util.DateTimeUtils.appStartOfDay | ||
import static org.hibernate.criterion.Order.desc | ||
import static org.hibernate.criterion.Restrictions.between | ||
|
||
class TrackLogAdminService extends BaseService { | ||
ConfigService configService | ||
SessionFactory sessionFactory | ||
|
||
Boolean getEnabled() { | ||
return conf.enabled == true | ||
} | ||
|
||
@ReadOnly | ||
List<TrackLog> queryTrackLog(LocalDate startDay, LocalDate endDay, Filter filter, Integer maxRows = null) { | ||
if (!enabled) throw new DataNotAvailableException('TrackService not available.') | ||
|
||
def maxDefault = conf.maxRows.default as Integer, | ||
maxLimit = conf.maxRows.limit as Integer | ||
|
||
maxRows = [(maxRows ? maxRows : maxDefault), maxLimit].min() | ||
|
||
def session = sessionFactory.currentSession | ||
Criteria c = session.createCriteria(TrackLog) | ||
c.maxResults = maxRows | ||
c.addOrder(desc('dateCreated')) | ||
c.add(between('dateCreated', appStartOfDay(startDay), appEndOfDay(endDay))) | ||
if (filter) { | ||
c.add(filter.criterion) | ||
} | ||
c.list() as List<TrackLog> | ||
} | ||
|
||
@ReadOnly | ||
Map lookups() {[ | ||
category: distinctVals('category'), | ||
browser: distinctVals('browser'), | ||
device: distinctVals('device'), | ||
username: distinctVals('username') | ||
] } | ||
|
||
//------------------------ | ||
// Implementation | ||
//------------------------ | ||
private List distinctVals(String property) { | ||
TrackLog.createCriteria().list { | ||
projections { distinct(property) } | ||
}.sort() | ||
} | ||
|
||
private Map getConf() { | ||
configService.getMap('xhActivityTrackingConfig') | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/main/groovy/io/xh/hoist/data/filter/CompoundFilter.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* This file belongs to Hoist, an application development toolkit | ||
* developed by Extremely Heavy Industries (www.xh.io | [email protected]) | ||
* | ||
* Copyright © 2024 Extremely Heavy Industries Inc. | ||
*/ | ||
|
||
package io.xh.hoist.data.filter | ||
|
||
import io.xh.hoist.json.JSONFormat | ||
import org.hibernate.criterion.Criterion | ||
|
||
/** | ||
* Combines multiple filters (including other nested CompoundFilters) via an AND or OR operator. | ||
*/ | ||
class CompoundFilter extends Filter implements JSONFormat { | ||
|
||
final List<Filter> filters | ||
final String op | ||
|
||
CompoundFilter(List filters, String op) { | ||
op = op ? op.toUpperCase() : 'AND' | ||
if (op != 'AND' && op != 'OR') throw new RuntimeException('CompoundFilter requires "op" value of "AND" or "OR"') | ||
this.filters = filters.collect { parse(it) }.findAll() | ||
this.op = op | ||
} | ||
|
||
Map formatForJSON() { | ||
return [ | ||
filters: filters, | ||
op: op | ||
] | ||
} | ||
|
||
//--------------------- | ||
// Overrides | ||
//---------------------- | ||
List<String> getAllFields() { | ||
filters.collectMany { it.allFields }.unique() | ||
} | ||
|
||
Criterion getCriterion() { | ||
op == 'AND' ? and(filters*.criterion) : or(filters*.criterion) | ||
} | ||
|
||
Closure<Boolean> getTestFn() { | ||
if (!filters) return { true } | ||
def tests = filters*.testFn | ||
return op == 'AND' ? | ||
{ tests.every { test -> test(it) } } : | ||
{ tests.any { test -> test(it) } } | ||
} | ||
|
||
boolean equals(Filter other) { | ||
if (other === this) return true; | ||
return ( | ||
other instanceof CompoundFilter && | ||
other.op == op && | ||
other.filters == filters | ||
) | ||
} | ||
} |
Oops, something went wrong.