Skip to content

Commit

Permalink
Migrate AsyncCheckProvider.status()
Browse files Browse the repository at this point in the history
  • Loading branch information
antweb committed Oct 18, 2024
1 parent a4f581b commit b7907ea
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@ import eu.pretix.libpretixsync.crypto.readPubkeyFromPem
import eu.pretix.libpretixsync.crypto.sig1.TicketProtos
import eu.pretix.libpretixsync.db.Answer
import eu.pretix.libpretixsync.db.NonceGenerator
import eu.pretix.libpretixsync.db.Order
import eu.pretix.libpretixsync.db.OrderPosition
import eu.pretix.libpretixsync.db.QuestionLike
import eu.pretix.libpretixsync.db.QueuedCall
import eu.pretix.libpretixsync.db.QueuedCheckIn
import eu.pretix.libpretixsync.models.CheckIn
import eu.pretix.libpretixsync.models.CheckInList
import eu.pretix.libpretixsync.models.Event
import eu.pretix.libpretixsync.models.Order as OrderModel
import eu.pretix.libpretixsync.models.OrderPosition as OrderPositionModel
Expand All @@ -29,7 +26,6 @@ import eu.pretix.libpretixsync.utils.logic.JsonLogic
import eu.pretix.libpretixsync.utils.logic.truthy
import io.requery.BlockingEntityStore
import io.requery.Persistable
import io.requery.kotlin.Logical
import io.requery.query.*
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
Expand Down Expand Up @@ -1129,48 +1125,6 @@ class AsyncCheckProvider(private val config: ConfigStore, private val dataStore:
return results
}

private fun basePositionQuery(lists: List<CheckInList>, onlyCheckedIn: Boolean): WhereAndOr<out Scalar<Int?>?> {

var q = dataStore.count(OrderPosition::class.java).distinct()
.leftJoin(Order::class.java).on(OrderPosition.ORDER_ID.eq(Order.ID))
.where(OrderPosition.SERVER_ID.eq(-1)) // stupid logic node just so we can dynamically add .or() below

for (list in lists) {
var lq: Logical<*, *> = Order.EVENT_SLUG.eq(list.eventSlug)
if (list.includePending) {
lq = lq.and(Order.STATUS.`in`(listOf("p", "n")))
} else {
lq = lq.and(Order.STATUS.eq("p").or(Order.STATUS.eq("n").and(Order.VALID_IF_PENDING.eq(true))))
}

if (list.subEventId != null && list.subEventId > 0) {
lq = lq.and(OrderPosition.SUBEVENT_ID.eq(list.subEventId))
}

if (!list.allItems) {
val product_ids = db.checkInListQueries.selectItemIdsForList(list.id)
.executeAsList()
.map {
// Not-null assertion needed for SQLite
it.id!!
}
lq = lq.and(OrderPosition.ITEM_ID.`in`(product_ids))
}

if (onlyCheckedIn) {
lq = lq.and(OrderPosition.ID.`in`(
db.checkInQueries.selectPositionIdByListIdAndType(
list_server_id = list.serverId,
type = "entry"
).executeAsList().map { it.position }
))
}
q = q.or(lq)
}

return q
}

@Throws(CheckException::class)
override fun status(eventSlug: String, listId: Long): TicketCheckProvider.StatusResult {
sentry.addBreadcrumb("provider.status", "offline status started")
Expand All @@ -1195,24 +1149,75 @@ class AsyncCheckProvider(private val config: ConfigStore, private val dataStore:
for (product in products) {
val variations: MutableList<TicketCheckProvider.StatusResultItemVariation> = ArrayList()
try {
val subEventId = if (list.subEventId != null && list.subEventId > 0) list.subEventId else -1L

val notAllItems = !list.allItems
val listItemIds = if (notAllItems) {
db.checkInListQueries.selectItemIdsForList(list.id)
.executeAsList()
.map {
// Not-null assertion needed for SQLite
it.id!!
}
} else {
// Dummy ID that is not used. Required for SQLDelight to generate valid SQL.
// See comments in search().
listOf(-1L)
}

for (`var` in product.variations) {
val position_count = basePositionQuery(listOf(list), false)
.and(OrderPosition.ITEM_ID.eq(product.id))
.and(OrderPosition.VARIATION_ID.eq(`var`.server_id)).get()!!.value()!!
val ci_count = basePositionQuery(listOf(list), true)
.and(OrderPosition.ITEM_ID.eq(product.id))
.and(OrderPosition.VARIATION_ID.eq(`var`.server_id)).get()!!.value()!!
val position_count = db.orderPositionQueries.countForStatus(
event_slug = list.eventSlug,
include_pending = list.includePending,
subevent_id = subEventId,
not_all_items = notAllItems,
list_item_ids = listItemIds,
only_checked_in_list_server_id = -1L,
item_id = product.id,
variation_id = `var`.server_id,
).executeAsOne().toInt()

val ci_count = db.orderPositionQueries.countForStatus(
event_slug = list.eventSlug,
include_pending = list.includePending,
subevent_id = subEventId,
not_all_items = notAllItems,
list_item_ids = listItemIds,
only_checked_in_list_server_id = list.serverId,
item_id = product.id,
variation_id = `var`.server_id,
).executeAsOne().toInt()

variations.add(TicketCheckProvider.StatusResultItemVariation(
`var`.server_id,
`var`.stringValue,
position_count,
ci_count
))
}
val position_count = basePositionQuery(listOf(list), false)
.and(OrderPosition.ITEM_ID.eq(product.id)).get()!!.value()!!
val ci_count = basePositionQuery(listOf(list), true)
.and(OrderPosition.ITEM_ID.eq(product.id)).get()!!.value()!!

val position_count = db.orderPositionQueries.countForStatus(
event_slug = list.eventSlug,
include_pending = list.includePending,
subevent_id = subEventId,
not_all_items = notAllItems,
list_item_ids = listItemIds,
only_checked_in_list_server_id = -1L,
item_id = product.id,
variation_id = -1L,
).executeAsOne().toInt()

val ci_count = db.orderPositionQueries.countForStatus(
event_slug = list.eventSlug,
include_pending = list.includePending,
subevent_id = subEventId,
not_all_items = notAllItems,
list_item_ids = listItemIds,
only_checked_in_list_server_id = list.serverId,
item_id = product.id,
variation_id = -1L,
).executeAsOne().toInt()

items.add(TicketCheckProvider.StatusResultItem(
product.serverId,
product.internalName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,25 @@ AND (
)
LIMIT :limit
OFFSET :offset;

countForStatus:
-- TODO: Check if DISTINCT is required here
SELECT COUNT(DISTINCT OrderPosition.id)
FROM OrderPosition
LEFT JOIN orders ON OrderPosition.order_ref = orders.id
WHERE(
orders.event_slug = :event_slug
AND CASE WHEN (:include_pending)
THEN orders.status IN ('p', 'n')
ELSE (orders.status = 'p' OR (orders.status = 'n' AND orders.valid_if_pending = TRUE))
END
AND CASE WHEN (:subevent_id > 0) THEN OrderPosition.subevent_id = :subevent_id ELSE TRUE END
AND CASE WHEN (:not_all_items) THEN OrderPosition.item IN :list_item_ids ELSE TRUE END
AND CASE WHEN (:only_checked_in_list_server_id > 0) THEN
(OrderPosition.id IN (SELECT position FROM CheckIn WHERE listId = :only_checked_in_list_server_id AND type = 'entry'))
ELSE
TRUE
END
AND OrderPosition.item = :item_id
AND CASE WHEN (:variation_id > 0) THEN OrderPosition.variation_id = :variation_id ELSE TRUE END
);

0 comments on commit b7907ea

Please sign in to comment.