@@ -10,20 +10,49 @@ pub struct GetAuthorRow {
10
10
pub name : String ,
11
11
pub bio : Option < String > ,
12
12
}
13
+ impl GetAuthorRow {
14
+ pub ( crate ) fn from_row ( row : & tokio_postgres:: Row ) -> Result < Self , tokio_postgres:: Error > {
15
+ Ok ( GetAuthorRow {
16
+ id : row. try_get ( 0 ) ?,
17
+ name : row. try_get ( 1 ) ?,
18
+ bio : row. try_get ( 2 ) ?,
19
+ } )
20
+ }
21
+ }
13
22
pub async fn get_author (
14
23
client : & impl tokio_postgres:: GenericClient ,
15
24
id : i64 ,
16
25
) -> Result < Option < GetAuthorRow > , tokio_postgres:: Error > {
17
- let row = client. query_opt ( GET_AUTHOR , & [ & id] ) . await ?;
18
- let v = match row {
19
- Some ( v) => GetAuthorRow {
20
- id : v. try_get ( 0 ) ?,
21
- name : v. try_get ( 1 ) ?,
22
- bio : v. try_get ( 2 ) ?,
23
- } ,
24
- None => return Ok ( None ) ,
25
- } ;
26
- Ok ( Some ( v) )
26
+ let query_struct = GetAuthor { id : id } ;
27
+ query_struct. query_opt ( client) . await
28
+ }
29
+ #[ derive( Debug ) ]
30
+ pub struct GetAuthor {
31
+ pub id : i64 ,
32
+ }
33
+ impl GetAuthor {
34
+ pub const QUERY : & ' static str = r#"-- name: GetAuthor :one
35
+ SELECT id, name, bio FROM authors
36
+ WHERE id = $1 LIMIT 1"# ;
37
+ }
38
+ impl GetAuthor {
39
+ pub async fn query_one (
40
+ & self ,
41
+ client : & impl tokio_postgres:: GenericClient ,
42
+ ) -> Result < GetAuthorRow , tokio_postgres:: Error > {
43
+ let row = client. query_one ( Self :: QUERY , & [ & self . id ] ) . await ?;
44
+ GetAuthorRow :: from_row ( & row)
45
+ }
46
+ pub async fn query_opt (
47
+ & self ,
48
+ client : & impl tokio_postgres:: GenericClient ,
49
+ ) -> Result < Option < GetAuthorRow > , tokio_postgres:: Error > {
50
+ let row = client. query_opt ( Self :: QUERY , & [ & self . id ] ) . await ?;
51
+ match row {
52
+ Some ( ref row) => Ok ( Some ( GetAuthorRow :: from_row ( row) ?) ) ,
53
+ None => Ok ( None ) ,
54
+ }
55
+ }
27
56
}
28
57
pub const LIST_AUTHORS : & str = r#"-- name: ListAuthors :many
29
58
SELECT id, name, bio FROM authors
@@ -34,20 +63,23 @@ pub struct ListAuthorsRow {
34
63
pub name : String ,
35
64
pub bio : Option < String > ,
36
65
}
66
+ impl ListAuthorsRow {
67
+ pub ( crate ) fn from_row ( row : & tokio_postgres:: Row ) -> Result < Self , tokio_postgres:: Error > {
68
+ Ok ( ListAuthorsRow {
69
+ id : row. try_get ( 0 ) ?,
70
+ name : row. try_get ( 1 ) ?,
71
+ bio : row. try_get ( 2 ) ?,
72
+ } )
73
+ }
74
+ }
37
75
pub async fn list_authors (
38
76
client : & impl tokio_postgres:: GenericClient ,
39
77
) -> Result <
40
78
impl Iterator < Item = Result < ListAuthorsRow , tokio_postgres:: Error > > ,
41
79
tokio_postgres:: Error ,
42
80
> {
43
81
let rows = client. query ( LIST_AUTHORS , & [ ] ) . await ?;
44
- Ok ( rows. into_iter ( ) . map ( |r| {
45
- Ok ( ListAuthorsRow {
46
- id : r. try_get ( 0 ) ?,
47
- name : r. try_get ( 1 ) ?,
48
- bio : r. try_get ( 2 ) ?,
49
- } )
50
- } ) )
82
+ Ok ( rows. into_iter ( ) . map ( |r| ListAuthorsRow :: from_row ( & r) ) )
51
83
}
52
84
pub const CREATE_AUTHOR : & str = r#"-- name: CreateAuthor :one
53
85
INSERT INTO authors (
@@ -62,21 +94,62 @@ pub struct CreateAuthorRow {
62
94
pub name : String ,
63
95
pub bio : Option < String > ,
64
96
}
97
+ impl CreateAuthorRow {
98
+ pub ( crate ) fn from_row ( row : & tokio_postgres:: Row ) -> Result < Self , tokio_postgres:: Error > {
99
+ Ok ( CreateAuthorRow {
100
+ id : row. try_get ( 0 ) ?,
101
+ name : row. try_get ( 1 ) ?,
102
+ bio : row. try_get ( 2 ) ?,
103
+ } )
104
+ }
105
+ }
65
106
pub async fn create_author (
66
107
client : & impl tokio_postgres:: GenericClient ,
67
108
name : & str ,
68
109
bio : Option < & str > ,
69
110
) -> Result < Option < CreateAuthorRow > , tokio_postgres:: Error > {
70
- let row = client. query_opt ( CREATE_AUTHOR , & [ & name, & bio] ) . await ?;
71
- let v = match row {
72
- Some ( v) => CreateAuthorRow {
73
- id : v. try_get ( 0 ) ?,
74
- name : v. try_get ( 1 ) ?,
75
- bio : v. try_get ( 2 ) ?,
76
- } ,
77
- None => return Ok ( None ) ,
111
+ let query_struct = CreateAuthor {
112
+ name : std:: borrow:: Cow :: Borrowed ( name) ,
113
+ bio : bio. map ( std:: borrow:: Cow :: Borrowed ) ,
78
114
} ;
79
- Ok ( Some ( v) )
115
+ query_struct. query_opt ( client) . await
116
+ }
117
+ #[ derive( Debug ) ]
118
+ pub struct CreateAuthor < ' a > {
119
+ pub name : std:: borrow:: Cow < ' a , str > ,
120
+ pub bio : Option < std:: borrow:: Cow < ' a , str > > ,
121
+ }
122
+ impl < ' a > CreateAuthor < ' a > {
123
+ pub const QUERY : & ' static str = r#"-- name: CreateAuthor :one
124
+ INSERT INTO authors (
125
+ name, bio
126
+ ) VALUES (
127
+ $1, $2
128
+ )
129
+ RETURNING id, name, bio"# ;
130
+ }
131
+ impl < ' a > CreateAuthor < ' a > {
132
+ pub async fn query_one (
133
+ & self ,
134
+ client : & impl tokio_postgres:: GenericClient ,
135
+ ) -> Result < CreateAuthorRow , tokio_postgres:: Error > {
136
+ let row = client
137
+ . query_one ( Self :: QUERY , & [ & self . name . as_ref ( ) , & self . bio . as_deref ( ) ] )
138
+ . await ?;
139
+ CreateAuthorRow :: from_row ( & row)
140
+ }
141
+ pub async fn query_opt (
142
+ & self ,
143
+ client : & impl tokio_postgres:: GenericClient ,
144
+ ) -> Result < Option < CreateAuthorRow > , tokio_postgres:: Error > {
145
+ let row = client
146
+ . query_opt ( Self :: QUERY , & [ & self . name . as_ref ( ) , & self . bio . as_deref ( ) ] )
147
+ . await ?;
148
+ match row {
149
+ Some ( ref row) => Ok ( Some ( CreateAuthorRow :: from_row ( row) ?) ) ,
150
+ None => Ok ( None ) ,
151
+ }
152
+ }
80
153
}
81
154
pub const DELETE_AUTHOR : & str = r#"-- name: DeleteAuthor :exec
82
155
DELETE FROM authors
@@ -87,3 +160,20 @@ pub async fn delete_author(
87
160
) -> Result < u64 , tokio_postgres:: Error > {
88
161
client. execute ( DELETE_AUTHOR , & [ & id] ) . await
89
162
}
163
+ #[ derive( Debug ) ]
164
+ pub struct DeleteAuthor {
165
+ pub id : i64 ,
166
+ }
167
+ impl DeleteAuthor {
168
+ pub const QUERY : & ' static str = r#"-- name: DeleteAuthor :exec
169
+ DELETE FROM authors
170
+ WHERE id = $1"# ;
171
+ }
172
+ impl DeleteAuthor {
173
+ pub async fn execute (
174
+ & self ,
175
+ client : & impl tokio_postgres:: GenericClient ,
176
+ ) -> Result < u64 , tokio_postgres:: Error > {
177
+ client. execute ( Self :: QUERY , & [ & self . id ] ) . await
178
+ }
179
+ }
0 commit comments