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 => Err("TEXTRAW is not supported".into()),
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 <[_]>::into_vec(::alloc::boxed::box_new([((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 <[_]>::into_vec(::alloc::boxed::box_new([(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_array() {
600 let mut data = Vec::new();
602 data.extend(create_jsonb_header(JSONB_ARRAY, 0x03).unwrap()); data.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap());
606 data.push(b'1');
607
608 data.extend(create_jsonb_header(JSONB_TRUE, 0x00).unwrap());
610
611 let result = read_jsonb_value(&data).unwrap().0;
612 assert_eq!(result, json!([1, true]));
613 }
614
615 #[diesel_test_helper::test]
616 fn test_read_jsonb_object() {
617 let mut data = Vec::new();
619 data.extend(create_jsonb_header(JSONB_OBJECT, 0x07).unwrap()); data.extend(create_jsonb_header(JSONB_TEXT, 0x03).unwrap());
623 data.extend_from_slice(b"key"); data.extend(create_jsonb_header(JSONB_INT, 0x02).unwrap());
627 data.extend_from_slice(b"42"); let result = read_jsonb_value(&data).unwrap().0;
630 assert_eq!(result, json!({"key": 42}));
631 }
632
633 #[diesel_test_helper::test]
634 fn test_read_jsonb_nested_object() {
635 let mut data = Vec::new();
636
637 data.extend(create_jsonb_header(JSONB_OBJECT, 42).unwrap());
638
639 data.extend(create_jsonb_header(JSONB_TEXT, 9).unwrap());
640 data.extend_from_slice(b"outer_key");
641
642 data.extend(create_jsonb_header(JSONB_OBJECT, 13).unwrap());
643
644 data.extend(create_jsonb_header(JSONB_TEXT, 9).unwrap());
645 data.extend_from_slice(b"inner_key");
646
647 data.extend(create_jsonb_header(JSONB_INT, 2).unwrap());
648 data.extend_from_slice(b"42");
649
650 data.extend(create_jsonb_header(JSONB_TEXT, 14).unwrap());
651 data.extend_from_slice(b"additional_key");
652
653 data.extend(create_jsonb_header(JSONB_TRUE, 0).unwrap());
654
655 let result = read_jsonb_value(&data).unwrap().0;
656 assert_eq!(
657 result,
658 json!({
659 "additional_key": true,
660 "outer_key": {
661 "inner_key": 42
662 },
663 })
664 );
665 }
666
667 #[diesel_test_helper::test]
668 fn test_write_jsonb_null() {
669 let value = serde_json::Value::Null;
670 let mut buffer = Vec::new();
671 write_jsonb_value(&value, &mut buffer).unwrap();
672 assert_eq!(buffer, vec![JSONB_NULL]);
673 }
674
675 #[diesel_test_helper::test]
676 fn test_write_jsonb_true() {
677 let value = serde_json::Value::Bool(true);
678 let mut buffer = Vec::new();
679 write_jsonb_value(&value, &mut buffer).unwrap();
680 assert_eq!(buffer, vec![JSONB_TRUE]);
681 }
682
683 #[diesel_test_helper::test]
684 fn test_write_jsonb_false() {
685 let value = serde_json::Value::Bool(false);
686 let mut buffer = Vec::new();
687 write_jsonb_value(&value, &mut buffer).unwrap();
688 assert_eq!(buffer, vec![JSONB_FALSE]);
689 }
690
691 #[diesel_test_helper::test]
692 fn test_write_jsonb_int() {
693 let value = serde_json::Value::Number(serde_json::Number::from(1));
694 let mut buffer = Vec::new();
695 write_jsonb_value(&value, &mut buffer).unwrap();
696
697 let mut expected_buffer = Vec::new();
698 expected_buffer.extend(create_jsonb_header(JSONB_INT, 0x01).unwrap());
699 expected_buffer.push(b'1'); assert_eq!(buffer, expected_buffer);
702 }
703
704 #[diesel_test_helper::test]
705 fn test_write_jsonb_float() {
706 let value = serde_json::Value::Number(serde_json::Number::from_f64(1.5).unwrap());
707 let mut buffer = Vec::new();
708 write_jsonb_value(&value, &mut buffer).unwrap();
709
710 let mut expected_buffer = Vec::new();
711 expected_buffer.extend(create_jsonb_header(JSONB_FLOAT, 0x03).unwrap());
712 expected_buffer.extend_from_slice(b"1.5"); assert_eq!(buffer, expected_buffer);
715 }
716
717 #[diesel_test_helper::test]
718 fn test_write_jsonb_text() {
719 let mut buffer = Vec::new();
720 let input_string = "hello";
721 write_jsonb_string(input_string, &mut buffer).unwrap();
722
723 let mut expected_buffer = Vec::new();
724 expected_buffer.extend(create_jsonb_header(JSONB_TEXT, 0x05).unwrap());
725 expected_buffer.extend_from_slice(b"hello");
726
727 assert_eq!(buffer, expected_buffer);
728 }
729
730 #[diesel_test_helper::test]
731 fn test_write_jsonb_textj() {
732 let mut buffer = Vec::new();
733 let input_string = "hello\nworld"; write_jsonb_string(input_string, &mut buffer).unwrap();
735
736 let mut expected_buffer = Vec::new();
737 expected_buffer.extend(create_jsonb_header(JSONB_TEXTJ, 12).unwrap());
738 expected_buffer.extend_from_slice(b"hello\\nworld");
739
740 assert_eq!(buffer, expected_buffer);
741 }
742
743 #[diesel_test_helper::test]
744 fn test_write_jsonb_array() {
745 let value = json!([1, true]);
746 let mut buffer = Vec::new();
747 write_jsonb_value(&value, &mut buffer).unwrap();
748
749 let mut expected_buffer = Vec::new();
750 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);
756 }
757
758 #[diesel_test_helper::test]
759 fn test_write_jsonb_object() {
760 let value = json!({"key": 42});
761 let mut buffer = Vec::new();
762 write_jsonb_value(&value, &mut buffer).unwrap();
763
764 let mut expected = Vec::new();
765 expected.extend(create_jsonb_header(JSONB_OBJECT, 7).unwrap());
766 expected.extend(create_jsonb_header(JSONB_TEXT, 3).unwrap());
767 expected.extend_from_slice(b"key");
768 expected.extend(create_jsonb_header(JSONB_INT, 2).unwrap());
769 expected.extend_from_slice(b"42");
770
771 assert_eq!(buffer, expected,);
772 }
773
774 #[diesel_test_helper::test]
775 fn jsonb_to_sql_bool() {
776 let conn = &mut connection();
777 let res = diesel::select(json!(true).into_sql::<Jsonb>().eq(&sql("jsonb('true')")))
778 .get_result::<bool>(conn)
779 .unwrap();
780 assert!(res);
781 }
782
783 #[diesel_test_helper::test]
784 fn jsonb_to_sql_null() {
785 let conn = &mut connection();
786 let res = diesel::select(json!(null).into_sql::<Jsonb>().eq(&sql("jsonb('null')")))
787 .get_result::<bool>(conn)
788 .unwrap();
789 assert!(res);
790 }
791
792 #[diesel_test_helper::test]
793 fn jsonb_to_sql_integer() {
794 let conn = &mut connection();
795 let res = diesel::select(json!(42).into_sql::<Jsonb>().eq(&sql("jsonb('42')")))
796 .get_result::<bool>(conn)
797 .unwrap();
798 assert!(res);
799 }
800
801 #[diesel_test_helper::test]
802 fn jsonb_to_sql_float() {
803 let conn = &mut connection();
804 let res = diesel::select(json!(42.23).into_sql::<Jsonb>().eq(&sql("jsonb('42.23')")))
805 .get_result::<bool>(conn)
806 .unwrap();
807 assert!(res);
808 }
809
810 #[diesel_test_helper::test]
811 fn jsonb_to_sql_text() {
812 let conn = &mut connection();
813
814 let res = diesel::select(
816 json!("hello")
817 .into_sql::<Jsonb>()
818 .eq(&sql("jsonb('\"hello\"')")),
819 )
820 .get_result::<bool>(conn)
821 .unwrap();
822
823 assert!(res);
824 }
825
826 #[diesel_test_helper::test]
827 fn jsonb_to_sql_textj() {
828 let conn = &mut connection();
829
830 let res = diesel::select(
832 json!("hello\nworld")
833 .into_sql::<Jsonb>()
834 .eq(&sql("jsonb('\"hello\\nworld\"')")), )
836 .get_result::<bool>(conn)
837 .unwrap();
838
839 assert!(res);
840 }
841
842 #[diesel_test_helper::test]
843 fn jsonb_to_sql_array() {
844 let conn = &mut connection();
845 let res = diesel::select(
846 json!([1, true, "foo"])
847 .into_sql::<Jsonb>()
848 .eq(&sql("jsonb('[1, true, \"foo\"]')")),
849 )
850 .get_result::<bool>(conn)
851 .unwrap();
852 assert!(res);
853 }
854
855 #[diesel_test_helper::test]
856 fn jsonb_to_sql_object() {
857 let conn = &mut connection();
858 let res = diesel::select(
859 json!({"key": "value"})
860 .into_sql::<Jsonb>()
861 .eq(&sql("jsonb('{\"key\": \"value\"}')")),
862 )
863 .get_result::<bool>(conn)
864 .unwrap();
865 assert!(res);
866 }
867
868 #[diesel_test_helper::test]
869 fn jsonb_to_sql_object_in_object() {
870 let conn = &mut connection();
871 let json_value = json!({
872 "outer_key": {
873 "additional_key": true,
874 "inner_key": {
875 "nested_key": 42
876 },
877 }
878 });
879 let res = diesel::select(json_value.into_sql::<Jsonb>().eq(&sql(
880 r#"jsonb('{"outer_key": {"additional_key": true, "inner_key": {"nested_key": 42}}}')"#,
881 )))
882 .get_result::<bool>(conn)
883 .unwrap();
884 assert!(res);
885 }
886
887 #[diesel_test_helper::test]
888 fn jsonb_to_sql_array_in_object() {
889 let conn = &mut connection();
890 let json_value = json!({
891 "is_valid": false,
892 "key": [1, 2, 3],
893 });
894 let res = diesel::select(
895 json_value
896 .into_sql::<Jsonb>()
897 .eq(&sql(r#"jsonb('{"is_valid": false, "key": [1, 2, 3]}')"#)),
898 )
899 .get_result::<bool>(conn)
900 .unwrap();
901 assert!(res);
902 }
903
904 #[diesel_test_helper::test]
905 fn jsonb_to_sql_object_in_array() {
906 let conn = &mut connection();
907 let json_value = json!([
908 {
909 "nested_key": "nested_value"
910 },
911 {
912 "int_value": 99
913 }
914 ]);
915 let res = diesel::select(json_value.into_sql::<Jsonb>().eq(&sql(
916 r#"jsonb('[{"nested_key": "nested_value"}, {"int_value": 99}]')"#,
917 )))
918 .get_result::<bool>(conn)
919 .unwrap();
920 assert!(res);
921 }
922
923 #[diesel_test_helper::test]
924 fn jsonb_from_sql_null() {
925 let conn = &mut connection();
926 let res = diesel::select(sql::<Jsonb>("jsonb('null')"))
927 .get_result::<serde_json::Value>(conn)
928 .unwrap();
929 assert_eq!(res, serde_json::json!(null));
930 }
931
932 #[diesel_test_helper::test]
933 fn jsonb_from_sql_true() {
934 let conn = &mut connection();
935 let res = diesel::select(sql::<Jsonb>("jsonb('true')"))
936 .get_result::<serde_json::Value>(conn)
937 .unwrap();
938 assert_eq!(res, serde_json::json!(true));
939 }
940
941 #[diesel_test_helper::test]
942 fn jsonb_from_sql_false() {
943 let conn = &mut connection();
944 let res = diesel::select(sql::<Jsonb>("jsonb('false')"))
945 .get_result::<serde_json::Value>(conn)
946 .unwrap();
947 assert_eq!(res, serde_json::json!(false));
948 }
949
950 #[diesel_test_helper::test]
951 fn jsonb_from_sql_int() {
952 let conn = &mut connection();
953 let res = diesel::select(sql::<Jsonb>("jsonb('42')"))
954 .get_result::<serde_json::Value>(conn)
955 .unwrap();
956 assert_eq!(res, serde_json::json!(42));
957 }
958
959 #[diesel_test_helper::test]
960 fn jsonb_from_sql_float() {
961 let conn = &mut connection();
962 let res = diesel::select(sql::<Jsonb>("jsonb('42.23')"))
963 .get_result::<serde_json::Value>(conn)
964 .unwrap();
965 assert_eq!(res, serde_json::json!(42.23));
966 }
967
968 #[diesel_test_helper::test]
969 fn jsonb_from_sql_object() {
970 let conn = &mut connection();
971 let res = diesel::select(sql::<Jsonb>("jsonb('{\"key\": \"value\"}')"))
972 .get_result::<serde_json::Value>(conn)
973 .unwrap();
974 assert_eq!(res, serde_json::json!({"key": "value"}));
975 }
976
977 #[diesel_test_helper::test]
978 fn jsonb_from_sql_array() {
979 let conn = &mut connection();
980 let res = diesel::select(sql::<Jsonb>("jsonb('[1, 2, 3]')"))
981 .get_result::<serde_json::Value>(conn)
982 .unwrap();
983 assert_eq!(res, serde_json::json!([1, 2, 3]));
984 }
985
986 #[diesel_test_helper::test]
987 fn jsonb_from_sql_nested_objects() {
988 let conn = &mut connection();
989 let res = diesel::select(sql::<Jsonb>("jsonb('{\"outer\": {\"inner\": 42}}')"))
990 .get_result::<serde_json::Value>(conn)
991 .unwrap();
992 assert_eq!(res, serde_json::json!({"outer": {"inner": 42}}));
993 }
994
995 #[diesel_test_helper::test]
996 fn jsonb_from_sql_nested_arrays() {
997 let conn = &mut connection();
998 let res = diesel::select(sql::<Jsonb>("jsonb('[[1, 2], [3, 4]]')"))
999 .get_result::<serde_json::Value>(conn)
1000 .unwrap();
1001 assert_eq!(res, serde_json::json!([[1, 2], [3, 4]]));
1002 }
1003
1004 #[diesel_test_helper::test]
1005 fn jsonb_from_sql_nested_arrays_in_objects() {
1006 let conn = &mut connection();
1007 let res = diesel::select(sql::<Jsonb>("jsonb('{\"array\": [1, 2, 3]}')"))
1008 .get_result::<serde_json::Value>(conn)
1009 .unwrap();
1010 assert_eq!(res, serde_json::json!({"array": [1, 2, 3]}));
1011 }
1012
1013 #[diesel_test_helper::test]
1014 fn jsonb_from_sql_nested_objects_in_arrays() {
1015 let conn = &mut connection();
1016 let res = diesel::select(sql::<Jsonb>(
1017 "jsonb('[{\"key1\": \"value1\"}, {\"key2\": \"value2\"}]')",
1018 ))
1019 .get_result::<serde_json::Value>(conn)
1020 .unwrap();
1021 assert_eq!(
1022 res,
1023 serde_json::json!([{"key1": "value1"}, {"key2": "value2"}])
1024 );
1025 }
1026
1027 #[diesel_test_helper::test]
1028 fn jsonb_from_sql_text() {
1029 let conn = &mut connection();
1030 let res = diesel::select(sql::<Jsonb>("jsonb('\"hello\"')"))
1031 .get_result::<serde_json::Value>(conn)
1032 .unwrap();
1033 assert_eq!(res, serde_json::json!("hello"));
1034 }
1035
1036 #[diesel_test_helper::test]
1037 fn jsonb_from_sql_textj() {
1038 let conn = &mut connection();
1039 let res = diesel::select(sql::<Jsonb>("jsonb('\"hello\\nworld\"')"))
1040 .get_result::<serde_json::Value>(conn)
1041 .unwrap();
1042 assert_eq!(res, serde_json::json!("hello\nworld"));
1043 }
1044
1045 #[diesel_test_helper::test]
1046 fn bad_json_from_sql() {
1047 let conn = &mut connection();
1048 let res = diesel::select(json!(true).into_sql::<Json>().eq(&sql("json('boom')")))
1049 .get_result::<bool>(conn);
1050 assert_eq!(res.unwrap_err().to_string(), "malformed JSON");
1051 }
1052
1053 #[diesel_test_helper::test]
1054 fn bad_jsonb_from_sql() {
1055 let conn = &mut connection();
1056 let res = diesel::select(json!(true).into_sql::<Jsonb>().eq(&sql("jsonb('boom')")))
1057 .get_result::<bool>(conn);
1058 assert_eq!(res.unwrap_err().to_string(), "malformed JSON");
1059 }
1060
1061 #[diesel_test_helper::test]
1062 fn no_json_from_sql() {
1063 let uuid: Result<serde_json::Value, _> = FromSql::<Json, Sqlite>::from_nullable_sql(None);
1064 assert_eq!(
1065 uuid.unwrap_err().to_string(),
1066 "Unexpected null for non-null column"
1067 );
1068 }
1069
1070 #[diesel_test_helper::test]
1071 fn no_jsonb_from_sql() {
1072 let uuid: Result<serde_json::Value, _> = FromSql::<Jsonb, Sqlite>::from_nullable_sql(None);
1073 assert_eq!(
1074 uuid.unwrap_err().to_string(),
1075 "Unexpected null for non-null column"
1076 );
1077 }
1078}