Skip to content

Commit

Permalink
move json from experimental to supported
Browse files Browse the repository at this point in the history
  • Loading branch information
kurtbuilds committed Aug 31, 2024
1 parent d57e2fb commit 8fb36ed
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 18 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,9 @@ pub struct Person {

## Json/Jsonb Columns

You can use `ormlite::types::Json` for JSON or JSONB fields. For unstructured data, use `serde_json::Value` as the inner
type. Use a struct with `Deserialize + Serialize` as the generic for structured data.
You can either use `ormlite::types::Json` for JSON or JSONB fields, or you can use the `json` attribute.
For unstructured data, use `serde_json::Value` as the inner type. Use a struct with `Deserialize + Serialize` as the
generic for structured data.

```rust
use ormlite::model::*;
Expand All @@ -472,6 +473,8 @@ pub struct Job {
pub id: i32,
pub structured_data: Json<JobData>,
pub unstructured_data: Json<Value>,
#[ormlite(json)]
pub other_data: Value,
}
```

Expand Down
4 changes: 1 addition & 3 deletions attr/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ pub struct ColumnAttributes {
/// Skip serializing this field to/from the database. Note the field must implement `Default`.
pub skip: Flag,

/// Experimental: Encode this field as JSON in the database.
/// Only applies to `derive(IntoArguments)`. For Model structs, wrap the object in `Json<..>`.
pub experimental_encode_as_json: Flag,
pub json: Flag,
}

#[cfg(test)]
Expand Down
10 changes: 5 additions & 5 deletions attr/src/metadata/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ pub struct ColumnMetadata {
pub one_to_many_foreign_key: Option<ForeignKey>,

pub skip: bool,
pub experimental_encode_as_json: bool,
pub rust_default: Option<String>,
pub join: Option<Join>,
pub json: bool,
}

impl ColumnMetadata {
Expand All @@ -55,9 +55,9 @@ impl Default for ColumnMetadata {
many_to_many_table: None,
one_to_many_foreign_key: None,
skip: false,
experimental_encode_as_json: false,
rust_default: None,
join: None,
json: false,
}
}
}
Expand Down Expand Up @@ -94,7 +94,7 @@ impl ColumnMetadata {
}

pub fn is_json(&self) -> bool {
self.column_type.is_json()
self.column_type.is_json() || self.json
}

/// We expect this to only return a `Model` of some kind.
Expand Down Expand Up @@ -158,8 +158,8 @@ impl TryFrom<&Field> for ColumnMetadata {
if args.skip.value() {
result.skip = true;
}
if args.experimental_encode_as_json.value() {
result.experimental_encode_as_json = true;
if args.json.value() {
result.json = true;
}
if let Some(default_value) = args.default_value {
result.rust_default = Some(default_value.value());
Expand Down
3 changes: 1 addition & 2 deletions attr/src/metadata/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ impl TableMetadata {
let mut columns = ast
.fields()
.map(ColumnMetadata::try_from)
.collect::<Result<Vec<_>, _>>()
.unwrap();
.collect::<Result<Vec<_>, _>>()?;
let mut pkey = columns
.iter()
.find(|&c| c.marked_primary_key)
Expand Down
14 changes: 12 additions & 2 deletions macro/src/codegen/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ pub fn generate_conditional_bind(c: &ColumnMetadata) -> TokenStream {
q = q.bind(value._id());
}
}
} else if c.json {
quote! {
if let Some(value) = self.#name {
q = q.bind(::ormlite::types::Json(value));
}
}
} else {
quote! {
if let Some(value) = self.#name {
Expand Down Expand Up @@ -71,7 +77,7 @@ pub(crate) fn table_primitive_types<'a>(attr: &'a TableMetadata, cache: &'a Meta
attr.columns
.iter()
.filter(|c| !c.skip)
.filter(|c| !c.experimental_encode_as_json)
.filter(|c| !c.json)
.map(|c| recursive_primitive_types_ty(&c.column_type, cache))
.flatten()
.unique()
Expand All @@ -82,7 +88,7 @@ pub fn from_row_bounds<'a>(
db: &dyn OrmliteCodegen,
attr: &'a TableMetadata,
cache: &'a MetadataCache,
) -> impl Iterator<Item = proc_macro2::TokenStream> + 'a {
) -> impl Iterator<Item=proc_macro2::TokenStream> + 'a {
let database = db.database_ts();
table_primitive_types(attr, cache).into_iter().map(move |ty| {
quote! {
Expand All @@ -109,6 +115,10 @@ pub fn insertion_binding(c: &ColumnMetadata) -> TokenStream {
quote! {
q = q.bind(#name._id());
}
} else if c.json {
quote! {
q = q.bind(::ormlite::types::Json(model.#name));
}
} else {
quote! {
q = q.bind(model.#name);
Expand Down
3 changes: 1 addition & 2 deletions macro/src/codegen/from_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ pub fn impl_from_row_using_aliases(
impl #model {
pub fn from_row_using_aliases<'a>(row: &'a #row, aliases: &'a [&str]) -> ::std::result::Result<Self, ::ormlite::SqlxError>
where
// &'a str: ::ormlite::ColumnIndex<#row>,
#(
#bounds
)*
Expand Down Expand Up @@ -141,7 +140,7 @@ pub fn from_row_for_column(get_value: TokenStream, col: &ColumnMetadata) -> Toke
let #id_id: <#ty as ::ormlite::model::JoinMeta>::IdType = ::ormlite::Row::try_get(row, #get_value)?;
let #id = ::ormlite::model::Join::new_with_id(#id_id);
}
} else if col.experimental_encode_as_json {
} else if col.json {
quote! {
let #id: ::ormlite::types::Json<#ty> = ::ormlite::Row::try_get(row, #get_value)?;
let #id = #id.0;
Expand Down
2 changes: 1 addition & 1 deletion macro/src/codegen/into_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn impl_IntoArguments(db: &dyn OrmliteCodegen, attr: &TableMetadata) -> Toke
let model = &attr.struct_name;
let params = attr.database_columns().map(|c| {
let field = &c.identifier;
let value = if c.is_json() || c.experimental_encode_as_json {
let value = if c.is_json() {
quote! {
::ormlite::types::Json(self.#field)
}
Expand Down
5 changes: 4 additions & 1 deletion ormlite/tests/postgres/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ struct Job {
typ: JobType,
name: String,
data: Json<JobData>,
#[ormlite(json)]
data2: JobData,
#[allow(dead_code)]
#[ormlite(skip)]
skipped: Option<Uuid>,
Expand All @@ -35,7 +37,7 @@ struct ApiJob {
id: i32,
typ: JobType,
name: String,
#[ormlite(experimental_encode_as_json)]
#[ormlite(json)]
data: JobData,
}

Expand All @@ -46,5 +48,6 @@ async fn main() {
"typ".to_string(),
"name".to_string(),
"data".to_string(),
"data2".to_string(),
]);
}

0 comments on commit 8fb36ed

Please sign in to comment.