1+ use chrono:: { DateTime , Utc } ;
12use sqlx:: Acquire ;
23
34use super :: { Blob , FileRange } ;
@@ -69,7 +70,16 @@ impl DatabaseBackend {
6970 // https://www.postgresql.org/message-id/162867790712200946i7ba8eb92v908ac595c0c35aee%40mail.gmail.com
7071 let max_size = max_size. min ( std:: i32:: MAX as usize ) as i32 ;
7172
72- let ( path, mime, date_updated, compression, content, is_too_big) = if let Some ( r) = range {
73+ struct Result {
74+ path : String ,
75+ mime : String ,
76+ date_updated : DateTime < Utc > ,
77+ compression : Option < i32 > ,
78+ content : Option < Vec < u8 > > ,
79+ is_too_big : bool ,
80+ }
81+
82+ let result = if let Some ( r) = range {
7383 // when we only want to get a range we can validate already if the range is small enough
7484 if ( r. end ( ) - r. start ( ) + 1 ) > max_size as u64 {
7585 return Err ( std:: io:: Error :: new (
@@ -80,10 +90,12 @@ impl DatabaseBackend {
8090 }
8191 let range_start = i32:: try_from ( * r. start ( ) ) ?;
8292
83- sqlx:: query!(
93+ sqlx:: query_as!(
94+ Result ,
8495 r#"SELECT
8596 path, mime, date_updated, compression,
86- substring(content from $2 for $3) as content
97+ substring(content from $2 for $3) as content,
98+ FALSE as "is_too_big!"
8799 FROM files
88100 WHERE path = $1;"# ,
89101 path,
@@ -92,21 +104,12 @@ impl DatabaseBackend {
92104 )
93105 . fetch_optional ( & self . pool )
94106 . await ?
95- . ok_or ( super :: PathNotFoundError )
96- . map ( |row| {
97- (
98- row. path ,
99- row. mime ,
100- row. date_updated ,
101- row. compression ,
102- row. content ,
103- false ,
104- )
105- } ) ?
107+ . ok_or ( super :: PathNotFoundError ) ?
106108 } else {
107109 // The size limit is checked at the database level, to avoid receiving data altogether if
108110 // the limit is exceeded.
109- sqlx:: query!(
111+ sqlx:: query_as!(
112+ Result ,
110113 r#"SELECT
111114 path, mime, date_updated, compression,
112115 (CASE WHEN LENGTH(content) <= $2 THEN content ELSE NULL END) AS content,
@@ -118,36 +121,26 @@ impl DatabaseBackend {
118121 )
119122 . fetch_optional ( & self . pool )
120123 . await ?
121- . ok_or ( super :: PathNotFoundError )
122- . map ( |row| {
123- (
124- row. path ,
125- row. mime ,
126- row. date_updated ,
127- row. compression ,
128- row. content ,
129- row. is_too_big ,
130- )
131- } ) ?
124+ . ok_or ( super :: PathNotFoundError ) ?
132125 } ;
133126
134- if is_too_big {
127+ if result . is_too_big {
135128 return Err ( std:: io:: Error :: new (
136129 std:: io:: ErrorKind :: Other ,
137130 crate :: error:: SizeLimitReached ,
138131 )
139132 . into ( ) ) ;
140133 }
141134
142- let compression = compression. map ( |i| {
135+ let compression = result . compression . map ( |i| {
143136 i. try_into ( )
144137 . expect ( "invalid compression algorithm stored in database" )
145138 } ) ;
146139 Ok ( Blob {
147- path,
148- mime,
149- date_updated,
150- content : content. unwrap_or_default ( ) ,
140+ path : result . path ,
141+ mime : result . mime ,
142+ date_updated : result . date_updated ,
143+ content : result . content . unwrap_or_default ( ) ,
151144 compression,
152145 } )
153146 }
0 commit comments