Auto-indexing service and GraphQL API for AT Protocol Records quickslice.slices.network/
atproto gleam graphql
at main 76 lines 2.4 kB view raw
1/// Converts GraphQL where input types to SQL where clause types 2/// 3/// This module bridges the gap between the GraphQL layer (lexicon_graphql/input/where) 4/// and the database layer (where_clause with database Value types). 5import database/executor.{type Value, Bool, Int, Text} 6import database/queries/where_clause 7import gleam/dict 8import gleam/list 9import gleam/option.{type Option} 10import lexicon_graphql/input/where 11 12/// Convert a where.WhereValue to a database Value 13fn convert_value(value: where.WhereValue) -> Value { 14 case value { 15 where.StringValue(s) -> Text(s) 16 where.IntValue(i) -> Int(i) 17 where.BoolValue(b) -> Bool(b) 18 } 19} 20 21/// Check if a WhereValue is numeric (Int) 22fn is_numeric_value(value: where.WhereValue) -> Bool { 23 case value { 24 where.IntValue(_) -> True 25 where.StringValue(_) -> False 26 where.BoolValue(_) -> False 27 } 28} 29 30/// Check if any comparison value in the condition is numeric 31fn has_numeric_comparison(cond: where.WhereCondition) -> Bool { 32 let check_opt = fn(opt: Option(where.WhereValue)) -> Bool { 33 case opt { 34 option.Some(v) -> is_numeric_value(v) 35 option.None -> False 36 } 37 } 38 check_opt(cond.gt) 39 || check_opt(cond.gte) 40 || check_opt(cond.lt) 41 || check_opt(cond.lte) 42} 43 44/// Convert a where.WhereCondition to a where_clause.WhereCondition 45fn convert_condition(cond: where.WhereCondition) -> where_clause.WhereCondition { 46 where_clause.WhereCondition( 47 eq: option.map(cond.eq, convert_value), 48 in_values: option.map(cond.in_values, fn(values) { 49 list.map(values, convert_value) 50 }), 51 contains: cond.contains, 52 gt: option.map(cond.gt, convert_value), 53 gte: option.map(cond.gte, convert_value), 54 lt: option.map(cond.lt, convert_value), 55 lte: option.map(cond.lte, convert_value), 56 is_null: cond.is_null, 57 is_numeric: has_numeric_comparison(cond), 58 ) 59} 60 61/// Convert a where.WhereClause to a where_clause.WhereClause 62pub fn convert_where_clause( 63 clause: where.WhereClause, 64) -> where_clause.WhereClause { 65 where_clause.WhereClause( 66 conditions: dict.map_values(clause.conditions, fn(_key, value) { 67 convert_condition(value) 68 }), 69 and: option.map(clause.and, fn(clauses) { 70 list.map(clauses, convert_where_clause) 71 }), 72 or: option.map(clause.or, fn(clauses) { 73 list.map(clauses, convert_where_clause) 74 }), 75 ) 76}