@@ -2,7 +2,7 @@ use diesel::prelude::*;
2
2
use diesel:: sqlite:: { Sqlite , SqliteConnection } ;
3
3
use diesel_async:: async_connection_wrapper:: AsyncConnectionWrapper ;
4
4
use diesel_async:: sync_connection_wrapper:: SyncConnectionWrapper ;
5
- use diesel_async:: { AsyncConnection , RunQueryDsl , SimpleAsyncConnection } ;
5
+ use diesel_async:: { AsyncConnection , RunQueryDsl } ;
6
6
use diesel_migrations:: { embed_migrations, EmbeddedMigrations , MigrationHarness } ;
7
7
8
8
// ordinary diesel model setup
@@ -15,7 +15,7 @@ table! {
15
15
}
16
16
17
17
#[ allow( dead_code) ]
18
- #[ derive( Debug , Queryable , Selectable ) ]
18
+ #[ derive( Debug , Queryable , QueryableByName , Selectable ) ]
19
19
#[ diesel( table_name = users) ]
20
20
struct User {
21
21
id : i32 ,
47
47
. map_err ( |e| Box :: new ( e) as Box < dyn std:: error:: Error > )
48
48
}
49
49
50
+ async fn transaction (
51
+ async_conn : & mut SyncConnectionWrapper < InnerConnection > ,
52
+ old_name : & str ,
53
+ new_name : & str ,
54
+ ) -> Result < Vec < User > , diesel:: result:: Error > {
55
+ async_conn
56
+ . transaction :: < Vec < User > , diesel:: result:: Error , _ > ( |c| {
57
+ Box :: pin ( async {
58
+ if old_name. is_empty ( ) {
59
+ Ok ( Vec :: new ( ) )
60
+ } else {
61
+ diesel:: update ( users:: table. filter ( users:: name. eq ( old_name) ) )
62
+ . set ( users:: name. eq ( new_name) )
63
+ . load ( c)
64
+ . await
65
+ }
66
+ } )
67
+ } )
68
+ . await
69
+ }
70
+
50
71
#[ tokio:: main]
51
72
async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
52
73
let db_url = std:: env:: var ( "DATABASE_URL" ) . expect ( "Env var `DATABASE_URL` not set" ) ;
@@ -57,10 +78,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
57
78
58
79
let mut sync_wrapper: SyncConnectionWrapper < InnerConnection > = establish ( & db_url) . await ?;
59
80
60
- sync_wrapper. batch_execute ( "DELETE FROM users" ) . await ?;
81
+ diesel:: delete ( users:: table)
82
+ . execute ( & mut sync_wrapper)
83
+ . await ?;
61
84
62
- sync_wrapper
63
- . batch_execute ( "INSERT INTO users(id, name) VALUES (3, 'toto')" )
85
+ diesel:: insert_into ( users:: table)
86
+ . values ( ( users:: id. eq ( 3 ) , users:: name. eq ( "toto" ) ) )
87
+ . execute ( & mut sync_wrapper)
64
88
. await ?;
65
89
66
90
let data: Vec < User > = users:: table
@@ -86,5 +110,28 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
86
110
. await ?;
87
111
println ! ( "{data:?}" ) ;
88
112
113
+ // a quick test to check if we correctly handle transactions
114
+ let mut conn_a: SyncConnectionWrapper < InnerConnection > = establish ( & db_url) . await ?;
115
+ let mut conn_b: SyncConnectionWrapper < InnerConnection > = establish ( & db_url) . await ?;
116
+
117
+ let handle_1 = tokio:: spawn ( async move {
118
+ loop {
119
+ let changed = transaction ( & mut conn_a, "iLuke" , "JustLuke" ) . await ;
120
+ println ! ( "Changed {changed:?}" ) ;
121
+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) ;
122
+ }
123
+ } ) ;
124
+
125
+ let handle_2 = tokio:: spawn ( async move {
126
+ loop {
127
+ let changed = transaction ( & mut conn_b, "JustLuke" , "iLuke" ) . await ;
128
+ println ! ( "Changed {changed:?}" ) ;
129
+ std:: thread:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) ;
130
+ }
131
+ } ) ;
132
+
133
+ let _ = handle_2. await ;
134
+ let _ = handle_1. await ;
135
+
89
136
Ok ( ( ) )
90
137
}
0 commit comments