Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions newswires/app/controllers/QueryController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import play.api.{Configuration, Logging}
import service.FeatureSwitchProvider

import java.time.Instant
import scala.util.Random

class QueryController(
val controllerComponents: ControllerComponents,
Expand Down Expand Up @@ -95,16 +94,8 @@ class QueryController(
timeStampColumn = timeStampColumn
)

val queryVariant = request.getQueryString("variant") match {
case Some("not_exists") => NotExists
case Some("plain_not") => PlainNot
case _ if Random.nextBoolean() => NotExists
case _ => PlainNot
}

val queryResponse = FingerpostWireEntry.query(
queryParams,
queryVariant = queryVariant,
countQueryCap = countQueryCap.getOrElse(COUNT_QUERY_CAP)
)

Expand Down
79 changes: 26 additions & 53 deletions newswires/app/db/FingerpostWireEntry.scala
Original file line number Diff line number Diff line change
Expand Up @@ -188,25 +188,9 @@ object FingerpostWireEntry

object Filters {
private def exclusionCondition(
alias: QuerySQLSyntaxProvider[SQLSyntaxSupport[
FingerpostWireEntry
], FingerpostWireEntry],
queryVariant: QueryVariant = PlainNot
)(innerClause: SQLSyntax) = {
queryVariant match {
case NotExists =>
// unpleasant, but the sort of trick you need to pull
// because "NOT IN (...)" doesn't hit an index.
// https://stackoverflow.com/a/19364694

sqls"""|NOT EXISTS (
| SELECT FROM ${FingerpostWireEntry as alias}
| WHERE ${syn.id} = ${alias.id}
| AND $innerClause
|)""".stripMargin

case PlainNot => sqls"NOT ($innerClause)"
}
innerClause: SQLSyntax
) = {
sqls"NOT ($innerClause)"
}

private def supplierCondition(
Expand Down Expand Up @@ -263,10 +247,9 @@ object FingerpostWireEntry
(suppliers: List[String]) => supplierCondition(syn, suppliers)

def supplierExclSQL(
suppliersExcl: List[String],
queryVariant: QueryVariant = PlainNot
suppliersExcl: List[String]
) = {
exclusionCondition(syn, queryVariant)(
exclusionCondition(
supplierCondition(syn, suppliersExcl)
)
}
Expand All @@ -279,10 +262,9 @@ object FingerpostWireEntry
)

def guSourceFeedExclSQL(
guSourceFeedsExcl: List[String],
queryVariant: QueryVariant = PlainNot
guSourceFeedsExcl: List[String]
) = {
exclusionCondition(syn, queryVariant)(
exclusionCondition(
sqls.in(
sqls"upper(${syn.guSourceFeed})",
guSourceFeedsExcl.map(feed => sqls"upper($feed)")
Expand Down Expand Up @@ -340,10 +322,9 @@ object FingerpostWireEntry
(keywords: List[String]) => keywordCondition(syn, keywords)

def keywordsExclSQL(
keywords: List[String],
queryVariant: QueryVariant = PlainNot
keywords: List[String]
): SQLSyntax = {
exclusionCondition(syn, queryVariant)(keywordCondition(syn, keywords))
exclusionCondition(keywordCondition(syn, keywords))
}

lazy val categoryCodeInclSQL =
Expand All @@ -356,10 +337,9 @@ object FingerpostWireEntry
}

def categoryCodeExclSQL(
categoryCodesExcl: List[String],
queryVariant: QueryVariant = PlainNot
categoryCodesExcl: List[String]
) = {
exclusionCondition(syn, queryVariant)(
exclusionCondition(
categoryCodeSomeConditions(syn, categoryCodesExcl)
)
}
Expand Down Expand Up @@ -403,10 +383,9 @@ object FingerpostWireEntry
}

def preComputedCategoriesExclSQL(
preComputedCategories: List[String],
queryVariant: QueryVariant = PlainNot
preComputedCategories: List[String]
) = {
exclusionCondition(syn, queryVariant)(
exclusionCondition(
preComputedCategoriesConditions(syn, preComputedCategories)
)
}
Expand All @@ -431,8 +410,7 @@ object FingerpostWireEntry
}

private[db] def filtersBuilder(
filters: FilterParams,
queryVariant: QueryVariant = PlainNot
filters: FilterParams
): Option[SQLSyntax] = {
val suppliersQuery: Option[SQLSyntax] = filters.suppliersIncl match {
case Nil => None
Expand All @@ -442,7 +420,7 @@ object FingerpostWireEntry
val suppliersExclQuery: Option[SQLSyntax] = filters.suppliersExcl match {
case Nil => None
case suppliersExcl =>
Some(Filters.supplierExclSQL(suppliersExcl, queryVariant))
Some(Filters.supplierExclSQL(suppliersExcl))
}

val searchQuery: Option[SQLSyntax] =
Expand All @@ -455,7 +433,7 @@ object FingerpostWireEntry

val keywordsExclQuery = filters.keywordExcl match {
case Nil => None
case keywords => Some(Filters.keywordsExclSQL(keywords, queryVariant))
case keywords => Some(Filters.keywordsExclSQL(keywords))
}

val categoryCodesInclQuery = filters.categoryCodesIncl match {
Expand All @@ -467,7 +445,7 @@ object FingerpostWireEntry
val categoryCodesExclQuery = filters.categoryCodesExcl match {
case Nil => None
case categoryCodesExcl =>
Some(Filters.categoryCodeExclSQL(categoryCodesExcl, queryVariant))
Some(Filters.categoryCodeExclSQL(categoryCodesExcl))
}

val hasDataFormattingQuery = filters.hasDataFormatting match {
Expand All @@ -488,8 +466,7 @@ object FingerpostWireEntry
case presetCategoriesExcl =>
Some(
Filters.preComputedCategoriesExclSQL(
presetCategoriesExcl,
queryVariant
presetCategoriesExcl
)
)
}
Expand All @@ -507,7 +484,7 @@ object FingerpostWireEntry
val guSourceFeedExclQuery = filters.guSourceFeedsExcl match {
case Nil => None
case sourceFeedsExcl =>
Some(Filters.guSourceFeedExclSQL(sourceFeedsExcl, queryVariant))
Some(Filters.guSourceFeedExclSQL(sourceFeedsExcl))
}

val eventCodeQuery = filters.eventCode match {
Expand Down Expand Up @@ -535,10 +512,9 @@ object FingerpostWireEntry
}

private[db] def presetsBuilder(
presets: List[FilterParams],
queryVariant: QueryVariant = PlainNot
presets: List[FilterParams]
): Option[SQLSyntax] = {
val andClauses = presets.flatMap(p => filtersBuilder(p, queryVariant))
val andClauses = presets.flatMap(p => filtersBuilder(p))
orAll(andClauses)
}

Expand All @@ -562,8 +538,7 @@ object FingerpostWireEntry
queryCursor: QueryCursor,
queryOrdering: TimeStampColumn,
searchPresets: List[FilterParams] = Nil,
negatedSearchPresets: List[FilterParams] = Nil,
queryVariant: QueryVariant = PlainNot
negatedSearchPresets: List[FilterParams] = Nil
): SQLSyntax = {

val dataOnlyWhereClauses = queryCursorQuery(queryCursor, queryOrdering)
Expand All @@ -572,8 +547,8 @@ object FingerpostWireEntry
searchParams.dateRange.end,
queryOrdering
)
val customSearchClauses = filtersBuilder(searchParams.filters, queryVariant)
val presetSearchClauses = presetsBuilder(searchPresets, queryVariant)
val customSearchClauses = filtersBuilder(searchParams.filters)
val presetSearchClauses = presetsBuilder(searchPresets)
val negatedPresetSearchClauses =
presetsBuilder(negatedSearchPresets).map(clause => sqls"NOT $clause")

Expand Down Expand Up @@ -653,8 +628,7 @@ object FingerpostWireEntry

def query(
queryParams: QueryParams,
countQueryCap: Long = COUNT_QUERY_CAP,
queryVariant: QueryVariant = PlainNot
countQueryCap: Long = COUNT_QUERY_CAP
): QueryResponse = DB readOnly { implicit session =>
val whereClause = buildWhereClause(
queryParams.searchParams,
Expand Down Expand Up @@ -721,8 +695,7 @@ object FingerpostWireEntry
QueryResponse(
results,
totalCount,
countQueryCap,
queryVariant
countQueryCap
)
}

Expand Down
34 changes: 0 additions & 34 deletions newswires/app/db/QueryVariant.scala

This file was deleted.

5 changes: 2 additions & 3 deletions newswires/app/models/QueryResponse.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package models

import db.{FingerpostWireEntry, QueryVariant, TimeStampColumn, ToolLink}
import db.{FingerpostWireEntry, TimeStampColumn, ToolLink}
import io.circe.generic.semiauto.{deriveDecoder, deriveEncoder}
import io.circe.{Decoder, Encoder}

case class QueryResponse(
results: List[FingerpostWireEntry],
totalCount: Long,
countQueryCap: Long,
queryVariant: QueryVariant
countQueryCap: Long
// keywordCounts: Map[String, Int]
)

Expand Down
6 changes: 0 additions & 6 deletions newswires/client/src/context/SearchContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -643,11 +643,5 @@ function createFetchedResultsTelemetryData({
totalCount: data.totalCount,
isRefresh,
requestId,
...Object.fromEntries(
Object.entries(data.queryVariant ?? {}).map(([key, value]) => [
`query-variant_${key}`,
JSON.stringify(value),
]),
),
};
}
10 changes: 0 additions & 10 deletions newswires/client/src/sharedTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ export const WiresQueryResponseSchema = z.object({
results: z.array(WireDataFromAPISchema),
totalCount: z.number(),
countQueryCap: z.number(),
queryVariant: z
.object({
name: z.string(),
description: z.string(),
})
.optional(),
// keywordCounts: z.record(z.string(), z.number()),
});

Expand Down Expand Up @@ -150,10 +144,6 @@ export type WiresQueryData = {
results: WireData[];
totalCount: number;
countQueryCap: number;
queryVariant?: {
name: string;
description: string;
};
};

export const isValidDateValue = (value: string): value is EuiDateString =>
Expand Down
45 changes: 0 additions & 45 deletions newswires/test/db/FingerpostWireEntrySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -786,51 +786,6 @@ class FingerpostWireEntrySpec extends AnyFlatSpec with Matchers with models {
)
}

behavior of "exclusion clauses when NotExists variant is specified"
it should "create the correct sql snippet for suppliersExcl when NotExists variant is specified" in {
val supplierExclClause =
"NOT EXISTS ( SELECT FROM fingerpost_wire_entry fm WHERE fm.id = fm.id AND upper(fm.supplier) in (upper(?)) )"
val suppliersExclSQL =
FingerpostWireEntry.Filters.supplierExclSQL(List("supplier"), NotExists)
suppliersExclSQL should matchSqlSnippet(
expectedClause = supplierExclClause,
expectedParams = List("supplier")
)
}
it should "create the correct sql snippet for categoryCodesExcl when NotExists variant is specified" in {
val categoryExclClause =
"NOT EXISTS ( SELECT FROM fingerpost_wire_entry fm WHERE fm.id = fm.id AND fm.category_codes && ? )"
val categoryCodesExcl =
FingerpostWireEntry.Filters.categoryCodeExclSQL(List("code"), NotExists)
categoryCodesExcl should matchSqlSnippet(
expectedClause = categoryExclClause,
expectedParams = List(List("code"))
)
}
it should "create the correct sql snippet for precomputedCategoriesExcl when NotExists variant is specified" in {
val precomputedCategoriesExclClause =
"NOT EXISTS ( SELECT FROM fingerpost_wire_entry fm WHERE fm.id = fm.id AND fm.precomputed_categories && ? )"
val precomputedCategoriesExcl =
FingerpostWireEntry.Filters.preComputedCategoriesExclSQL(
List("category"),
NotExists
)
precomputedCategoriesExcl should matchSqlSnippet(
expectedClause = precomputedCategoriesExclClause,
expectedParams = List(List("category"))
)
}
it should "create the correct sql snippet for keywordsExcl when NotExists variant is specified" in {
val keywordExclClause =
"NOT EXISTS ( SELECT FROM fingerpost_wire_entry fm WHERE fm.id = fm.id AND (fm.content -> 'keywords') ??| ? )"
val keywordExclSQL =
FingerpostWireEntry.Filters.keywordsExclSQL(List("keyword"), NotExists)
keywordExclSQL should matchSqlSnippet(
expectedClause = keywordExclClause,
expectedParams = List(List("keyword"))
)
}

behavior of "dataformatting SQL helpers"
it should "create the correct sql snippet for hasDataFormatting set to true" in {
val hasDataFormattingSQL =
Expand Down
10 changes: 2 additions & 8 deletions newswires/test/models/QueryResponseSpec.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package models

import db.{
AddedToCollectionAtTime,
FingerpostWireEntry,
IngestedAtTime,
PlainNot
}
import db.{AddedToCollectionAtTime, FingerpostWireEntry, IngestedAtTime}
import helpers.models
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
Expand All @@ -20,8 +15,7 @@ class QueryResponseSpec extends AnyFlatSpec with Matchers with models {
QueryResponse(
results = results,
totalCount = results.length,
countQueryCap = FingerpostWireEntry.COUNT_QUERY_CAP,
queryVariant = PlainNot
countQueryCap = FingerpostWireEntry.COUNT_QUERY_CAP
)

behavior of "QueryResponse.display"
Expand Down
Loading