11use log:: { debug, error, info, warn} ;
2- use rusqlite:: { Connection , Result as SqlResult } ;
32use serialport:: SerialPort ;
43use std:: io:: { Read , Write } ;
5- use std:: sync:: { Arc , Mutex } ;
64use std:: thread;
75use std:: time:: Duration ;
86use thiserror:: Error ;
97
8+ use crate :: cashcode_db:: CashCodeDb ;
9+
1010// protocol constants
1111const COMMAND_POLL : & [ u8 ] = & [ 0x02 , 0x03 , 0x06 , 0x33 , 0xDA , 0x81 ] ;
1212const COMMAND_RESET : & [ u8 ] = & [ 0x02 , 0x03 , 0x06 , 0x30 , 0x41 , 0xB3 ] ;
@@ -97,7 +97,7 @@ impl BillNominal {
9797 }
9898 }
9999
100- fn value ( & self ) -> i32 {
100+ pub fn value ( & self ) -> i32 {
101101 * self as i32
102102 }
103103}
@@ -118,7 +118,7 @@ pub enum BillEvent {
118118pub struct CashCode {
119119 port : Box < dyn SerialPort > ,
120120 stacker_removed : bool ,
121- db : Arc < Mutex < Connection > > ,
121+ db : CashCodeDb ,
122122}
123123
124124impl CashCode {
@@ -130,38 +130,15 @@ impl CashCode {
130130 . open ( ) ?;
131131
132132 info ! ( "opening database: {}" , db_path) ;
133- let db = Connection :: open ( db_path) ?;
134-
135- // initialize database
136- Self :: init_database ( & db) ?;
133+ let db = CashCodeDb :: open ( db_path) ?;
137134
138135 Ok ( CashCode {
139136 port,
140137 stacker_removed : false ,
141- db : Arc :: new ( Mutex :: new ( db ) ) ,
138+ db,
142139 } )
143140 }
144141
145- fn init_database ( db : & Connection ) -> SqlResult < ( ) > {
146- db. execute (
147- "CREATE TABLE IF NOT EXISTS accepted_bills (
148- nominal INTEGER PRIMARY KEY,
149- quantity INTEGER NOT NULL
150- )" ,
151- [ ] ,
152- ) ?;
153-
154- let nominals = [ 1000 , 2000 , 5000 , 10000 , 20000 ] ;
155- for nominal in nominals {
156- db. execute (
157- "INSERT OR IGNORE INTO accepted_bills (nominal, quantity) VALUES (?1, 0)" ,
158- [ nominal] ,
159- ) ?;
160- }
161-
162- Ok ( ( ) )
163- }
164-
165142 fn send_command ( & mut self , command : & [ u8 ] ) -> Result < ( ) , CashCodeError > {
166143 self . port . write_all ( command) ?;
167144 thread:: sleep ( Duration :: from_millis ( 20 ) ) ;
@@ -381,7 +358,7 @@ impl CashCode {
381358
382359 if let Some ( nominal) = BillNominal :: from_code ( nominal_code) {
383360 info ! ( "bill accepted: {} dram" , nominal. value( ) ) ;
384- self . record_bill ( nominal) ?;
361+ self . db . record_bill ( nominal) ?;
385362 Some ( BillEvent :: Accepted ( nominal) )
386363 } else {
387364 warn ! ( "bill accepted with unknown nominal: 0x{:02X}" , nominal_code) ;
@@ -404,41 +381,12 @@ impl CashCode {
404381 Ok ( event)
405382 }
406383
407- fn record_bill ( & self , nominal : BillNominal ) -> Result < ( ) , CashCodeError > {
408- let db = self . db . lock ( ) . unwrap ( ) ;
409- db. execute (
410- "UPDATE accepted_bills SET quantity = quantity + 1 WHERE nominal = ?1" ,
411- [ nominal. value ( ) ] ,
412- ) ?;
413- Ok ( ( ) )
414- }
415-
416384 #[ allow( dead_code) ]
417385 pub fn get_bill_counts ( & self ) -> Result < Vec < ( i32 , i32 ) > , CashCodeError > {
418- let db = self . db . lock ( ) . unwrap ( ) ;
419- let mut stmt =
420- db. prepare ( "SELECT nominal, quantity FROM accepted_bills ORDER BY nominal" ) ?;
421-
422- let rows = stmt. query_map ( [ ] , |row| Ok ( ( row. get ( 0 ) ?, row. get ( 1 ) ?) ) ) ?;
423-
424- let mut results = Vec :: new ( ) ;
425- for row in rows {
426- results. push ( row?) ;
427- }
428-
429- Ok ( results)
386+ self . db . get_bill_counts ( )
430387 }
431388
432389 pub fn get_total_amount ( & self ) -> Result < i32 , CashCodeError > {
433- let db = self . db . lock ( ) . unwrap ( ) ;
434- let total: i32 = db
435- . query_row (
436- "SELECT SUM(nominal * quantity) FROM accepted_bills" ,
437- [ ] ,
438- |row| row. get ( 0 ) ,
439- )
440- . unwrap_or ( 0 ) ;
441-
442- Ok ( total)
390+ self . db . get_total_amount ( )
443391 }
444392}
0 commit comments