Skip to content

Commit 65b16a4

Browse files
authored
Merge pull request #491 from supabase/or/release-1-5-0
Update version for 1.5.0 release
2 parents 339521a + 8d130ad commit 65b16a4

File tree

9 files changed

+249
-177
lines changed

9 files changed

+249
-177
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pg_graphql"
3-
version = "1.4.4"
3+
version = "1.5.0"
44
edition = "2021"
55

66
[lib]

docs/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,8 @@
6464
## 1.4.4
6565
- bugfix: function returning a noncompliant view's type no longer breaks introspection
6666

67+
## 1.5.0
68+
- feature: `first`/`offset` based pagination
69+
- feature: improved descriptions for all internal error states
70+
6771
## master

src/builder.rs

Lines changed: 140 additions & 102 deletions
Large diffs are not rendered by default.

src/graphql.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ impl __Schema {
133133
column_names = &fkey.referenced_table_meta.column_names;
134134
}
135135

136-
let table: &Arc<Table> = self.context.get_table_by_oid(table_ref.oid).unwrap();
136+
let table: &Arc<Table> = self
137+
.context
138+
.get_table_by_oid(table_ref.oid)
139+
.expect("failed to get table by oid");
137140

138141
let is_inflection_on = self.inflect_names(table.schema_oid);
139142

@@ -1123,6 +1126,15 @@ pub struct FilterTypeType {
11231126
pub schema: Arc<__Schema>,
11241127
}
11251128

1129+
impl FilterTypeType {
1130+
fn entity_name(&self) -> String {
1131+
match &self.entity {
1132+
FilterableType::Scalar(s) => s.name().expect("scalar name should exist"),
1133+
FilterableType::Enum(e) => e.name().expect("enum type name should exist"),
1134+
}
1135+
}
1136+
}
1137+
11261138
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11271139
pub struct FilterEntityType {
11281140
pub table: Arc<Table>,
@@ -1340,7 +1352,11 @@ fn function_args(schema: &Arc<__Schema>, func: &Arc<Function>) -> Vec<__InputVal
13401352
if matches!(t.category, TypeCategory::Pseudo) {
13411353
None
13421354
} else {
1343-
Some((t, arg_name.unwrap(), arg_default))
1355+
Some((
1356+
t,
1357+
arg_name.expect("function arg name should exist"),
1358+
arg_default,
1359+
))
13441360
}
13451361
}
13461362
None => None,
@@ -1713,7 +1729,7 @@ impl ___Type for NodeInterfaceType {
17131729
}
17141730

17151731
fn possible_types(&self) -> Option<Vec<__Type>> {
1716-
let node_interface_name = self.name().unwrap();
1732+
let node_interface_name = self.name().expect("node interface type name should exist");
17171733

17181734
let mut possible_types = vec![];
17191735

@@ -1723,8 +1739,10 @@ impl ___Type for NodeInterfaceType {
17231739
.sorted_by(|a, b| a.name().cmp(&b.name()))
17241740
{
17251741
let type_interfaces: Vec<__Type> = type_.interfaces().unwrap_or(vec![]);
1726-
let interface_names: Vec<String> =
1727-
type_interfaces.iter().map(|x| x.name().unwrap()).collect();
1742+
let interface_names: Vec<String> = type_interfaces
1743+
.iter()
1744+
.map(|x| x.name().expect("type interface name should exist"))
1745+
.collect();
17281746
if interface_names.contains(&node_interface_name) {
17291747
possible_types.push(type_)
17301748
}
@@ -2076,7 +2094,7 @@ impl ___Type for NodeType {
20762094
if foreign_table.is_none() {
20772095
continue;
20782096
}
2079-
let foreign_table = foreign_table.unwrap();
2097+
let foreign_table = foreign_table.expect("foreign table should exist");
20802098
if !self
20812099
.schema
20822100
.graphql_table_select_types_are_valid(foreign_table)
@@ -2125,7 +2143,7 @@ impl ___Type for NodeType {
21252143
if foreign_table.is_none() {
21262144
continue;
21272145
}
2128-
let foreign_table = foreign_table.unwrap();
2146+
let foreign_table = foreign_table.expect("foreign table should exist");
21292147
if !self
21302148
.schema
21312149
.graphql_table_select_types_are_valid(foreign_table)
@@ -3354,10 +3372,7 @@ impl ___Type for FilterTypeType {
33543372
}
33553373

33563374
fn name(&self) -> Option<String> {
3357-
match &self.entity {
3358-
FilterableType::Scalar(s) => Some(format!("{}Filter", s.name().unwrap())),
3359-
FilterableType::Enum(e) => Some(format!("{}Filter", e.name().unwrap())),
3360-
}
3375+
Some(format!("{}Filter", self.entity_name()))
33613376
}
33623377

33633378
fn fields(&self, _include_deprecated: bool) -> Option<Vec<__Field>> {
@@ -3367,10 +3382,7 @@ impl ___Type for FilterTypeType {
33673382
fn description(&self) -> Option<String> {
33683383
Some(format!(
33693384
"Boolean expression comparing fields on type \"{}\"",
3370-
match &self.entity {
3371-
FilterableType::Scalar(s) => s.name().unwrap(),
3372-
FilterableType::Enum(e) => e.name().unwrap(),
3373-
}
3385+
self.entity_name()
33743386
))
33753387
}
33763388

@@ -3853,15 +3865,15 @@ pub struct __Schema {
38533865
#[cached(
38543866
type = "SizedCache<String, HashMap<String, __Type>>",
38553867
create = "{ SizedCache::with_size(200) }",
3856-
convert = r#"{ serde_json::ser::to_string(&schema.context.config).unwrap() }"#,
3868+
convert = r#"{ serde_json::ser::to_string(&schema.context.config).expect("schema config should be a string") }"#,
38573869
sync_writes = true
38583870
)]
38593871
pub fn type_map(schema: &__Schema) -> HashMap<String, __Type> {
38603872
let tmap: HashMap<String, __Type> = schema
38613873
.types()
38623874
.into_iter()
38633875
.filter(|x| x.name().is_some())
3864-
.map(|x| (x.name().unwrap(), x))
3876+
.map(|x| (x.name().expect("type should have a name"), x))
38653877
.collect();
38663878
tmap
38673879
}

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ fn resolve(
6262
}
6363
};
6464

65-
let value: serde_json::Value = serde_json::to_value(response).unwrap();
65+
let value: serde_json::Value =
66+
serde_json::to_value(response).expect("failed to convert response into json");
6667

6768
pgrx::JsonB(value)
6869
}

src/parser_util.rs

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -577,54 +577,56 @@ pub fn validate_arg_from_type(type_: &__Type, value: &gson::Value) -> Result<gso
577577
Scalar::Opaque => value.clone(),
578578
}
579579
}
580-
__Type::Enum(enum_) => match value {
581-
GsonValue::Absent => value.clone(),
582-
GsonValue::Null => value.clone(),
583-
GsonValue::String(user_input_string) => {
584-
let matches_enum_value = enum_
585-
.enum_values(true)
586-
.into_iter()
587-
.flatten()
588-
.find(|x| x.name().as_str() == user_input_string);
589-
match matches_enum_value {
590-
Some(_) => {
591-
match &enum_.enum_ {
592-
EnumSource::Enum(e) => e
593-
.directives
594-
.mappings
595-
.as_ref()
596-
// Use mappings if available and mapped
597-
.and_then(|mappings| mappings.get_by_right(user_input_string))
598-
.map(|val| GsonValue::String(val.clone()))
599-
.unwrap_or_else(|| value.clone()),
600-
EnumSource::FilterIs => value.clone(),
580+
__Type::Enum(enum_) => {
581+
let enum_name = enum_.name().expect("enum type should have a name");
582+
match value {
583+
GsonValue::Absent => value.clone(),
584+
GsonValue::Null => value.clone(),
585+
GsonValue::String(user_input_string) => {
586+
let matches_enum_value = enum_
587+
.enum_values(true)
588+
.into_iter()
589+
.flatten()
590+
.find(|x| x.name().as_str() == user_input_string);
591+
match matches_enum_value {
592+
Some(_) => {
593+
match &enum_.enum_ {
594+
EnumSource::Enum(e) => e
595+
.directives
596+
.mappings
597+
.as_ref()
598+
// Use mappings if available and mapped
599+
.and_then(|mappings| mappings.get_by_right(user_input_string))
600+
.map(|val| GsonValue::String(val.clone()))
601+
.unwrap_or_else(|| value.clone()),
602+
EnumSource::FilterIs => value.clone(),
603+
}
601604
}
602-
}
603-
None => {
604-
return Err(format!("Invalid input for {} type", enum_.name().unwrap()))
605+
None => return Err(format!("Invalid input for {} type", enum_name)),
605606
}
606607
}
608+
_ => return Err(format!("Invalid input for {} type", enum_name)),
607609
}
608-
_ => return Err(format!("Invalid input for {} type", enum_.name().unwrap())),
609-
},
610-
__Type::OrderBy(enum_) => match value {
611-
GsonValue::Absent => value.clone(),
612-
GsonValue::Null => value.clone(),
613-
GsonValue::String(user_input_string) => {
614-
let matches_enum_value = enum_
615-
.enum_values(true)
616-
.into_iter()
617-
.flatten()
618-
.find(|x| x.name().as_str() == user_input_string);
619-
match matches_enum_value {
620-
Some(_) => value.clone(),
621-
None => {
622-
return Err(format!("Invalid input for {} type", enum_.name().unwrap()))
610+
}
611+
__Type::OrderBy(enum_) => {
612+
let enum_name = enum_.name().expect("order by type should have a name");
613+
match value {
614+
GsonValue::Absent => value.clone(),
615+
GsonValue::Null => value.clone(),
616+
GsonValue::String(user_input_string) => {
617+
let matches_enum_value = enum_
618+
.enum_values(true)
619+
.into_iter()
620+
.flatten()
621+
.find(|x| x.name().as_str() == user_input_string);
622+
match matches_enum_value {
623+
Some(_) => value.clone(),
624+
None => return Err(format!("Invalid input for {} type", enum_name)),
623625
}
624626
}
627+
_ => return Err(format!("Invalid input for {} type", enum_name)),
625628
}
626-
_ => return Err(format!("Invalid input for {} type", enum_.name().unwrap())),
627-
},
629+
}
628630
__Type::List(list_type) => {
629631
let inner_type: __Type = *list_type.type_.clone();
630632
match value {

src/resolve.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,11 @@ where
157157
let query_type = schema_type.query_type();
158158
let map = field_map(&query_type);
159159

160+
let query_type_name = query_type.name().expect("query type should have a name");
160161
let selections = match normalize_selection_set(
161162
&selection_set,
162163
&fragment_definitions,
163-
&query_type.name().unwrap(),
164+
&query_type_name,
164165
variables,
165166
&query_type,
166167
) {
@@ -196,8 +197,7 @@ where
196197
res_errors.push(ErrorMessage {
197198
message: format!(
198199
"Unknown field {:?} on type {}",
199-
selection.name,
200-
query_type.name().unwrap()
200+
selection.name, query_type_name
201201
),
202202
});
203203
}
@@ -376,10 +376,13 @@ where
376376

377377
let map = field_map(&mutation_type);
378378

379+
let mutation_type_name = mutation_type
380+
.name()
381+
.expect("mutation type should have a name");
379382
let selections = match normalize_selection_set(
380383
&selection_set,
381384
&fragment_definitions,
382-
&mutation_type.name().unwrap(),
385+
&mutation_type_name,
383386
variables,
384387
&mutation_type,
385388
) {
@@ -409,8 +412,7 @@ where
409412
conn = match maybe_field_def {
410413
None => Err(format!(
411414
"Unknown field {:?} on type {}",
412-
selection.name,
413-
mutation_type.name().unwrap()
415+
selection.name, mutation_type_name
414416
))?,
415417
Some(field_def) => match field_def.type_.unmodified_type() {
416418
__Type::InsertResponse(_) => {

src/sql_types.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,8 +756,12 @@ pub(crate) fn get_one_readonly<A: FromDatum + IntoDatum>(
756756

757757
pub fn load_sql_config() -> Config {
758758
let query = include_str!("../sql/load_sql_config.sql");
759-
let sql_result: serde_json::Value = get_one_readonly::<JsonB>(query).unwrap().unwrap().0;
760-
let config: Config = serde_json::from_value(sql_result).unwrap();
759+
let sql_result: serde_json::Value = get_one_readonly::<JsonB>(query)
760+
.expect("failed to read sql config")
761+
.expect("sql config is missing")
762+
.0;
763+
let config: Config =
764+
serde_json::from_value(sql_result).expect("failed to convert sql config into json");
761765
config
762766
}
763767

@@ -776,7 +780,10 @@ pub fn calculate_hash<T: Hash>(t: &T) -> u64 {
776780
pub fn load_sql_context(_config: &Config) -> Result<Arc<Context>, String> {
777781
// cache value for next query
778782
let query = include_str!("../sql/load_sql_context.sql");
779-
let sql_result: serde_json::Value = get_one_readonly::<JsonB>(query).unwrap().unwrap().0;
783+
let sql_result: serde_json::Value = get_one_readonly::<JsonB>(query)
784+
.expect("failed to read sql context")
785+
.expect("sql context is missing")
786+
.0;
780787
let context: Result<Context, serde_json::Error> = serde_json::from_value(sql_result);
781788

782789
/// This pass cross-reference types with its details

src/transpile.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@ use std::collections::HashSet;
1212
use std::sync::Arc;
1313

1414
pub fn quote_ident(ident: &str) -> String {
15-
unsafe { direct_function_call::<String>(pg_sys::quote_ident, &[ident.into_datum()]).unwrap() }
15+
unsafe {
16+
direct_function_call::<String>(pg_sys::quote_ident, &[ident.into_datum()])
17+
.expect("failed to quote ident")
18+
}
1619
}
1720

1821
pub fn quote_literal(ident: &str) -> String {
19-
unsafe { direct_function_call::<String>(pg_sys::quote_literal, &[ident.into_datum()]).unwrap() }
22+
unsafe {
23+
direct_function_call::<String>(pg_sys::quote_literal, &[ident.into_datum()])
24+
.expect("failed to quote literal")
25+
}
2026
}
2127

2228
pub fn rand_block_name() -> String {
@@ -1305,10 +1311,10 @@ impl QueryEntrypoint for NodeBuilder {
13051311
let quoted_table = quote_ident(&self.table.name);
13061312
let object_clause = self.to_sql(&quoted_block_name, param_context)?;
13071313

1308-
if self.node_id.is_none() {
1309-
return Err("Expected nodeId argument missing".to_string());
1310-
}
1311-
let node_id = self.node_id.as_ref().unwrap();
1314+
let node_id = self
1315+
.node_id
1316+
.as_ref()
1317+
.ok_or("Expected nodeId argument missing")?;
13121318

13131319
let node_id_clause = node_id.to_sql(&quoted_block_name, &self.table, param_context)?;
13141320

0 commit comments

Comments
 (0)