refactor: extract omnigraph-queries crate from omnigraph-server

Move queries.rs (stored-query registry + validation) into omnigraph-queries (deps: omnigraph-config, omnigraph-compiler; no serde). Repoint crate::config -> omnigraph_config. The two catalog-projection tests (which exercise api::query_catalog_entry) are removed here and relocated to omnigraph-api-types in the next commit, where that function lives. Server aliases via 'pub use omnigraph_queries as queries;'. 16 queries tests pass; server+cli compile. No behavior change.
This commit is contained in:
Ragnor Comerford 2026-06-03 10:40:43 +02:00
parent c5ea4875d5
commit 628ecf428a
No known key found for this signature in database
6 changed files with 31 additions and 63 deletions

10
Cargo.lock generated
View file

@ -4649,6 +4649,15 @@ dependencies = [
"tempfile",
]
[[package]]
name = "omnigraph-queries"
version = "0.6.1"
dependencies = [
"omnigraph-compiler",
"omnigraph-config",
"tempfile",
]
[[package]]
name = "omnigraph-server"
version = "0.6.1"
@ -4668,6 +4677,7 @@ dependencies = [
"omnigraph-config",
"omnigraph-engine",
"omnigraph-policy",
"omnigraph-queries",
"regex",
"serde",
"serde_json",

View file

@ -7,6 +7,7 @@ members = [
"crates/omnigraph-policy",
"crates/omnigraph-server",
"crates/omnigraph-config",
"crates/omnigraph-queries",
]
default-members = [
"crates/omnigraph",

View file

@ -0,0 +1,16 @@
[package]
name = "omnigraph-queries"
version = "0.6.1"
edition = "2024"
description = "Stored-query registry and validation for the Omnigraph graph database."
license = "MIT"
repository = "https://github.com/ModernRelay/omnigraph"
homepage = "https://github.com/ModernRelay/omnigraph"
documentation = "https://docs.rs/omnigraph-queries"
[dependencies]
omnigraph-config = { path = "../omnigraph-config", version = "0.6.1" }
omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.1" }
[dev-dependencies]
tempfile = { workspace = true }

View file

@ -22,7 +22,7 @@ use omnigraph_compiler::query::parser::parse_query;
use omnigraph_compiler::query::typecheck::typecheck_query_decl;
use omnigraph_compiler::types::{PropType, ScalarType};
use crate::config::{OmnigraphConfig, QueryEntry};
use omnigraph_config::{OmnigraphConfig, QueryEntry};
/// One loaded stored query. `source` is the full `.gq` file text — the
/// invocation handler hands it to `run_query` / `run_mutate` verbatim,
@ -593,71 +593,11 @@ embedding: Vector(4)
assert!(report.is_clean(), "no breakage or warning expected: {:?}", report);
}
// --- catalog projection (api::query_catalog_entry) ---
#[test]
fn catalog_entry_projects_every_param_kind() {
use crate::api::{self, ParamKind};
let reg = QueryRegistry::from_specs(vec![spec_tool(
"all_types",
"query all_types($s: String, $i: I32, $big: I64, $u: U64, $f: F64, $b: Bool, \
$d: Date, $dt: DateTime, $blob: Blob, $opt: String?, $list: [I32], $vec: Vector(4)) \
{ match { $x: User } return { $x.name } }",
true,
"all",
)])
.unwrap();
let entry = api::query_catalog_entry(reg.lookup("all_types").unwrap());
assert_eq!(entry.name, "all_types");
assert_eq!(entry.tool_name, "all");
assert!(!entry.mutation);
let by: std::collections::HashMap<_, _> =
entry.params.iter().map(|p| (p.name.as_str(), p)).collect();
assert_eq!(by["s"].kind, ParamKind::String);
assert_eq!(by["i"].kind, ParamKind::Int);
assert_eq!(by["big"].kind, ParamKind::BigInt, "I64 → bigint (string on the wire)");
assert_eq!(by["u"].kind, ParamKind::BigInt, "U64 → bigint");
assert_eq!(by["f"].kind, ParamKind::Float);
assert_eq!(by["b"].kind, ParamKind::Bool);
assert_eq!(by["d"].kind, ParamKind::Date);
assert_eq!(by["dt"].kind, ParamKind::DateTime);
assert_eq!(by["blob"].kind, ParamKind::Blob);
assert!(!by["s"].nullable);
assert!(by["opt"].nullable, "String? → nullable");
assert_eq!(by["list"].kind, ParamKind::List);
assert_eq!(by["list"].item_kind, Some(ParamKind::Int), "[I32] → list of int");
assert_eq!(by["vec"].kind, ParamKind::Vector);
assert_eq!(by["vec"].vector_dim, Some(4));
}
#[test]
fn catalog_entry_flags_mutation_and_empty_params() {
use crate::api;
let reg = QueryRegistry::from_specs(vec![spec(
"add_user",
"query add_user($name: String) { insert User { name: $name } }",
true,
)])
.unwrap();
let entry = api::query_catalog_entry(reg.lookup("add_user").unwrap());
assert!(entry.mutation, "insert body → mutation flag");
let reg2 = QueryRegistry::from_specs(vec![spec(
"no_params",
"query no_params() { match { $u: User } return { $u.name } }",
true,
)])
.unwrap();
let entry2 = api::query_catalog_entry(reg2.lookup("no_params").unwrap());
assert!(entry2.params.is_empty(), "no declared params → empty list");
}
// --- load() error collection (file I/O + parse in one pass) ---
#[test]
fn load_collects_io_and_parse_errors_in_one_pass() {
use crate::config::load_config;
use omnigraph_config::load_config;
let temp = tempfile::tempdir().unwrap();
std::fs::write(
temp.path().join("good.gq"),

View file

@ -23,6 +23,7 @@ omnigraph = { package = "omnigraph-engine", path = "../omnigraph", version = "0.
omnigraph-compiler = { path = "../omnigraph-compiler", version = "0.6.1" }
omnigraph-policy = { path = "../omnigraph-policy", version = "0.6.1" }
omnigraph-config = { path = "../omnigraph-config", version = "0.6.1" }
omnigraph-queries = { path = "../omnigraph-queries", version = "0.6.1" }
axum = { workspace = true }
clap = { workspace = true }
color-eyre = { workspace = true }

View file

@ -4,7 +4,7 @@ pub use omnigraph_config as config;
pub mod graph_id;
pub mod identity;
pub mod policy;
pub mod queries;
pub use omnigraph_queries as queries;
pub mod registry;
pub mod workload;