first go at db maintenance window, turned off for now
This commit is contained in:
		
							parent
							
								
									141b88ecfd
								
							
						
					
					
						commit
						09801cd00e
					
				|  | @ -695,18 +695,8 @@ class Config: | ||||||
|         try:    db['db-server'] = self.supported_databases[name].db_server |         try:    db['db-server'] = self.supported_databases[name].db_server | ||||||
|         except: pass |         except: pass | ||||||
| 
 | 
 | ||||||
|         if self.supported_databases[name].db_server== DATABASE_TYPE_MYSQL: |         db['db-backend'] = self.get_backend(self.supported_databases[name].db_server) | ||||||
|             db['db-backend'] = 2 | 
 | ||||||
|         elif self.supported_databases[name].db_server== DATABASE_TYPE_POSTGRESQL: |  | ||||||
|             db['db-backend'] = 3 |  | ||||||
|         elif self.supported_databases[name].db_server== DATABASE_TYPE_SQLITE: |  | ||||||
|             db['db-backend'] = 4 |  | ||||||
|             # sqlcoder: this assignment fixes unicode problems for me with sqlite (windows, cp1252) |  | ||||||
|             #           feel free to remove or improve this if you understand the problems |  | ||||||
|             #           better than me (not hard!) |  | ||||||
|             Charset.not_needed1, Charset.not_needed2, Charset.not_needed3 = True, True, True |  | ||||||
|         else: |  | ||||||
|             raise ValueError('Unsupported database backend: %s' % self.supported_databases[name].db_server) |  | ||||||
|         return db |         return db | ||||||
| 
 | 
 | ||||||
|     def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None, |     def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None, | ||||||
|  | @ -726,6 +716,23 @@ class Config: | ||||||
|             if db_type   is not None: self.supported_databases[db_name].dp_type   = db_type |             if db_type   is not None: self.supported_databases[db_name].dp_type   = db_type | ||||||
|         return |         return | ||||||
|      |      | ||||||
|  |     def get_backend(self, name): | ||||||
|  |         """Returns the number of the currently used backend""" | ||||||
|  |         if name == DATABASE_TYPE_MYSQL: | ||||||
|  |             ret = 2 | ||||||
|  |         elif name == DATABASE_TYPE_POSTGRESQL: | ||||||
|  |             ret = 3 | ||||||
|  |         elif name == DATABASE_TYPE_SQLITE: | ||||||
|  |             ret = 4 | ||||||
|  |             # sqlcoder: this assignment fixes unicode problems for me with sqlite (windows, cp1252) | ||||||
|  |             #           feel free to remove or improve this if you understand the problems | ||||||
|  |             #           better than me (not hard!) | ||||||
|  |             Charset.not_needed1, Charset.not_needed2, Charset.not_needed3 = True, True, True | ||||||
|  |         else: | ||||||
|  |             raise ValueError('Unsupported database backend: %s' % self.supported_databases[name].db_server) | ||||||
|  | 
 | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|     def getDefaultSite(self): |     def getDefaultSite(self): | ||||||
|         "Returns first enabled site or None" |         "Returns first enabled site or None" | ||||||
|         for site_name,site in self.supported_sites.iteritems(): |         for site_name,site in self.supported_sites.iteritems(): | ||||||
|  |  | ||||||
|  | @ -226,7 +226,7 @@ class Database: | ||||||
|     # create index indexname on tablename (col); |     # create index indexname on tablename (col); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def __init__(self, c, sql = None):  |     def __init__(self, c, sql = None, autoconnect = True):  | ||||||
|         #log = Configuration.get_logger("logging.conf", "db", log_dir=c.dir_log) |         #log = Configuration.get_logger("logging.conf", "db", log_dir=c.dir_log) | ||||||
|         log.debug("Creating Database instance, sql = %s" % sql) |         log.debug("Creating Database instance, sql = %s" % sql) | ||||||
|         self.config = c |         self.config = c | ||||||
|  | @ -247,41 +247,42 @@ class Database: | ||||||
|         else: |         else: | ||||||
|             self.sql = sql |             self.sql = sql | ||||||
| 
 | 
 | ||||||
|         # connect to db |         if autoconnect: | ||||||
|         self.do_connect(c) |             # connect to db | ||||||
|  |             self.do_connect(c) | ||||||
|              |              | ||||||
|         if self.backend == self.PGSQL: |             if self.backend == self.PGSQL: | ||||||
|             from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE |                 from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE | ||||||
|             #ISOLATION_LEVEL_AUTOCOMMIT     = 0 |                 #ISOLATION_LEVEL_AUTOCOMMIT     = 0 | ||||||
|             #ISOLATION_LEVEL_READ_COMMITTED = 1  |                 #ISOLATION_LEVEL_READ_COMMITTED = 1  | ||||||
|             #ISOLATION_LEVEL_SERIALIZABLE   = 2 |                 #ISOLATION_LEVEL_SERIALIZABLE   = 2 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         if self.backend == self.SQLITE and self.database == ':memory:' and self.wrongDbVersion: |             if self.backend == self.SQLITE and self.database == ':memory:' and self.wrongDbVersion: | ||||||
|             log.info("sqlite/:memory: - creating") |                 log.info("sqlite/:memory: - creating") | ||||||
|             self.recreate_tables() |                 self.recreate_tables() | ||||||
|             self.wrongDbVersion = False |                 self.wrongDbVersion = False | ||||||
| 
 | 
 | ||||||
|         self.pcache      = None     # PlayerId cache |             self.pcache      = None     # PlayerId cache | ||||||
|         self.cachemiss   = 0        # Delete me later - using to count player cache misses |             self.cachemiss   = 0        # Delete me later - using to count player cache misses | ||||||
|         self.cachehit    = 0        # Delete me later - using to count player cache hits |             self.cachehit    = 0        # Delete me later - using to count player cache hits | ||||||
| 
 | 
 | ||||||
|         # config while trying out new hudcache mechanism |             # config while trying out new hudcache mechanism | ||||||
|         self.use_date_in_hudcache = True |             self.use_date_in_hudcache = True | ||||||
| 
 | 
 | ||||||
|         #self.hud_hero_style = 'T'  # Duplicate set of vars just for hero - not used yet. |             #self.hud_hero_style = 'T'  # Duplicate set of vars just for hero - not used yet. | ||||||
|         #self.hud_hero_hands = 2000 # Idea is that you might want all-time stats for others |             #self.hud_hero_hands = 2000 # Idea is that you might want all-time stats for others | ||||||
|         #self.hud_hero_days  = 30   # but last T days or last H hands for yourself |             #self.hud_hero_days  = 30   # but last T days or last H hands for yourself | ||||||
| 
 | 
 | ||||||
|         # vars for hand ids or dates fetched according to above config: |             # vars for hand ids or dates fetched according to above config: | ||||||
|         self.hand_1day_ago = 0             # max hand id more than 24 hrs earlier than now |             self.hand_1day_ago = 0             # max hand id more than 24 hrs earlier than now | ||||||
|         self.date_ndays_ago = 'd000000'    # date N days ago ('d' + YYMMDD) |             self.date_ndays_ago = 'd000000'    # date N days ago ('d' + YYMMDD) | ||||||
|         self.h_date_ndays_ago = 'd000000'  # date N days ago ('d' + YYMMDD) for hero |             self.h_date_ndays_ago = 'd000000'  # date N days ago ('d' + YYMMDD) for hero | ||||||
|         self.date_nhands_ago = {}          # dates N hands ago per player - not used yet |             self.date_nhands_ago = {}          # dates N hands ago per player - not used yet | ||||||
| 
 | 
 | ||||||
|         self.saveActions = False if self.import_options['saveActions'] == False else True |             self.saveActions = False if self.import_options['saveActions'] == False else True | ||||||
| 
 | 
 | ||||||
|         self.connection.rollback()  # make sure any locks taken so far are released |             self.connection.rollback()  # make sure any locks taken so far are released | ||||||
|     #end def __init__ |     #end def __init__ | ||||||
| 
 | 
 | ||||||
|     # could be used by hud to change hud style |     # could be used by hud to change hud style | ||||||
|  | @ -313,7 +314,7 @@ class Database: | ||||||
|         self.__connected = True |         self.__connected = True | ||||||
| 
 | 
 | ||||||
|     def connect(self, backend=None, host=None, database=None, |     def connect(self, backend=None, host=None, database=None, | ||||||
|                 user=None, password=None): |                 user=None, password=None, create=False): | ||||||
|         """Connects a database with the given parameters""" |         """Connects a database with the given parameters""" | ||||||
|         if backend is None: |         if backend is None: | ||||||
|             raise FpdbError('Database backend not defined') |             raise FpdbError('Database backend not defined') | ||||||
|  | @ -384,32 +385,35 @@ class Database: | ||||||
|             #    log.warning("SQLite won't work well without 'sqlalchemy' installed.") |             #    log.warning("SQLite won't work well without 'sqlalchemy' installed.") | ||||||
| 
 | 
 | ||||||
|             if database != ":memory:": |             if database != ":memory:": | ||||||
|                 if not os.path.isdir(self.config.dir_database): |                 if not os.path.isdir(self.config.dir_database) and create: | ||||||
|                     print "Creating directory: '%s'" % (self.config.dir_database) |                     print "Creating directory: '%s'" % (self.config.dir_database) | ||||||
|                     log.info("Creating directory: '%s'" % (self.config.dir_database)) |                     log.info("Creating directory: '%s'" % (self.config.dir_database)) | ||||||
|                     os.mkdir(self.config.dir_database) |                     os.mkdir(self.config.dir_database) | ||||||
|                 database = os.path.join(self.config.dir_database, database) |                 database = os.path.join(self.config.dir_database, database) | ||||||
|             self.db_path = database |             self.db_path = database | ||||||
|             log.info("Connecting to SQLite: %(database)s" % {'database':self.db_path}) |             log.info("Connecting to SQLite: %(database)s" % {'database':self.db_path}) | ||||||
|             self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES ) |             if os.path.exists(database) or create: | ||||||
|             sqlite3.register_converter("bool", lambda x: bool(int(x))) |                 self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES ) | ||||||
|             sqlite3.register_adapter(bool, lambda x: "1" if x else "0") |                 sqlite3.register_converter("bool", lambda x: bool(int(x))) | ||||||
|             self.connection.create_function("floor", 1, math.floor) |                 sqlite3.register_adapter(bool, lambda x: "1" if x else "0") | ||||||
|             tmp = sqlitemath() |                 self.connection.create_function("floor", 1, math.floor) | ||||||
|             self.connection.create_function("mod", 2, tmp.mod) |                 tmp = sqlitemath() | ||||||
|             if use_numpy: |                 self.connection.create_function("mod", 2, tmp.mod) | ||||||
|                 self.connection.create_aggregate("variance", 1, VARIANCE) |                 if use_numpy: | ||||||
|  |                     self.connection.create_aggregate("variance", 1, VARIANCE) | ||||||
|  |                 else: | ||||||
|  |                     log.warning("Some database functions will not work without NumPy support") | ||||||
|  |                 self.cursor = self.connection.cursor() | ||||||
|  |                 self.cursor.execute('PRAGMA temp_store=2')  # use memory for temp tables/indexes | ||||||
|  |                 self.cursor.execute('PRAGMA synchronous=0') # don't wait for file writes to finish | ||||||
|             else: |             else: | ||||||
|                 log.warning("Some database functions will not work without NumPy support") |                 raise FpdbError("sqlite database "+database+" does not exist") | ||||||
|             self.cursor = self.connection.cursor() |  | ||||||
|             self.cursor.execute('PRAGMA temp_store=2')  # use memory for temp tables/indexes |  | ||||||
|             self.cursor.execute('PRAGMA synchronous=0') # don't wait for file writes to finish |  | ||||||
|         else: |         else: | ||||||
|             raise FpdbError("unrecognised database backend:"+backend) |             raise FpdbError("unrecognised database backend:"+str(backend)) | ||||||
| 
 | 
 | ||||||
|         self.cursor = self.connection.cursor() |         self.cursor = self.connection.cursor() | ||||||
|         self.cursor.execute(self.sql.query['set tx level']) |         self.cursor.execute(self.sql.query['set tx level']) | ||||||
|         self.check_version(database=database, create=True) |         self.check_version(database=database, create=create) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     def check_version(self, database, create): |     def check_version(self, database, create): | ||||||
|  |  | ||||||
|  | @ -97,6 +97,7 @@ except: | ||||||
| 
 | 
 | ||||||
| import GuiPrefs | import GuiPrefs | ||||||
| import GuiLogView | import GuiLogView | ||||||
|  | import GuiDatabase | ||||||
| import GuiBulkImport | import GuiBulkImport | ||||||
| import GuiPlayerStats | import GuiPlayerStats | ||||||
| import GuiPositionalStats | import GuiPositionalStats | ||||||
|  | @ -288,10 +289,31 @@ class fpdb: | ||||||
| 
 | 
 | ||||||
|         dia.destroy() |         dia.destroy() | ||||||
| 
 | 
 | ||||||
|     def dia_create_del_database(self, widget, data=None): |     def dia_maintain_dbs(self, widget, data=None): | ||||||
|         self.warning_box("Unimplemented: Create/Delete Database") |         self.warning_box("Unimplemented: Maintain Databases") | ||||||
|         self.obtain_global_lock() |         return | ||||||
|         self.release_global_lock() |         if len(self.tab_names) == 1: | ||||||
|  |             if self.obtain_global_lock():  # returns true if successful | ||||||
|  |                 # only main tab has been opened, open dialog | ||||||
|  |                 dia = gtk.Dialog("Maintain Databases", | ||||||
|  |                                  self.window, | ||||||
|  |                                  gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, | ||||||
|  |                                  (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, | ||||||
|  |                                   gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) | ||||||
|  |                 dia.set_default_size(700, 320) | ||||||
|  | 
 | ||||||
|  |                 prefs = GuiDatabase.GuiDatabase(self.config, self.window, dia) | ||||||
|  |                 response = dia.run() | ||||||
|  |                 if response == gtk.RESPONSE_ACCEPT: | ||||||
|  |                     # save updated config | ||||||
|  |                     self.config.save() | ||||||
|  | 
 | ||||||
|  |                 self.release_global_lock() | ||||||
|  | 
 | ||||||
|  |             dia.destroy() | ||||||
|  |         else: | ||||||
|  |             self.warning_box("Cannot open Database Maintenance window because " | ||||||
|  |                              + "other windows have been opened. Re-start fpdb to use this option.") | ||||||
| 
 | 
 | ||||||
|     def dia_create_del_user(self, widget, data=None): |     def dia_create_del_user(self, widget, data=None): | ||||||
|         self.warning_box("Unimplemented: Create/Delete user") |         self.warning_box("Unimplemented: Create/Delete user") | ||||||
|  | @ -620,7 +642,7 @@ class fpdb: | ||||||
|                   <menuitem action="tableviewer"/> |                   <menuitem action="tableviewer"/> | ||||||
|                 </menu> |                 </menu> | ||||||
|                 <menu action="database"> |                 <menu action="database"> | ||||||
|                   <menuitem action="createdb"/> |                   <menuitem action="maintaindbs"/> | ||||||
|                   <menuitem action="createuser"/> |                   <menuitem action="createuser"/> | ||||||
|                   <menuitem action="createtabs"/> |                   <menuitem action="createtabs"/> | ||||||
|                   <menuitem action="rebuildhudcache"/> |                   <menuitem action="rebuildhudcache"/> | ||||||
|  | @ -663,7 +685,7 @@ class fpdb: | ||||||
|                                  ('sessionreplay', None, '_Session Replayer (todo)', None, 'Session Replayer (todo)', self.not_implemented), |                                  ('sessionreplay', None, '_Session Replayer (todo)', None, 'Session Replayer (todo)', self.not_implemented), | ||||||
|                                  ('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer), |                                  ('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer), | ||||||
|                                  ('database', None, '_Database'), |                                  ('database', None, '_Database'), | ||||||
|                                  ('createdb', None, 'Create or Delete _Database (todo)', None, 'Create or Delete Database', self.dia_create_del_database), |                                  ('maintaindbs', None, '_Maintain Databases (todo)', None, 'Maintain Databases', self.dia_maintain_dbs), | ||||||
|                                  ('createuser', None, 'Create or Delete _User (todo)', None, 'Create or Delete User', self.dia_create_del_user), |                                  ('createuser', None, 'Create or Delete _User (todo)', None, 'Create or Delete User', self.dia_create_del_user), | ||||||
|                                  ('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables), |                                  ('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables), | ||||||
|                                  ('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache), |                                  ('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache), | ||||||
|  | @ -685,7 +707,7 @@ class fpdb: | ||||||
|         window.add_accel_group(accel_group) |         window.add_accel_group(accel_group) | ||||||
|         return menubar |         return menubar | ||||||
| 
 | 
 | ||||||
|     def load_profile(self): |     def load_profile(self, create_db = False): | ||||||
|         """Loads profile from the provided path name.""" |         """Loads profile from the provided path name.""" | ||||||
|         self.config = Configuration.Config(file=options.config, dbname=options.dbname) |         self.config = Configuration.Config(file=options.config, dbname=options.dbname) | ||||||
|         if self.config.file_error: |         if self.config.file_error: | ||||||
|  | @ -911,7 +933,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") | ||||||
|         self.tab_main_help(None, None) |         self.tab_main_help(None, None) | ||||||
| 
 | 
 | ||||||
|         self.window.show() |         self.window.show() | ||||||
|         self.load_profile() |         self.load_profile(create_db = True) | ||||||
| 
 | 
 | ||||||
|         if not options.errorsToConsole: |         if not options.errorsToConsole: | ||||||
|             fileName = os.path.join(self.config.dir_log, 'fpdb-errors.txt') |             fileName = os.path.join(self.config.dir_log, 'fpdb-errors.txt') | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user