1use crate::deserialize::{self, FromSql};
4use crate::serialize::{self, IsNull, Output, ToSql};
5use crate::sql_types;
6use crate::sqlite::{Sqlite, SqliteValue};
7use alloc::boxed::Box;
8use alloc::string::{String, ToString};
9use alloc::vec::Vec;
10
11#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
12impl FromSql<sql_types::Json, Sqlite> for serde_json::Value {
13 fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
14 serde_json::from_str(value.read_text()).map_err(|_| "Invalid Json".into())
15 }
16}
17
18#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
19impl ToSql<sql_types::Json, Sqlite> for serde_json::Value {
20 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
21 out.set_value(serde_json::to_string(self)?);
22 Ok(IsNull::No)
23 }
24}
25
26#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
27impl FromSql<sql_types::Jsonb, Sqlite> for serde_json::Value {
28 fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
29 use self::jsonb::*;
30
31 let bytes = value.read_blob();
32
33 if bytes.is_empty() {
34 return Err("Empty blob cannot be decoded as JSONB".into());
35 }
36
37 let (jsonb, _size) = read_jsonb_value(bytes)?;
39
40 Ok(jsonb)
41 }
42}
43
44#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
45impl ToSql<sql_types::Jsonb, Sqlite> for serde_json::Value {
46 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
47 use self::jsonb::*;
48
49 let mut buffer = Vec::new();
51
52 write_jsonb_value(self, &mut buffer)?;
54
55 out.set_value(buffer);
57
58 Ok(IsNull::No)
59 }
60}
61
62#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
63mod jsonb {
64 extern crate serde_json;
65
66 use super::*;
67
68 pub(super) const JSONB_NULL: u8 = 0x00;
69 pub(super) const JSONB_TRUE: u8 = 0x01;
70 pub(super) const JSONB_FALSE: u8 = 0x02;
71 pub(super) const JSONB_INT: u8 = 0x03;
72 pub(super) const JSONB_INT5: u8 = 0x04;
73 pub(super) const JSONB_FLOAT: u8 = 0x05;
74 pub(super) const JSONB_FLOAT5: u8 = 0x06;
75 pub(super) const JSONB_TEXT: u8 = 0x07;
76 pub(super) const JSONB_TEXTJ: u8 = 0x08;
77 pub(super) const JSONB_TEXT5: u8 = 0x09;
78 pub(super) const JSONB_TEXTRAW: u8 = 0x0A;
79 pub(super) const JSONB_ARRAY: u8 = 0x0B;
80 pub(super) const JSONB_OBJECT: u8 = 0x0C;
81
82 pub(super) fn read_jsonb_value(
84 bytes: &[u8],
85 ) -> deserialize::Result<(serde_json::Value, usize)> {
86 if bytes.is_empty() {
87 return Err("Empty JSONB data".into());
88 }
89
90 let first_byte = bytes[0];
92 let element_type = first_byte & 0x0F;
93 let size_hint = (first_byte & 0xF0) >> 4;
94
95 let (payload_size, header_size) = match size_hint {
96 0x00..=0x0B => (size_hint as usize, 1), 0x0C => {
98 if bytes.len() < 2 {
99 return Err("Invalid JSONB data: insufficient bytes for payload size".into());
100 }
101 (bytes[1] as usize, 2) }
103 0x0D => {
104 if bytes.len() < 3 {
105 return Err("Invalid JSONB data: insufficient bytes for payload size".into());
106 }
107 (u16::from_be_bytes([bytes[1], bytes[2]]) as usize, 3) }
109 0x0E => {
110 if bytes.len() < 5 {
111 return Err("Invalid JSONB data: insufficient bytes for payload size".into());
112 }
113 (
114 u32::from_be_bytes([bytes[1], bytes[2], bytes[3], bytes[4]]) as usize,
115 5,
116 ) }
118 0x0F => {
119 if bytes.len() < 9 {
120 return Err("Invalid JSONB data: insufficient bytes for payload size".into());
121 }
122 (
123 usize::try_from(u64::from_be_bytes([
124 bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
125 bytes[8],
126 ]))
127 .map_err(Box::new)?,
128 9,
129 ) }
131 _ => return Err("Invalid payload size hint".into()),
132 };
133
134 let total_size = header_size + payload_size;
135 if bytes.len() < total_size {
136 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Invalid JSONB data: insufficient bytes for value of type {0}, expected {1} bytes, got {2}",
element_type, total_size, bytes.len()))
})alloc::format!(
137 "Invalid JSONB data: insufficient bytes for value of type {}, expected {} bytes, got {}",
138 element_type,
139 total_size,
140 bytes.len()
141 )
142 .into());
143 }
144
145 let payload_bytes = &bytes[header_size..total_size];
146
147 let value = match element_type {
148 JSONB_NULL => Ok(serde_json::Value::Null),
149 JSONB_TRUE => Ok(serde_json::Value::Bool(true)),
150 JSONB_FALSE => Ok(serde_json::Value::Bool(false)),
151 JSONB_INT => read_jsonb_int(payload_bytes, payload_size),
152 JSONB_INT5 => Err("INT5 is not supported".into()),
153 JSONB_FLOAT => read_jsonb_float(payload_bytes, payload_size),
154 JSONB_FLOAT5 => Err("FLOAT5 is not supported".into()),
155 JSONB_TEXT => read_jsonb_text(payload_bytes, payload_size),
156 JSONB_TEXTJ => read_jsonb_textj(payload_bytes, payload_size),
157 JSONB_TEXTRAW => read_jsonb_text(payload_bytes, payload_size),
158 JSONB_TEXT5 => Err("TEXT5 is not supported".into()),
159 JSONB_ARRAY => read_jsonb_array(payload_bytes, payload_size),
160 JSONB_OBJECT => read_jsonb_object(payload_bytes, payload_size),
161 _ => Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Unsupported or reserved JSONB type: {0}",
element_type))
})alloc::format!("Unsupported or reserved JSONB type: {element_type}").into()),
162 }?;
163
164 Ok((value, total_size))
165 }
166
167 pub(super) fn read_jsonb_int(
169 bytes: &[u8],
170 payload_size: usize,
171 ) -> deserialize::Result<serde_json::Value> {
172 if bytes.len() < payload_size {
174 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected payload of size {0}, but got {1}",
payload_size, bytes.len()))
})alloc::format!(
175 "Expected payload of size {}, but got {}",
176 payload_size,
177 bytes.len()
178 )
179 .into());
180 }
181
182 let int_str = core::str::from_utf8(bytes).map_err(|_| "Invalid ASCII in JSONB integer")?;
184 let int_value = serde_json::from_str(int_str)
185 .map_err(|_| "Failed to parse JSONB")
186 .and_then(|v: serde_json::Value| {
187 v.is_i64()
188 .then_some(v)
189 .ok_or("Failed to parse JSONB integer")
190 })?;
191
192 Ok(int_value)
193 }
194
195 pub(super) fn read_jsonb_float(
197 bytes: &[u8],
198 payload_size: usize,
199 ) -> deserialize::Result<serde_json::Value> {
200 if bytes.len() < payload_size {
201 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected payload of size {0}, but got {1}",
payload_size, bytes.len()))
})alloc::format!(
202 "Expected payload of size {}, but got {}",
203 payload_size,
204 bytes.len()
205 )
206 .into());
207 }
208
209 let float_str = core::str::from_utf8(bytes).map_err(|_| "Invalid UTF-8 in JSONB float")?;
210 let float_value = serde_json::from_str(float_str)
211 .map_err(|_| "Failed to parse JSONB")
212 .and_then(|v: serde_json::Value| {
213 v.is_f64()
214 .then_some(v)
215 .ok_or("Failed to parse JSONB number")
216 })?;
217
218 Ok(float_value)
219 }
220
221 pub(super) fn read_jsonb_text(
223 bytes: &[u8],
224 payload_size: usize,
225 ) -> deserialize::Result<serde_json::Value> {
226 if bytes.len() < payload_size {
227 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected payload of size {0}, but got {1}",
payload_size, bytes.len()))
})alloc::format!(
228 "Expected payload of size {}, but got {}",
229 payload_size,
230 bytes.len()
231 )
232 .into());
233 }
234
235 let text = core::str::from_utf8(bytes).map_err(|_| "Invalid UTF-8 in JSONB string")?;
236 Ok(serde_json::Value::String(text.to_string()))
237 }
238
239 pub(super) fn read_jsonb_textj(
240 bytes: &[u8],
241 payload_size: usize,
242 ) -> deserialize::Result<serde_json::Value> {
243 if bytes.len() < payload_size {
244 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Expected payload of size {0}, but got {1}",
payload_size, bytes.len()))
})alloc::format!(
245 "Expected payload of size {}, but got {}",
246 payload_size,
247 bytes.len()
248 )
249 .into());
250 }
251
252 let text = core::str::from_utf8(bytes).map_err(|_| "Invalid UTF-8 in JSONB string")?;
253
254 let unescaped_text = serde_json::from_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("\"{0}\"", text))
})alloc::format!("\"{text}\""))
256 .map_err(|_| "Failed to parse JSON-escaped text in TEXTJ")?;
257
258 Ok(unescaped_text)
259 }
260
261 pub(super) fn read_jsonb_array(
263 bytes: &[u8],
264 payload_size: usize,
265 ) -> deserialize::Result<serde_json::Value> {
266 let mut elements = Vec::new();
267 let mut total_read = 0;
268
269 while total_read < payload_size {
270 let (element, consumed) = read_jsonb_value(&bytes[total_read..payload_size])?;
271
272 elements.push(element);
273 total_read += consumed;
274 }
275
276 if total_read != payload_size {
277 return Err("Array payload size mismatch".into());
278 }
279
280 Ok(serde_json::Value::Array(elements))
281 }
282
283 pub(super) fn read_jsonb_object(
284 bytes: &[u8],
285 payload_size: usize,
286 ) -> deserialize::Result<serde_json::Value> {
287 let mut object = serde_json::Map::new();
288 let mut total_read = 0;
289
290 while total_read < payload_size {
291 let (key_value, key_consumed) = read_jsonb_value(&bytes[total_read..])?;
293 let key_str = key_value
294 .as_str()
295 .ok_or("Invalid object key in JSONB, must be a string")?
296 .to_string();
297 total_read += key_consumed;
298
299 let (value, value_consumed) = read_jsonb_value(&bytes[total_read..])?;
301 object.insert(key_str, value);
302 total_read += value_consumed;
303 }
304
305 if total_read != payload_size {
307 return Err("Object payload size mismatch".into());
308 }
309
310 Ok(serde_json::Value::Object(object))
311 }
312
313 pub(super) fn create_jsonb_header(
315 element_type: u8,
316 payload_size: usize,
317 ) -> Result<Vec<u8>, String> {
318 if payload_size > 2_147_483_647 {
320 return Err("Payload size exceeds the maximum allowed size of 2GB".into());
321 }
322
323 let header = if payload_size <= 0x0B {
324 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[((u8::try_from(payload_size).map_err(|e| e.to_string())?) << 4) |
element_type]))alloc::vec![
326 ((u8::try_from(payload_size).map_err(|e| e.to_string())?) << 4) | element_type
327 ]
328 } else if payload_size <= 0xFF {
329 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[(0x0C << 4) | element_type,
u8::try_from(payload_size).map_err(|e| e.to_string())?]))alloc::vec![
331 (0x0C << 4) | element_type,
332 u8::try_from(payload_size).map_err(|e| e.to_string())?,
333 ]
334 } else if payload_size <= 0xFFFF {
335 let mut header = Vec::with_capacity(3);
336
337 header.push((0x0D << 4) | element_type);
339 header.extend_from_slice(
340 &(u16::try_from(payload_size).map_err(|e| e.to_string())?).to_be_bytes(),
341 );
342
343 header
344 } else {
345 let mut header = Vec::with_capacity(5);
346
347 header.push((0x0E << 4) | element_type);
349 header.extend_from_slice(
350 &(u32::try_from(payload_size).map_err(|e| e.to_string())?).to_be_bytes(),
351 );
352
353 header
354 };
355
356 Ok(header)
357 }
358
359 pub(super) fn write_jsonb_header(
360 buffer: &mut Vec<u8>,
361 element_type: u8,
362 payload_size: usize,
363 ) -> serialize::Result {
364 let header = create_jsonb_header(element_type, payload_size)?;
366 buffer.extend(header);
367 Ok(IsNull::No)
368 }
369
370 pub(super) fn write_jsonb_value(
372 value: &serde_json::Value,
373 buffer: &mut Vec<u8>,
374 ) -> serialize::Result {
375 if value.is_null() {
376 write_jsonb_null(buffer)
377 } else if value.is_boolean() {
378 write_jsonb_bool(value.as_bool().ok_or("Failed to read JSONB value")?, buffer)
379 } else if value.is_number() {
380 write_jsonb_number(value, buffer)
381 } else if value.is_string() {
382 write_jsonb_string(value.as_str().ok_or("Failed to read JSONB value")?, buffer)
383 } else if value.is_array() {
384 write_jsonb_array(
385 value.as_array().ok_or("Failed to read JSONB value")?,
386 buffer,
387 )
388 } else if value.is_object() {
389 write_jsonb_object(
390 value.as_object().ok_or("Failed to read JSONB value")?,
391 buffer,
392 )
393 } else {
394 Err("Unsupported JSONB value type".into())
395 }
396 }
397
398 pub(super) fn write_jsonb_null(buffer: &mut Vec<u8>) -> serialize::Result {
400 write_jsonb_header(buffer, JSONB_NULL, 0x0)?;
401 Ok(IsNull::No)
402 }
403
404 pub(super) fn write_jsonb_bool(b: bool, buffer: &mut Vec<u8>) -> serialize::Result {
406 write_jsonb_header(buffer, if b { JSONB_TRUE } else { JSONB_FALSE }, 0x0)?;
408 Ok(IsNull::No)
409 }
410
411 pub(super) fn write_jsonb_number(
413 n: &serde_json::Value,
414 buffer: &mut Vec<u8>,
415 ) -> serialize::Result {
416 if let Some(i) = n.as_i64() {
417 write_jsonb_int(i, buffer)
419 } else if let Some(f) = n.as_f64() {
420 write_jsonb_float(f, buffer)
422 } else {
423 Err("Invalid JSONB number type".into())
424 }
425 }
426
427 pub(super) fn write_jsonb_int(i: i64, buffer: &mut Vec<u8>) -> serialize::Result {
429 let int_str = i.to_string();
430
431 write_jsonb_header(buffer, JSONB_INT, int_str.len())?;
432
433 buffer.extend_from_slice(int_str.as_bytes());
435
436 Ok(IsNull::No)
437 }
438
439 pub(super) fn write_jsonb_float(f: f64, buffer: &mut Vec<u8>) -> serialize::Result {
441 let float_str = f.to_string();
442
443 write_jsonb_header(buffer, JSONB_FLOAT, float_str.len())?;
444
445 buffer.extend_from_slice(float_str.as_bytes());
447
448 Ok(IsNull::No)
449 }
450
451 pub(super) fn write_jsonb_string(s: &str, buffer: &mut Vec<u8>) -> serialize::Result {
452 if s.chars().any(|c| c.is_control()) {
453 write_jsonb_textj(s, buffer)
455 } else {
456 write_jsonb_header(buffer, JSONB_TEXT, s.len())?;
457 buffer.extend_from_slice(s.as_bytes());
459 Ok(IsNull::No)
460 }
461 }
462
463 pub(super) fn write_jsonb_textj(s: &str, buffer: &mut Vec<u8>) -> serialize::Result {
464 let escaped_string = serde_json::to_string(&String::from(s))
466 .map_err(|_| "Failed to serialize string for TEXTJ")?;
467
468 let escaped_string = &escaped_string[1..escaped_string.len() - 1];
470
471 write_jsonb_header(buffer, JSONB_TEXTJ, escaped_string.len())?;
473
474 buffer.extend_from_slice(escaped_string.as_bytes());
476
477 Ok(IsNull::No)
478 }
479
480 pub(super) fn write_jsonb_array(
482 arr: &[serde_json::Value],
483 buffer: &mut Vec<u8>,
484 ) -> serialize::Result {
485 let mut tmp_buffer = Vec::new();
486
487 for element in arr {
489 write_jsonb_value(element, &mut tmp_buffer)?;
490 }
491
492 write_jsonb_header(buffer, JSONB_ARRAY, tmp_buffer.len())?;
493
494 buffer.extend_from_slice(&tmp_buffer);
495
496 Ok(IsNull::No)
497 }
498
499 pub(super) fn write_jsonb_object(
501 obj: &serde_json::Map<String, serde_json::Value>,
502 buffer: &mut Vec<u8>,
503 ) -> serialize::Result {
504 let mut tmp_buffer = Vec::new();
505
506 for (key, value) in obj {
508 write_jsonb_string(key, &mut tmp_buffer)?;
510
511 write_jsonb_value(value, &mut tmp_buffer)?;
513 }
514
515 write_jsonb_header(buffer, JSONB_OBJECT, tmp_buffer.len())?;
516
517 buffer.extend_from_slice(&tmp_buffer);
518
519 Ok(IsNull::No)
520 }
521}
522
523#[cfg(test)]
524#[cfg(all(feature = "__sqlite-shared", feature = "serde_json"))]
525mod tests {
526 use super::jsonb::*;
527 use super::*;
528 use crate::ExpressionMethods;
529 use crate::query_dsl::RunQueryDsl;
530 use crate::test_helpers::connection;
531 use crate::{IntoSql, dsl::sql};
532 use serde_json::{Value, json};
533 use sql_types::{Json, Jsonb};
534
535 #[diesel_test_helper::test]
536 fn json_to_sql() {
537 let conn = &mut connection();
538 let res = diesel::select(json!(true).into_sql::<Json>().eq(&sql("json('true')")))
539 .get_result::<bool>(conn)
540 .unwrap();
541 assert!(res);
542 }
543
544 #[diesel_test_helper::test]
545 fn test_read_jsonb_null() {
546 let data = vec![JSONB_NULL];
547 let result = read_jsonb_value(&data).unwrap().0;
548 assert_eq!(result, Value::Null);
549 }
550
551 #[diesel_test_helper::test]
552 fn test_read_jsonb_true() {
553 let data = vec![JSONB_TRUE];
554 let result = read_jsonb_value(&data).unwrap().0;
555 assert_eq!(result, Value::Bool(true));
556 }
557
558 #[diesel_test_helper::test]
559 fn test_read_jsonb_false() {
560 let data = vec![JSONB_FALSE];
561 let result = read_jsonb_value(&data).unwrap().0;
562 assert_eq!(result, Value::Bool(false));
563 }
564
565 #[diesel_test_helper::test]
566 fn test_read_jsonb_int() {
567 let mut data = Vec::new();
569 data.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap());
570 data.push(b'1'); let result = read_jsonb_value(&data).unwrap().0;
573 assert_eq!(result, json!(1));
574 }
575
576 #[diesel_test_helper::test]
577 fn test_read_jsonb_float() {
578 let mut data = Vec::new();
580 data.extend(create_jsonb_header(JSONB_FLOAT, 0x03).unwrap());
581 data.extend_from_slice(b"1.5"); let result = read_jsonb_value(&data).unwrap().0;
584 assert_eq!(result, json!(1.5));
585 }
586
587 #[diesel_test_helper::test]
588 fn test_read_jsonb_text() {
589 let mut data = Vec::new();
591 data.extend(create_jsonb_header(JSONB_TEXT, 0x03).unwrap());
592 data.extend_from_slice(b"foo"); let result = read_jsonb_value(&data).unwrap().0;
595 assert_eq!(result, json!("foo"));
596 }
597
598 #[diesel_test_helper::test]
599 fn test_read_jsonb_textraw() {
600 let mut data = Vec::new();
602 data.extend(create_jsonb_header(JSONB_TEXTRAW, 0x03).unwrap());
603 data.extend_from_slice(b"foo");
604
605 let result = read_jsonb_value(&data).unwrap().0;
606 assert_eq!(result, json!("foo"));
607 }
608
609 #[diesel_test_helper::test]
610 fn test_read_jsonb_object_with_textraw_key() {
611 let mut data = Vec::new();
613 data.extend(create_jsonb_header(JSONB_OBJECT, 0x06).unwrap());
614 data.extend(create_jsonb_header(JSONB_TEXTRAW, 0x01).unwrap());
615 data.extend_from_slice(b"a");
616 data.extend(create_jsonb_header(JSONB_TEXTRAW, 0x03).unwrap());
617 data.extend_from_slice(b"bar");
618
619 let result = read_jsonb_value(&data).unwrap().0;
620 assert_eq!(result, json!({"a": "bar"}));
621 }
622
623 #[diesel_test_helper::test]
624 fn test_read_jsonb_array() {
625 let mut data = Vec::new();
627 data.extend(create_jsonb_header(JSONB_ARRAY, 0x03).unwrap()); data.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap());
631 data.push(b'1');
632
633 data.extend(create_jsonb_header(JSONB_TRUE, 0x00).unwrap());
635
636 let result = read_jsonb_value(&data).unwrap().0;
637 assert_eq!(result, json!([1, true]));
638 }
639
640 #[diesel_test_helper::test]
641 fn test_read_jsonb_object() {
642 let mut data = Vec::new();
644 data.extend(create_jsonb_header(JSONB_OBJECT, 0x07).unwrap()); data.extend(create_jsonb_header(JSONB_TEXT, 0x03).unwrap());
648 data.extend_from_slice(b"key"); data.extend(create_jsonb_header(JSONB_INT, 0x02).unwrap());
652 data.extend_from_slice(b"42"); let result = read_jsonb_value(&data).unwrap().0;
655 assert_eq!(result, json!({"key": 42}));
656 }
657
658 #[diesel_test_helper::test]
659 fn test_read_jsonb_nested_object() {
660 let mut data = Vec::new();
661
662 data.extend(create_jsonb_header(JSONB_OBJECT, 42).unwrap());
663
664 data.extend(create_jsonb_header(JSONB_TEXT, 9).unwrap());
665 data.extend_from_slice(b"outer_key");
666
667 data.extend(create_jsonb_header(JSONB_OBJECT, 13).unwrap());
668
669 data.extend(create_jsonb_header(JSONB_TEXT, 9).unwrap());
670 data.extend_from_slice(b"inner_key");
671
672 data.extend(create_jsonb_header(JSONB_INT, 2).unwrap());
673 data.extend_from_slice(b"42");
674
675 data.extend(create_jsonb_header(JSONB_TEXT, 14).unwrap());
676 data.extend_from_slice(b"additional_key");
677
678 data.extend(create_jsonb_header(JSONB_TRUE, 0).unwrap());
679
680 let result = read_jsonb_value(&data).unwrap().0;
681 assert_eq!(
682 result,
683 json!({
684 "additional_key": true,
685 "outer_key": {
686 "inner_key": 42
687 },
688 })
689 );
690 }
691
692 #[diesel_test_helper::test]
693 fn test_write_jsonb_null() {
694 let value = serde_json::Value::Null;
695 let mut buffer = Vec::new();
696 write_jsonb_value(&value, &mut buffer).unwrap();
697 assert_eq!(buffer, vec![JSONB_NULL]);
698 }
699
700 #[diesel_test_helper::test]
701 fn test_write_jsonb_true() {
702 let value = serde_json::Value::Bool(true);
703 let mut buffer = Vec::new();
704 write_jsonb_value(&value, &mut buffer).unwrap();
705 assert_eq!(buffer, vec![JSONB_TRUE]);
706 }
707
708 #[diesel_test_helper::test]
709 fn test_write_jsonb_false() {
710 let value = serde_json::Value::Bool(false);
711 let mut buffer = Vec::new();
712 write_jsonb_value(&value, &mut buffer).unwrap();
713 assert_eq!(buffer, vec![JSONB_FALSE]);
714 }
715
716 #[diesel_test_helper::test]
717 fn test_write_jsonb_int() {
718 let value = serde_json::Value::Number(serde_json::Number::from(1));
719 let mut buffer = Vec::new();
720 write_jsonb_value(&value, &mut buffer).unwrap();
721
722 let mut expected_buffer = Vec::new();
723 expected_buffer.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap());
724 expected_buffer.push(b'1'); assert_eq!(buffer, expected_buffer);
727 }
728
729 #[diesel_test_helper::test]
730 fn test_write_jsonb_float() {
731 let value = serde_json::Value::Number(serde_json::Number::from_f64(1.5).unwrap());
732 let mut buffer = Vec::new();
733 write_jsonb_value(&value, &mut buffer).unwrap();
734
735 let mut expected_buffer = Vec::new();
736 expected_buffer.extend(create_jsonb_header(JSONB_FLOAT, 0x03).unwrap());
737 expected_buffer.extend_from_slice(b"1.5"); assert_eq!(buffer, expected_buffer);
740 }
741
742 #[diesel_test_helper::test]
743 fn test_write_jsonb_text() {
744 let mut buffer = Vec::new();
745 let input_string = "hello";
746 write_jsonb_string(input_string, &mut buffer).unwrap();
747
748 let mut expected_buffer = Vec::new();
749 expected_buffer.extend(create_jsonb_header(JSONB_TEXT, 0x05).unwrap());
750 expected_buffer.extend_from_slice(b"hello");
751
752 assert_eq!(buffer, expected_buffer);
753 }
754
755 #[diesel_test_helper::test]
756 fn test_write_jsonb_textj() {
757 let mut buffer = Vec::new();
758 let input_string = "hello\nworld"; write_jsonb_string(input_string, &mut buffer).unwrap();
760
761 let mut expected_buffer = Vec::new();
762 expected_buffer.extend(create_jsonb_header(JSONB_TEXTJ, 12).unwrap());
763 expected_buffer.extend_from_slice(b"hello\\nworld");
764
765 assert_eq!(buffer, expected_buffer);
766 }
767
768 #[diesel_test_helper::test]
769 fn test_write_jsonb_array() {
770 let value = json!([1, true]);
771 let mut buffer = Vec::new();
772 write_jsonb_value(&value, &mut buffer).unwrap();
773
774 let mut expected_buffer = Vec::new();
775 expected_buffer.extend(create_jsonb_header(JSONB_ARRAY, 0x03).unwrap()); expected_buffer.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap()); expected_buffer.push(b'1'); expected_buffer.extend(create_jsonb_header(JSONB_TRUE, 0x00).unwrap()); assert_eq!(buffer, expected_buffer);
781 }
782
783 #[diesel_test_helper::test]
784 fn test_write_jsonb_object() {
785 let value = json!({"key": 42});
786 let mut buffer = Vec::new();
787 write_jsonb_value(&value, &mut buffer).unwrap();
788
789 let mut expected = Vec::new();
790 expected.extend(create_jsonb_header(JSONB_OBJECT, 7).unwrap());
791 expected.extend(create_jsonb_header(JSONB_TEXT, 3).unwrap());
792 expected.extend_from_slice(b"key");
793 expected.extend(create_jsonb_header(JSONB_INT, 2).unwrap());
794 expected.extend_from_slice(b"42");
795
796 assert_eq!(buffer, expected,);
797 }
798
799 #[diesel_test_helper::test]
800 fn jsonb_to_sql_bool() {
801 let conn = &mut connection();
802 let res = diesel::select(json!(true).into_sql::<Jsonb>().eq(&sql("jsonb('true')")))
803 .get_result::<bool>(conn)
804 .unwrap();
805 assert!(res);
806 }
807
808 #[diesel_test_helper::test]
809 fn jsonb_to_sql_null() {
810 let conn = &mut connection();
811 let res = diesel::select(json!(null).into_sql::<Jsonb>().eq(&sql("jsonb('null')")))
812 .get_result::<bool>(conn)
813 .unwrap();
814 assert!(res);
815 }
816
817 #[diesel_test_helper::test]
818 fn jsonb_to_sql_integer() {
819 let conn = &mut connection();
820 let res = diesel::select(json!(42).into_sql::<Jsonb>().eq(&sql("jsonb('42')")))
821 .get_result::<bool>(conn)
822 .unwrap();
823 assert!(res);
824 }
825
826 #[diesel_test_helper::test]
827 fn jsonb_to_sql_float() {
828 let conn = &mut connection();
829 let res = diesel::select(json!(42.23).into_sql::<Jsonb>().eq(&sql("jsonb('42.23')")))
830 .get_result::<bool>(conn)
831 .unwrap();
832 assert!(res);
833 }
834
835 #[diesel_test_helper::test]
836 fn jsonb_to_sql_text() {
837 let conn = &mut connection();
838
839 let res = diesel::select(
841 json!("hello")
842 .into_sql::<Jsonb>()
843 .eq(&sql("jsonb('\"hello\"')")),
844 )
845 .get_result::<bool>(conn)
846 .unwrap();
847
848 assert!(res);
849 }
850
851 #[diesel_test_helper::test]
852 fn jsonb_to_sql_textj() {
853 let conn = &mut connection();
854
855 let res = diesel::select(
857 json!("hello\nworld")
858 .into_sql::<Jsonb>()
859 .eq(&sql("jsonb('\"hello\\nworld\"')")), )
861 .get_result::<bool>(conn)
862 .unwrap();
863
864 assert!(res);
865 }
866
867 #[diesel_test_helper::test]
868 fn jsonb_to_sql_array() {
869 let conn = &mut connection();
870 let res = diesel::select(
871 json!([1, true, "foo"])
872 .into_sql::<Jsonb>()
873 .eq(&sql("jsonb('[1, true, \"foo\"]')")),
874 )
875 .get_result::<bool>(conn)
876 .unwrap();
877 assert!(res);
878 }
879
880 #[diesel_test_helper::test]
881 fn jsonb_to_sql_object() {
882 let conn = &mut connection();
883 let res = diesel::select(
884 json!({"key": "value"})
885 .into_sql::<Jsonb>()
886 .eq(&sql("jsonb('{\"key\": \"value\"}')")),
887 )
888 .get_result::<bool>(conn)
889 .unwrap();
890 assert!(res);
891 }
892
893 #[diesel_test_helper::test]
894 fn jsonb_to_sql_object_in_object() {
895 let conn = &mut connection();
896 let json_value = json!({
897 "outer_key": {
898 "additional_key": true,
899 "inner_key": {
900 "nested_key": 42
901 },
902 }
903 });
904 let res = diesel::select(json_value.into_sql::<Jsonb>().eq(&sql(
905 r#"jsonb('{"outer_key": {"additional_key": true, "inner_key": {"nested_key": 42}}}')"#,
906 )))
907 .get_result::<bool>(conn)
908 .unwrap();
909 assert!(res);
910 }
911
912 #[diesel_test_helper::test]
913 fn jsonb_to_sql_array_in_object() {
914 let conn = &mut connection();
915 let json_value = json!({
916 "is_valid": false,
917 "key": [1, 2, 3],
918 });
919 let res = diesel::select(
920 json_value
921 .into_sql::<Jsonb>()
922 .eq(&sql(r#"jsonb('{"is_valid": false, "key": [1, 2, 3]}')"#)),
923 )
924 .get_result::<bool>(conn)
925 .unwrap();
926 assert!(res);
927 }
928
929 #[diesel_test_helper::test]
930 fn jsonb_to_sql_object_in_array() {
931 let conn = &mut connection();
932 let json_value = json!([
933 {
934 "nested_key": "nested_value"
935 },
936 {
937 "int_value": 99
938 }
939 ]);
940 let res = diesel::select(json_value.into_sql::<Jsonb>().eq(&sql(
941 r#"jsonb('[{"nested_key": "nested_value"}, {"int_value": 99}]')"#,
942 )))
943 .get_result::<bool>(conn)
944 .unwrap();
945 assert!(res);
946 }
947
948 #[diesel_test_helper::test]
949 fn jsonb_from_sql_null() {
950 let conn = &mut connection();
951 let res = diesel::select(sql::<Jsonb>("jsonb('null')"))
952 .get_result::<serde_json::Value>(conn)
953 .unwrap();
954 assert_eq!(res, serde_json::json!(null));
955 }
956
957 #[diesel_test_helper::test]
958 fn jsonb_from_sql_true() {
959 let conn = &mut connection();
960 let res = diesel::select(sql::<Jsonb>("jsonb('true')"))
961 .get_result::<serde_json::Value>(conn)
962 .unwrap();
963 assert_eq!(res, serde_json::json!(true));
964 }
965
966 #[diesel_test_helper::test]
967 fn jsonb_from_sql_false() {
968 let conn = &mut connection();
969 let res = diesel::select(sql::<Jsonb>("jsonb('false')"))
970 .get_result::<serde_json::Value>(conn)
971 .unwrap();
972 assert_eq!(res, serde_json::json!(false));
973 }
974
975 #[diesel_test_helper::test]
976 fn jsonb_from_sql_int() {
977 let conn = &mut connection();
978 let res = diesel::select(sql::<Jsonb>("jsonb('42')"))
979 .get_result::<serde_json::Value>(conn)
980 .unwrap();
981 assert_eq!(res, serde_json::json!(42));
982 }
983
984 #[diesel_test_helper::test]
985 fn jsonb_from_sql_float() {
986 let conn = &mut connection();
987 let res = diesel::select(sql::<Jsonb>("jsonb('42.23')"))
988 .get_result::<serde_json::Value>(conn)
989 .unwrap();
990 assert_eq!(res, serde_json::json!(42.23));
991 }
992
993 #[diesel_test_helper::test]
994 fn jsonb_from_sql_object() {
995 let conn = &mut connection();
996 let res = diesel::select(sql::<Jsonb>("jsonb('{\"key\": \"value\"}')"))
997 .get_result::<serde_json::Value>(conn)
998 .unwrap();
999 assert_eq!(res, serde_json::json!({"key": "value"}));
1000 }
1001
1002 #[diesel_test_helper::test]
1003 fn jsonb_from_sql_array() {
1004 let conn = &mut connection();
1005 let res = diesel::select(sql::<Jsonb>("jsonb('[1, 2, 3]')"))
1006 .get_result::<serde_json::Value>(conn)
1007 .unwrap();
1008 assert_eq!(res, serde_json::json!([1, 2, 3]));
1009 }
1010
1011 #[diesel_test_helper::test]
1012 fn jsonb_from_sql_nested_objects() {
1013 let conn = &mut connection();
1014 let res = diesel::select(sql::<Jsonb>("jsonb('{\"outer\": {\"inner\": 42}}')"))
1015 .get_result::<serde_json::Value>(conn)
1016 .unwrap();
1017 assert_eq!(res, serde_json::json!({"outer": {"inner": 42}}));
1018 }
1019
1020 #[diesel_test_helper::test]
1021 fn jsonb_from_sql_nested_arrays() {
1022 let conn = &mut connection();
1023 let res = diesel::select(sql::<Jsonb>("jsonb('[[1, 2], [3, 4]]')"))
1024 .get_result::<serde_json::Value>(conn)
1025 .unwrap();
1026 assert_eq!(res, serde_json::json!([[1, 2], [3, 4]]));
1027 }
1028
1029 #[diesel_test_helper::test]
1030 fn jsonb_from_sql_nested_arrays_in_objects() {
1031 let conn = &mut connection();
1032 let res = diesel::select(sql::<Jsonb>("jsonb('{\"array\": [1, 2, 3]}')"))
1033 .get_result::<serde_json::Value>(conn)
1034 .unwrap();
1035 assert_eq!(res, serde_json::json!({"array": [1, 2, 3]}));
1036 }
1037
1038 #[diesel_test_helper::test]
1039 fn jsonb_from_sql_nested_objects_in_arrays() {
1040 let conn = &mut connection();
1041 let res = diesel::select(sql::<Jsonb>(
1042 "jsonb('[{\"key1\": \"value1\"}, {\"key2\": \"value2\"}]')",
1043 ))
1044 .get_result::<serde_json::Value>(conn)
1045 .unwrap();
1046 assert_eq!(
1047 res,
1048 serde_json::json!([{"key1": "value1"}, {"key2": "value2"}])
1049 );
1050 }
1051
1052 #[diesel_test_helper::test]
1053 fn jsonb_from_sql_text() {
1054 let conn = &mut connection();
1055 let res = diesel::select(sql::<Jsonb>("jsonb('\"hello\"')"))
1056 .get_result::<serde_json::Value>(conn)
1057 .unwrap();
1058 assert_eq!(res, serde_json::json!("hello"));
1059 }
1060
1061 #[diesel_test_helper::test]
1062 fn jsonb_from_sql_textj() {
1063 let conn = &mut connection();
1064 let res = diesel::select(sql::<Jsonb>("jsonb('\"hello\\nworld\"')"))
1065 .get_result::<serde_json::Value>(conn)
1066 .unwrap();
1067 assert_eq!(res, serde_json::json!("hello\nworld"));
1068 }
1069
1070 #[diesel_test_helper::test]
1071 fn bad_json_from_sql() {
1072 let conn = &mut connection();
1073 let res = diesel::select(json!(true).into_sql::<Json>().eq(&sql("json('boom')")))
1074 .get_result::<bool>(conn);
1075 assert_eq!(res.unwrap_err().to_string(), "malformed JSON");
1076 }
1077
1078 #[diesel_test_helper::test]
1079 fn bad_jsonb_from_sql() {
1080 let conn = &mut connection();
1081 let res = diesel::select(json!(true).into_sql::<Jsonb>().eq(&sql("jsonb('boom')")))
1082 .get_result::<bool>(conn);
1083 assert_eq!(res.unwrap_err().to_string(), "malformed JSON");
1084 }
1085
1086 #[diesel_test_helper::test]
1087 fn no_json_from_sql() {
1088 let uuid: Result<serde_json::Value, _> = FromSql::<Json, Sqlite>::from_nullable_sql(None);
1089 assert_eq!(
1090 uuid.unwrap_err().to_string(),
1091 "Unexpected null for non-null column"
1092 );
1093 }
1094
1095 #[diesel_test_helper::test]
1096 fn no_jsonb_from_sql() {
1097 let uuid: Result<serde_json::Value, _> = FromSql::<Jsonb, Sqlite>::from_nullable_sql(None);
1098 assert_eq!(
1099 uuid.unwrap_err().to_string(),
1100 "Unexpected null for non-null column"
1101 );
1102 }
1103}