mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-04 03:27:00 -05:00 
			
		
		
		
	Add a lock to allow plugins to sync access to the Kobo db
This commit is contained in:
		
							parent
							
								
									7aa9d1d7fc
								
							
						
					
					
						commit
						05bc7e966e
					
				@ -4,12 +4,17 @@
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
from contextlib import closing, suppress
 | 
					from contextlib import closing, suppress
 | 
				
			||||||
 | 
					from threading import RLock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import apsw
 | 
					import apsw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from calibre.prints import debug_print
 | 
					from calibre.prints import debug_print
 | 
				
			||||||
from calibre.ptempfile import PersistentTemporaryFile, TemporaryDirectory
 | 
					from calibre.ptempfile import PersistentTemporaryFile, TemporaryDirectory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Any plugins not running in the device thread must acquire this lock before
 | 
				
			||||||
 | 
					# trying to access the Kobo database.
 | 
				
			||||||
 | 
					kobo_db_lock = RLock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def row_factory(cursor: apsw.Cursor, row):
 | 
					def row_factory(cursor: apsw.Cursor, row):
 | 
				
			||||||
    return {k[0]: row[i] for i, k in enumerate(cursor.getdescription())}
 | 
					    return {k[0]: row[i] for i, k in enumerate(cursor.getdescription())}
 | 
				
			||||||
@ -68,14 +73,18 @@ class Database:
 | 
				
			|||||||
                raise
 | 
					                raise
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __enter__(self) -> apsw.Connection:
 | 
					    def __enter__(self) -> apsw.Connection:
 | 
				
			||||||
 | 
					        kobo_db_lock.acquire()
 | 
				
			||||||
        self.conn = apsw.Connection(self.dbpath)
 | 
					        self.conn = apsw.Connection(self.dbpath)
 | 
				
			||||||
        if self.use_row_factory:
 | 
					        if self.use_row_factory:
 | 
				
			||||||
            self.conn.setrowtrace(row_factory)
 | 
					            self.conn.setrowtrace(row_factory)
 | 
				
			||||||
        return self.conn.__enter__()
 | 
					        return self.conn.__enter__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __exit__(self, exc_type, exc_value, tb) -> bool | None:
 | 
					    def __exit__(self, exc_type, exc_value, tb) -> bool | None:
 | 
				
			||||||
        with closing(self.conn):
 | 
					        try:
 | 
				
			||||||
            suppress_exception = self.conn.__exit__(exc_type, exc_value, tb)
 | 
					            with closing(self.conn):
 | 
				
			||||||
            if self.needs_copy and (suppress_exception or (exc_type is None and exc_value is None and tb is None)):
 | 
					                suppress_exception = self.conn.__exit__(exc_type, exc_value, tb)
 | 
				
			||||||
                copy_db(self.conn, self.path_on_device)
 | 
					                if self.needs_copy and (suppress_exception or (exc_type is None and exc_value is None and tb is None)):
 | 
				
			||||||
 | 
					                    copy_db(self.conn, self.path_on_device)
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            kobo_db_lock.release()
 | 
				
			||||||
        return suppress_exception
 | 
					        return suppress_exception
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user