Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jefbarn committed Jul 27, 2021
1 parent e5b7f6b commit 5c64a80
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build]
# Postgres symbols won't ve available until runtime
rustflags = ["-C", "link-args=-Wl,-undefined,dynamic_lookup"]
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
.idea/
/target
*.iml
**/*.rs.bk
Cargo.lock
sql/*.generated.sql
34 changes: 34 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "pgx_json_schema"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[features]
default = ["pg11"]
pg10 = ["pgx/pg10"]
pg11 = ["pgx/pg11"]
pg12 = ["pgx/pg12"]
pg13 = ["pgx/pg13"]
pg_test = []

[dependencies]
pgx = "0.1.20"
pgx-macros = "0.1.20"
serde_json = "1.0.59"
jsonschema = "0.12.0"
#jtd = "0.3"

[dev-dependencies]
pgx-tests = "0.1.20"

[profile.dev]
panic = "unwind"

[profile.release]
panic = "unwind"
opt-level = 3
lto = "fat"
codegen-units = 1
5 changes: 5 additions & 0 deletions pgx_json_schema.control
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
comment = 'pgx_json_schema: Created by pgx'
default_version = '1.0'
module_pathname = '$libdir/pgx_json_schema'
relocatable = false
superuser = false
1 change: 1 addition & 0 deletions sql/load-order.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lib.generated.sql
80 changes: 80 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use jsonschema::JSONSchema;
use pgx::*;

pg_module_magic!();

#[pg_extern]
fn json_schema_is_valid(schema: JsonB, instance: JsonB) -> bool {
jsonschema::is_valid(&schema.0, &instance.0)
}

#[pg_extern]
fn json_schema_get_errors(
schema: JsonB,
instance: JsonB,
) -> impl std::iter::Iterator<
Item = (
name!(error_value, JsonB),
name!(description, String),
name!(details, String),
name!(instance_path, String),
name!(schema_path, String),
),
> {
let compiled = JSONSchema::compile(&schema.0)
.unwrap_or_else(|err| panic!("Error compiling schema: {:#?}", err));

let result = compiled
.validate(&instance.0)
.err()
.into_iter()
.flat_map(|iter| iter);

let new: Vec<(JsonB, String, String, String, String)> = result
.map(|e| {
let description = e.to_string();
(
JsonB(e.instance.into_owned()),
description,
format!("{:?}", (e.kind)).clone(),
e.instance_path.to_string(),
e.schema_path.to_string(),
)
})
.collect();

new.into_iter()
}

#[cfg(any(test, feature = "pg_test"))]
mod tests {
use pgx::*;

#[pg_test]
fn test_json_schema_is_valid() {
let valid = Spi::get_one::<bool>(
"select json_schema_is_valid('{\"maxLength\": 5}', '\"foobar\"'::jsonb)",
);
assert_eq!(valid, Some(false))
}

#[pg_test]
fn test_json_schema_get_errors() {
let (_value, description) = Spi::get_two::<JsonB, String>(
"select * from json_schema_get_errors('{\"maxLength\": 5}', '\"foobar\"'::jsonb)",
);
assert_eq!(description, Some("\"foobar\" is longer than 5 characters".to_string()))
}
}

#[cfg(test)]
pub mod pg_test {
pub fn setup(_options: Vec<&str>) {
// perform one-off initialization when the pg_test framework starts
}

pub fn postgresql_conf_options() -> Vec<&'static str> {
// return any postgresql.conf settings that are required for your tests
vec![]
}
}

0 comments on commit 5c64a80

Please sign in to comment.