Exemple #1
0
    def __init__(self, controller, db_dir, db_name):

        if HydrusPaths.GetFreeSpace(db_dir) < 500 * 1048576:

            raise Exception(
                'Sorry, it looks like the db partition has less than 500MB, please free up some space.'
            )

        HydrusDBBase.DBBase.__init__(self)

        self._controller = controller
        self._db_dir = db_dir
        self._db_name = db_name

        self._modules = []

        HydrusDBBase.TemporaryIntegerTableNameCache()

        self._ssl_cert_filename = '{}.crt'.format(self._db_name)
        self._ssl_key_filename = '{}.key'.format(self._db_name)

        self._ssl_cert_path = os.path.join(self._db_dir,
                                           self._ssl_cert_filename)
        self._ssl_key_path = os.path.join(self._db_dir, self._ssl_key_filename)

        main_db_filename = db_name

        if not main_db_filename.endswith('.db'):

            main_db_filename += '.db'

        self._db_filenames = {}

        self._db_filenames['main'] = main_db_filename

        self._durable_temp_db_filename = db_name + '.temp.db'

        durable_temp_db_path = os.path.join(self._db_dir,
                                            self._durable_temp_db_filename)

        if os.path.exists(durable_temp_db_path):

            HydrusPaths.DeletePath(durable_temp_db_path)

            wal_lad = durable_temp_db_path + '-wal'

            if os.path.exists(wal_lad):

                HydrusPaths.DeletePath(wal_lad)

            shm_lad = durable_temp_db_path + '-shm'

            if os.path.exists(shm_lad):

                HydrusPaths.DeletePath(shm_lad)

            HydrusData.Print(
                'Found and deleted the durable temporary database on boot. The last exit was probably not clean.'
            )

        self._InitExternalDatabases()

        self._is_first_start = False
        self._is_db_updated = False
        self._local_shutdown = False
        self._pause_and_disconnect = False
        self._loop_finished = False
        self._ready_to_serve_requests = False
        self._could_not_initialise = False

        self._jobs = queue.Queue()

        self._currently_doing_job = False
        self._current_status = ''
        self._current_job_name = ''

        self._db = None
        self._is_connected = False

        self._cursor_transaction_wrapper = None

        if os.path.exists(
                os.path.join(self._db_dir, self._db_filenames['main'])):

            # open and close to clean up in case last session didn't close well

            self._InitDB()
            self._CloseDBConnection()

        self._InitDB()

        (version, ) = self._Execute('SELECT version FROM version;').fetchone()

        if version > HC.SOFTWARE_VERSION:

            self._ReportOverupdatedDB(version)

        if version < (HC.SOFTWARE_VERSION - 15):

            self._ReportUnderupdatedDB(version)

        if version < HC.SOFTWARE_VERSION - 50:

            raise Exception('Your current database version of hydrus ' +
                            str(version) +
                            ' is too old for this software version ' +
                            str(HC.SOFTWARE_VERSION) +
                            ' to update. Please try updating with version ' +
                            str(version + 45) + ' or earlier first.')

        self._RepairDB(version)

        while version < HC.SOFTWARE_VERSION:

            time.sleep(self.UPDATE_WAIT)

            try:

                self._cursor_transaction_wrapper.BeginImmediate()

            except Exception as e:

                raise HydrusExceptions.DBAccessException(str(e))

            try:

                self._UpdateDB(version)

                self._cursor_transaction_wrapper.Commit()

                self._is_db_updated = True

            except:

                e = Exception('Updating the ' + self._db_name +
                              ' db to version ' + str(version + 1) +
                              ' caused this error:' + os.linesep +
                              traceback.format_exc())

                try:

                    self._cursor_transaction_wrapper.Rollback()

                except Exception as rollback_e:

                    HydrusData.Print(
                        'When the update failed, attempting to rollback the database failed.'
                    )

                    HydrusData.PrintException(rollback_e)

                raise e

            (version,
             ) = self._Execute('SELECT version FROM version;').fetchone()

        self._CloseDBConnection()

        self._controller.CallToThreadLongRunning(self.MainLoop)

        while not self._ready_to_serve_requests:

            time.sleep(0.1)

            if self._could_not_initialise:

                raise Exception(
                    'Could not initialise the db! Error written to the log!')
Exemple #2
0
 def __init__( self, controller, db_dir, db_name ):
     
     if HydrusPaths.GetFreeSpace( db_dir ) < 500 * 1048576:
         
         raise Exception( 'Sorry, it looks like the db partition has less than 500MB, please free up some space.' )
         
     
     self._controller = controller
     self._db_dir = db_dir
     self._db_name = db_name
     
     self._transaction_started = 0
     self._in_transaction = False
     self._transaction_contains_writes = False
     
     self._connection_timestamp = 0
     
     main_db_filename = db_name
     
     if not main_db_filename.endswith( '.db' ):
         
         main_db_filename += '.db'
         
     
     self._db_filenames = {}
     
     self._db_filenames[ 'main' ] = main_db_filename
     
     self._durable_temp_db_filename = db_name + '.temp.db'
     
     self._InitExternalDatabases()
     
     if distutils.version.LooseVersion( sqlite3.sqlite_version ) < distutils.version.LooseVersion( '3.11.0' ):
         
         self._fast_big_transaction_wal = False
         
     else:
         
         self._fast_big_transaction_wal = True
         
     
     self._is_first_start = False
     self._is_db_updated = False
     self._local_shutdown = False
     self._pause_and_disconnect = False
     self._loop_finished = False
     self._ready_to_serve_requests = False
     self._could_not_initialise = False
     
     self._jobs = queue.Queue()
     self._pubsubs = []
     
     self._currently_doing_job = False
     self._current_status = ''
     self._current_job_name = ''
     
     self._db = None
     self._c = None
     
     if os.path.exists( os.path.join( self._db_dir, self._db_filenames[ 'main' ] ) ):
         
         # open and close to clean up in case last session didn't close well
         
         self._InitDB()
         self._CloseDBCursor()
         
     
     self._InitDB()
     
     self._RepairDB()
     
     ( version, ) = self._c.execute( 'SELECT version FROM version;' ).fetchone()
     
     if version > HC.SOFTWARE_VERSION:
         
         self._ReportOverupdatedDB( version )
         
     
     if version < ( HC.SOFTWARE_VERSION - 15 ):
         
         self._ReportUnderupdatedDB( version )
         
     
     if version < HC.SOFTWARE_VERSION - 50:
         
         raise Exception( 'Your current database version of hydrus ' + str( version ) + ' is too old for this software version ' + str( HC.SOFTWARE_VERSION ) + ' to update. Please try updating with version ' + str( version + 45 ) + ' or earlier first.' )
         
     
     while version < HC.SOFTWARE_VERSION:
         
         time.sleep( self.UPDATE_WAIT )
         
         try:
             
             self._BeginImmediate()
             
         except Exception as e:
             
             raise HydrusExceptions.DBAccessException( str( e ) )
             
         
         try:
             
             self._UpdateDB( version )
             
             self._Commit()
             
             self._is_db_updated = True
             
         except:
             
             e = Exception( 'Updating the ' + self._db_name + ' db to version ' + str( version + 1 ) + ' caused this error:' + os.linesep + traceback.format_exc() )
             
             try:
                 
                 self._Rollback()
                 
             except Exception as rollback_e:
                 
                 HydrusData.Print( 'When the update failed, attempting to rollback the database failed.' )
                 
                 HydrusData.PrintException( rollback_e )
                 
             
             raise e
             
         
         ( version, ) = self._c.execute( 'SELECT version FROM version;' ).fetchone()
         
     
     self._CloseDBCursor()
     
     self._controller.CallToThreadLongRunning( self.MainLoop )
     
     while not self._ready_to_serve_requests:
         
         time.sleep( 0.1 )
         
         if self._could_not_initialise:
             
             raise Exception( 'Could not initialise the db! Error written to the log!' )
Exemple #3
0
def CheckHasSpaceForDBTransaction(db_dir, num_bytes):

    if HG.no_db_temp_files:

        space_needed = int(num_bytes * 1.1)

        approx_available_memory = psutil.virtual_memory().available * 4 / 5

        if approx_available_memory < num_bytes:

            raise Exception(
                'I believe you need about ' +
                HydrusData.ToHumanBytes(space_needed) +
                ' available memory, since you are running in no_db_temp_files mode, but you only seem to have '
                + HydrusData.ToHumanBytes(approx_available_memory) + '.')

        db_disk_free_space = HydrusPaths.GetFreeSpace(db_dir)

        if db_disk_free_space < space_needed:

            raise Exception(
                'I believe you need about ' +
                HydrusData.ToHumanBytes(space_needed) +
                ' on your db\'s disk partition, but you only seem to have ' +
                HydrusData.ToHumanBytes(db_disk_free_space) + '.')

    else:

        temp_dir = HydrusTemp.GetCurrentTempDir()

        temp_disk_free_space = HydrusPaths.GetFreeSpace(temp_dir)

        temp_and_db_on_same_device = HydrusPaths.GetDevice(
            temp_dir) == HydrusPaths.GetDevice(db_dir)

        if temp_and_db_on_same_device:

            space_needed = int(num_bytes * 2.2)

            if temp_disk_free_space < space_needed:

                raise Exception(
                    'I believe you need about ' +
                    HydrusData.ToHumanBytes(space_needed) +
                    ' on your db\'s disk partition, which I think also holds your temporary path, but you only seem to have '
                    + HydrusData.ToHumanBytes(temp_disk_free_space) + '.')

        else:

            space_needed = int(num_bytes * 1.1)

            if temp_disk_free_space < space_needed:

                raise Exception(
                    'I believe you need about ' +
                    HydrusData.ToHumanBytes(space_needed) +
                    ' on your temporary path\'s disk partition, which I think is '
                    + temp_dir + ', but you only seem to have ' +
                    HydrusData.ToHumanBytes(temp_disk_free_space) + '.')

            db_disk_free_space = HydrusPaths.GetFreeSpace(db_dir)

            if db_disk_free_space < space_needed:

                raise Exception(
                    'I believe you need about ' +
                    HydrusData.ToHumanBytes(space_needed) +
                    ' on your db\'s disk partition, but you only seem to have '
                    + HydrusData.ToHumanBytes(db_disk_free_space) + '.')