def db_save_setting(parameter, value): """ Save Setting to DB. :param parameter: PARAMETER to match :param value: Value to save as Str :return: True if saved """ id_query = Settings.select().where(Settings.parameter == parameter) if not id_query.exists(): Settings.create(parameter=parameter) setting = id_query.get() setting.value = str(value) # Handle a BusyError attempting to write to Settings by retrying up to five times. n_retries = 0 max_retries = 5 while True: try: setting.save() break except BusyError as be: n_retries += 1 if n_retries > max_retries: raise be sleep_time_secs = 0.1 * n_retries time.sleep(sleep_time_secs) # Don't log at INFO level or above - these are typically written to # OPTECS_LOG_MESSAGES table, adding to database contention. logging.debug(f'Trip.save() Try#{n_retries} failed w/BusyError. " +' f'Sleeping {sleep_time_secs} seconds before retrying.') logging.debug('Save ' + parameter + ' -> ' + str(value)) return True
def db_sync_transaction_id(self, transaction_id): try: last_id = Settings.get(Settings.parameter == 'last_db_transaction') last_id.value = transaction_id last_id.save() except Settings.DoesNotExist: new_setting = Settings.create(parameter='last_db_transaction', value=transaction_id) new_setting.save()
def getset_setting(parm_name, default_val): """ Get parm_name setting from SETTINGS table. If setting not in SETTINGS, use default_val. Side-effect: also add default_val to SETTINGS table. """ fr_query = Settings.select().where(Settings.parameter == parm_name) if not fr_query.exists(): Settings.create(parameter=parm_name, value=default_val) return fr_query.get().value
def clear_setting(setting_name): """ Delete setting from SETTINGS @param setting_name: e.g. 'current_user_id' @return: True or None """ try: Settings.get(Settings.parameter == setting_name).delete_instance() return True except Settings.DoesNotExist: return None
def _update_backup_time(self): """ Set most recent backup time to now. @return: """ try: last_sync = Settings.get(Settings.parameter == 'last_backup_time') last_sync.value = arrow.now() last_sync.save() except Settings.DoesNotExist: new_setting = Settings.create(parameter='last_backup_time', value=arrow.now()) new_setting.save() self.lastBackupTimeChanged.emit()
def test_entry_from_db_is_read(self): # Get the current entry, if any, ready to restore at conclusion select_q = Settings.select().where( Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME) orig_list = json.loads(select_q.get().value) self._logger.debug("Orig list = {}".format(orig_list)) test_value = None test_candidates = ('NSCC', 'XYZA', 'XXXX' ) # Unlikely real catch category codes for candidate_test_value in test_candidates: if candidate_test_value not in orig_list: test_value = candidate_test_value break errFmtStr = "Unexpectedly, every value in test value list ({}) was in orig. list" self.assertIsNotNone(test_value, errFmtStr.format(test_candidates)) self._logger.info("Adding {} to value field.".format(test_value)) # Add a catch category code to the db entry test_list = orig_list.copy() test_list.append(test_value) test_list_as_json = json.dumps(test_list) fr_update = Settings.update(value=test_list_as_json).where( Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME) fr_update.execute() # Test that newly instantiated class returns list with new entry. Three parts: # 1. Check that the db has the right updated list fr_query = Settings.select().where( Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME) updated_list = json.loads(fr_query.get().value) self.assertEqual(test_list, updated_list) self._logger.debug("updated_list = {}".format(test_list)) self.assertIsNotNone(updated_list) # 2. Verify that the pre-existing frequent catch category code does NOT get updated value - # that it doesn't do a re-pull from the db on every get of its property self.assertNotIn(test_value, self.tfcc.catch_category_codes) # 3. Instantiate a new copy of frequent catch_category_codes and verify it DOES have the # new value in the list. newtfcc = TrawlFrequentCatchCategories( self.TEST_SETTINGS_PARAMETER_NAME) self.assertIn(test_value, newtfcc.catch_category_codes)
def _insert_default_test_record(self): test_list_as_json = json.dumps(TrawlFrequentCatchCategories. DEFAULT_TRAWL_FREQUENT_CATCH_CATEGORIES) self._logger.debug( "Default test list as JSON = {}".format(test_list_as_json)) insert_q = Settings.insert(parameter=self.TEST_SETTINGS_PARAMETER_NAME, value=test_list_as_json) insert_q.execute()
def db_sync_transaction_id(self): # TODO Temporarily always get all transactions. For production, comment out line below. # return self.default_transaction_id try: last_id = Settings.get(Settings.parameter == 'last_db_transaction') return last_id.value except Settings.DoesNotExist: return self.default_transaction_id
def get_setting(setting_name, fallback_value=None): """ Load setting from SETTINGS @param setting_name: e.g. 'current_user_id' @param fallback_value: value to return if value not found @return: value or fallback_value or None """ try: return Settings.get(Settings.parameter == setting_name).value except Settings.DoesNotExist: return fallback_value
def lastBackupTime(self): """ Returns string representation of last DB backup. @return: string value """ try: last_sync = Settings.get(Settings.parameter == 'last_backup_time') last_time = arrow.get(last_sync.value) return last_time.humanize() except Settings.DoesNotExist: return 'Never'
def get_or_set_setting(setting_name, default_value): """ Load setting from SETTINGS. If not found, then set to default_value @param setting_name: e.g. 'current_user_id' @param default_value: value to set if setting not found @return: found value or default_value """ try: return Settings.get(Settings.parameter == setting_name).value except Settings.DoesNotExist: ObserverDBUtil.db_save_setting(setting_name, default_value) return default_value
def end_trip(self): """ End current trip - TODO: other DB lock function to lock trip(TODO) :return: """ self._logger.info("User ended trip # {}".format(self.tripId)) self._current_trip = None self._certs_model.clear( ) # FIELD-2084: prevent permit to carry to next trip self.tripsChanged.emit() self.tripIdChanged.emit('') self.currentVesselNameChanged.emit('') # remove current trip ID setting from DB try: tripnum = Settings.get(Settings.parameter == 'trip_number') tripnum.delete_instance() except Settings.DoesNotExist as e: self._logger.error( 'Could not delete trip_number setting: {}'.format(e))
def _delete_test_record(self): """ Remove the test setting.""" delete_q = Settings.delete().where( Settings.parameter == self.TEST_SETTINGS_PARAMETER_NAME) delete_q.execute()
def db_load_setting(parameter): try: return Settings.get(Settings.parameter == parameter).value except Settings.DoesNotExist as e: logging.info('DB Setting does not exist: ' + parameter) return None
def __init__(self, db): super().__init__() self._logger = logging.getLogger(__name__) self._db = db # These data will also get saved into (new) Trips cs_query = Settings.select().where(Settings.parameter == 'catch_share') if not cs_query.exists(): Settings.create(parameter='catch_share', value='TRUE') self._catchshare = cs_query.get() gt_query = Settings.select().where(Settings.parameter == 'gear_type') if not gt_query.exists(): Settings.create(parameter='gear_type', value='TRUE') self._geartype_trawl_default = gt_query.get() self._users = ObserverUsers() self._trips = ObserverTrip() self._hauls = Hauls(db=db) self._sets = Sets(db=db) self._catches = ObserverCatches(db=db) self._current_cc = None self._current_cc_name = "" # for display self._current_spec_name = "" # for display fr_query = Settings.select().where(Settings.parameter == 'first_run') if not fr_query.exists(): Settings.create(parameter='first_run', value='TRUE') self._firstrun = fr_query.get() cu_query = Settings.select().where(Settings.parameter == 'current_user') if not cu_query.exists(): Settings.create(parameter='current_user') self._current_user = cu_query.get() cu_query = Settings.select().where(Settings.parameter == 'current_user_id') if not cu_query.exists(): Settings.create(parameter='current_user_id') self._current_user_id = cu_query.get() # Type max depth as integer self._trawl_max_depth_fathoms = int(self.getset_setting( 'trawl_max_depth_fathoms', DefaultDefaultSettings.trawl_max_depth_fathoms)) self.trawlMaxDepthFathomsChanged.emit(self._trawl_max_depth_fathoms) # Confirmation-required basket weight, typed as integer self._trawl_confirm_basket_weight_lbs = int(self.getset_setting( 'trawl_confirm_basket_weight_lbs', DefaultDefaultSettings.trawl_confirm_basket_weight_lbs)) self.trawlConfirmBasketWeightLbsChanged.emit(self._trawl_confirm_basket_weight_lbs) # Max basket weight as integer, typed as integer self._trawl_max_basket_weight_lbs = int(self.getset_setting( 'trawl_max_basket_weight_lbs', DefaultDefaultSettings.trawl_max_basket_weight_lbs)) self.trawlMaxBasketWeightLbsChanged.emit(self._trawl_max_basket_weight_lbs) # Minimum and maximum degrees latitude as integer. # No emits necessary: this value will not change during a run. self._trawl_min_latitude_degrees = int(self.getset_setting( 'trawl_minimum_latitude_degrees', DefaultDefaultSettings.trawl_minimum_latitude_degrees)) self._trawl_max_latitude_degrees = int(self.getset_setting( 'trawl_maximum_latitude_degrees', DefaultDefaultSettings.trawl_maximum_latitude_degrees)) # DB Backup Thread self._backup_thread = QThread() self._backup_worker = None self._comments_all = '' self._comments_trip = '' self._comments_haul = dict() self._db_formatted_comments_trip = '' self._db_formatted_comments_haul = dict() self.currentTripId = ObserverDBUtil.db_load_setting('trip_number') # Current Trip ID if set self.update_comments() self._catches.retainedCatchWeightChanged.connect(self.update_wm5_catch_weights) # ret. catch changes --> WM5 updates self._hauls.otcWeightChanged.connect(self.update_wm5_catch_weights) # otc changes --> WM5 updates