Skip to content

Commit

Permalink
feat: Develop constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
ppodolsky committed Oct 23, 2023
1 parent e3cc49a commit f5a44a6
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 165 deletions.
14 changes: 10 additions & 4 deletions summa-core/src/validators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ pub fn parse_fields<'a>(schema: &'a Schema, fields: &'a [String], removed_fields
} else if fields.is_empty() {
Ok(schema
.fields()
.map(|(_, field_entry)| {
schema
.find_field(field_entry.name())
.ok_or_else(|| ValidationError::MissingField(field_entry.name().to_string()))
.filter_map(|(_, field_entry)| {
if removed_fields.iter().any(|e| e == field_entry.name()) {
None
} else {
Some(
schema
.find_field(field_entry.name())
.ok_or_else(|| ValidationError::MissingField(field_entry.name().to_string())),
)
}
})
.collect::<Result<_, _>>()?)
} else {
Expand Down
1 change: 0 additions & 1 deletion summa-proto/proto/public_service.proto
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
syntax = "proto3";
package summa.proto;

import "search_service.proto";
import "query.proto";


Expand Down
14 changes: 14 additions & 0 deletions summa-proto/proto/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ message QueryParserConfig {
optional string query_language = 11;
}

message SearchRequest {
// The index name or alias
string index_alias = 1;
// Query DSL. Use `MatchQuery` to pass a free-form query
Query query = 2;
// Every collector is responsible of processing and storing documents and/or their derivatives (like counters)
// to return them to the caller
repeated Collector collectors = 3;
// Is requiring fieldnorms needed for the query?
optional bool is_fieldnorms_scoring_enabled = 4;
optional bool load_cache = 5;
optional bool store_cache = 6;
}

message SearchResponse {
// Time spent inside of `search` handler
double elapsed_secs = 1;
Expand Down
14 changes: 0 additions & 14 deletions summa-proto/proto/search_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,3 @@ service SearchApi {
// Make search in Summa
rpc search (SearchRequest) returns (SearchResponse) {}
}

message SearchRequest {
// The index name or alias
string index_alias = 1;
// Query DSL. Use `MatchQuery` to pass a free-form query
Query query = 2;
// Every collector is responsible of processing and storing documents and/or their derivatives (like counters)
// to return them to the caller
repeated Collector collectors = 3;
// Is requiring fieldnorms needed for the query?
optional bool is_fieldnorms_scoring_enabled = 4;
optional bool load_cache = 5;
optional bool store_cache = 6;
}
3 changes: 3 additions & 0 deletions summa-server/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum Error {
Json(#[from] serde_json::Error),
#[error("lock_error: {0}")]
Lock(#[from] tokio::sync::TryLockError),
#[error("not_allowed_error")]
NotAllowed,
#[error("tantivy_error: {0}")]
Tantivy(#[from] tantivy::TantivyError),
#[error("timeout_error: {0}")]
Expand Down Expand Up @@ -94,6 +96,7 @@ impl From<Error> for tonic::Status {
},
Error::Validation(ValidationError::MissingIndex(_)) => tonic::Code::NotFound,
Error::Validation(_) => tonic::Code::InvalidArgument,
Error::NotAllowed => tonic::Code::PermissionDenied,
Error::Lock(_) => tonic::Code::FailedPrecondition,
_ => tonic::Code::Internal,
},
Expand Down
1 change: 1 addition & 0 deletions summa-server/src/services/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ impl Api {
.add_service(grpc_reflection_service)
.add_service(consumer_service.clone())
.add_service(index_service.clone())
.add_service(public_service.clone())
.add_service(reflection_service.clone())
.add_service(search_service.clone());
let grpc_listener = Api::set_listener(&api_config.grpc_endpoint)?;
Expand Down
11 changes: 7 additions & 4 deletions summa-server/src/services/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,9 @@ impl Index {
.and_then(|query| query.query)
.unwrap_or_else(|| proto::query::Query::All(proto::AllQuery {}));

if search_request.collectors.len() > 2 {
return Err(crate::errors::Error::NotAllowed);
}
for collector in &mut search_request.collectors {
match &mut collector.collector {
Some(proto::collector::Collector::TopDocs(top_docs)) => {
Expand All @@ -667,7 +670,7 @@ impl Index {
reservoir_sampling.removed_fields = vec!["content".to_string()];
}
Some(proto::collector::Collector::Count(_)) => {}
_ => panic!("Not allowed"),
_ => return Err(crate::errors::Error::NotAllowed),
}
}

Expand All @@ -676,9 +679,9 @@ impl Index {
&search_request.index_alias,
query,
search_request.collectors,
search_request.is_fieldnorms_scoring_enabled,
search_request.load_cache,
search_request.store_cache,
Some(true),
Some(true),
Some(true),
)
.await?;
Ok(self.index_registry.finalize_extraction(collector_outputs).await?)
Expand Down
2 changes: 1 addition & 1 deletion summa-wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "summa-wasm"
version = "0.133.0"
version = "0.133.3"
authors = ["Pasha Podolsky <[email protected]>"]
edition = "2021"
license-file = "LICENSE"
Expand Down
2 changes: 1 addition & 1 deletion summa-wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "summa-wasm",
"description": "WASM-bindings for Summa",
"version": "0.133.0",
"version": "0.133.3",
"keywords": [
"search",
"database",
Expand Down
2 changes: 2 additions & 0 deletions summa-wasm/src/grpc-web/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export * as index_service from "./index_service"
export * as public_service from "./public_service"
export * as public_service_client from "./public_service.client"
export * as query from "./query"
export * as search_service from "./search_service"
export * as search_service_client from "./search_service.client"
2 changes: 1 addition & 1 deletion summa-wasm/src/grpc-web/public_service.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { ServiceInfo } from "@protobuf-ts/runtime-rpc";
import { PublicApi } from "./public_service";
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
import type { SearchResponse } from "./query";
import type { SearchRequest } from "./search_service";
import type { SearchRequest } from "./query";
import type { UnaryCall } from "@protobuf-ts/runtime-rpc";
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
/**
Expand Down
2 changes: 1 addition & 1 deletion summa-wasm/src/grpc-web/public_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @generated from protobuf file "public_service.proto" (package "summa.proto", syntax proto3)
// tslint:disable
import { SearchResponse } from "./query";
import { SearchRequest } from "./search_service";
import { SearchRequest } from "./query";
import { ServiceType } from "@protobuf-ts/runtime-rpc";
/**
* @generated ServiceType for protobuf service summa.proto.PublicApi
Expand Down
120 changes: 120 additions & 0 deletions summa-wasm/src/grpc-web/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,44 @@ export interface QueryParserConfig {
*/
query_language?: string;
}
/**
* @generated from protobuf message summa.proto.SearchRequest
*/
export interface SearchRequest {
/**
* The index name or alias
*
* @generated from protobuf field: string index_alias = 1;
*/
index_alias: string;
/**
* Query DSL. Use `MatchQuery` to pass a free-form query
*
* @generated from protobuf field: summa.proto.Query query = 2;
*/
query?: Query;
/**
* Every collector is responsible of processing and storing documents and/or their derivatives (like counters)
* to return them to the caller
*
* @generated from protobuf field: repeated summa.proto.Collector collectors = 3;
*/
collectors: Collector[];
/**
* Is requiring fieldnorms needed for the query?
*
* @generated from protobuf field: optional bool is_fieldnorms_scoring_enabled = 4;
*/
is_fieldnorms_scoring_enabled?: boolean;
/**
* @generated from protobuf field: optional bool load_cache = 5;
*/
load_cache?: boolean;
/**
* @generated from protobuf field: optional bool store_cache = 6;
*/
store_cache?: boolean;
}
/**
* @generated from protobuf message summa.proto.SearchResponse
*/
Expand Down Expand Up @@ -1263,6 +1301,88 @@ class QueryParserConfig$Type extends MessageType<QueryParserConfig> {
*/
export const QueryParserConfig = new QueryParserConfig$Type();
// @generated message type with reflection information, may provide speed optimized methods
class SearchRequest$Type extends MessageType<SearchRequest> {
constructor() {
super("summa.proto.SearchRequest", [
{ no: 1, name: "index_alias", kind: "scalar", localName: "index_alias", T: 9 /*ScalarType.STRING*/ },
{ no: 2, name: "query", kind: "message", T: () => Query },
{ no: 3, name: "collectors", kind: "message", repeat: 1 /*RepeatType.PACKED*/, T: () => Collector },
{ no: 4, name: "is_fieldnorms_scoring_enabled", kind: "scalar", localName: "is_fieldnorms_scoring_enabled", opt: true, T: 8 /*ScalarType.BOOL*/ },
{ no: 5, name: "load_cache", kind: "scalar", localName: "load_cache", opt: true, T: 8 /*ScalarType.BOOL*/ },
{ no: 6, name: "store_cache", kind: "scalar", localName: "store_cache", opt: true, T: 8 /*ScalarType.BOOL*/ }
]);
}
create(value?: PartialMessage<SearchRequest>): SearchRequest {
const message = { index_alias: "", collectors: [] };
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
if (value !== undefined)
reflectionMergePartial<SearchRequest>(this, message, value);
return message;
}
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: SearchRequest): SearchRequest {
let message = target ?? this.create(), end = reader.pos + length;
while (reader.pos < end) {
let [fieldNo, wireType] = reader.tag();
switch (fieldNo) {
case /* string index_alias */ 1:
message.index_alias = reader.string();
break;
case /* summa.proto.Query query */ 2:
message.query = Query.internalBinaryRead(reader, reader.uint32(), options, message.query);
break;
case /* repeated summa.proto.Collector collectors */ 3:
message.collectors.push(Collector.internalBinaryRead(reader, reader.uint32(), options));
break;
case /* optional bool is_fieldnorms_scoring_enabled */ 4:
message.is_fieldnorms_scoring_enabled = reader.bool();
break;
case /* optional bool load_cache */ 5:
message.load_cache = reader.bool();
break;
case /* optional bool store_cache */ 6:
message.store_cache = reader.bool();
break;
default:
let u = options.readUnknownField;
if (u === "throw")
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
let d = reader.skip(wireType);
if (u !== false)
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
}
}
return message;
}
internalBinaryWrite(message: SearchRequest, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
/* string index_alias = 1; */
if (message.index_alias !== "")
writer.tag(1, WireType.LengthDelimited).string(message.index_alias);
/* summa.proto.Query query = 2; */
if (message.query)
Query.internalBinaryWrite(message.query, writer.tag(2, WireType.LengthDelimited).fork(), options).join();
/* repeated summa.proto.Collector collectors = 3; */
for (let i = 0; i < message.collectors.length; i++)
Collector.internalBinaryWrite(message.collectors[i], writer.tag(3, WireType.LengthDelimited).fork(), options).join();
/* optional bool is_fieldnorms_scoring_enabled = 4; */
if (message.is_fieldnorms_scoring_enabled !== undefined)
writer.tag(4, WireType.Varint).bool(message.is_fieldnorms_scoring_enabled);
/* optional bool load_cache = 5; */
if (message.load_cache !== undefined)
writer.tag(5, WireType.Varint).bool(message.load_cache);
/* optional bool store_cache = 6; */
if (message.store_cache !== undefined)
writer.tag(6, WireType.Varint).bool(message.store_cache);
let u = options.writeUnknownFields;
if (u !== false)
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
return writer;
}
}
/**
* @generated MessageType for protobuf message summa.proto.SearchRequest
*/
export const SearchRequest = new SearchRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class SearchResponse$Type extends MessageType<SearchResponse> {
constructor() {
super("summa.proto.SearchResponse", [
Expand Down
2 changes: 1 addition & 1 deletion summa-wasm/src/grpc-web/search_service.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { ServiceInfo } from "@protobuf-ts/runtime-rpc";
import { SearchApi } from "./search_service";
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
import type { SearchResponse } from "./query";
import type { SearchRequest } from "./search_service";
import type { SearchRequest } from "./query";
import type { UnaryCall } from "@protobuf-ts/runtime-rpc";
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
/**
Expand Down
Loading

0 comments on commit f5a44a6

Please sign in to comment.