~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/canonical/database/sqlbase.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-09-13 08:44:05 UTC
  • mfrom: (7675.1045.788 db-devel)
  • Revision ID: launchpad@pqm.canonical.com-20110913084405-t6b62nt98rcmp6wg
Merging db-stable at revno 10971

Show diffs side-by-side

added added

removed removed

Lines of Context:
291
291
                             "directly instantiated.")
292
292
 
293
293
    @classmethod
294
 
    def _get_zopeless_connection_config(self, dbname, dbhost):
295
 
        # This method exists for testability.
296
 
 
297
 
        # This is only used by scripts, so we must connect to the read-write
298
 
        # DB here -- that's why we use rw_main_master directly.
299
 
        from canonical.database.postgresql import ConnectionString
300
 
        main_connection_string = ConnectionString(dbconfig.rw_main_master)
301
 
 
302
 
        # Override dbname and dbhost in the connection string if they
303
 
        # have been passed in.
304
 
        if dbname is None:
305
 
            dbname = main_connection_string.dbname
306
 
        else:
307
 
            main_connection_string.dbname = dbname
308
 
 
309
 
        if dbhost is None:
310
 
            dbhost = main_connection_string.host
311
 
        else:
312
 
            main_connection_string.host = dbhost
313
 
 
314
 
        return str(main_connection_string), dbname, dbhost
315
 
 
316
 
    @classmethod
317
 
    def initZopeless(cls, dbname=None, dbhost=None, dbuser=None,
318
 
                     isolation=ISOLATION_LEVEL_DEFAULT):
319
 
 
320
 
        main_connection_string, dbname, dbhost = (
321
 
            cls._get_zopeless_connection_config(dbname, dbhost))
322
 
 
323
 
        assert dbuser is not None, '''
324
 
            dbuser is now required. All scripts must connect as unique
325
 
            database users.
326
 
            '''
 
294
    def initZopeless(cls, dbuser=None, isolation=ISOLATION_LEVEL_DEFAULT):
 
295
        if dbuser is None:
 
296
            raise AssertionError(
 
297
                "dbuser is now required. All scripts must connect as unique "
 
298
                "database users.")
327
299
 
328
300
        isolation_level = {
329
301
            ISOLATION_LEVEL_AUTOCOMMIT: 'autocommit',
333
305
        # Construct a config fragment:
334
306
        overlay = dedent("""\
335
307
            [database]
336
 
            rw_main_master: %(main_connection_string)s
337
308
            isolation_level: %(isolation_level)s
338
 
            """ % {
339
 
                'isolation_level': isolation_level,
340
 
                'main_connection_string': main_connection_string,
341
 
                })
342
309
 
343
 
        if dbuser:
344
 
            overlay += dedent("""\
345
 
                [launchpad]
346
 
                dbuser: %(dbuser)s
347
 
                """ % {'dbuser': dbuser})
 
310
            [launchpad]
 
311
            dbuser: %(dbuser)s
 
312
            """ % dict(
 
313
                isolation_level=isolation_level,
 
314
                dbuser=dbuser))
348
315
 
349
316
        if cls._installed is not None:
350
317
            if cls._config_overlay != overlay:
357
324
        else:
358
325
            config.push(cls._CONFIG_OVERLAY_NAME, overlay)
359
326
            cls._config_overlay = overlay
360
 
            cls._dbname = dbname
361
 
            cls._dbhost = dbhost
362
327
            cls._dbuser = dbuser
363
328
            cls._isolation = isolation
364
329
            cls._reset_stores()
419
384
        assert cls._installed is not None, (
420
385
            "ZopelessTransactionManager not installed")
421
386
        cls.uninstall()
422
 
        cls.initZopeless(cls._dbname, cls._dbhost, cls._dbuser, isolation)
 
387
        cls.initZopeless(cls._dbuser, isolation)
423
388
 
424
389
    @staticmethod
425
390
    def conn():
781
746
    transaction.commit()
782
747
 
783
748
 
784
 
def connect(user, dbname=None, isolation=ISOLATION_LEVEL_DEFAULT):
 
749
def connect(user=None, dbname=None, isolation=ISOLATION_LEVEL_DEFAULT):
785
750
    """Return a fresh DB-API connection to the MAIN MASTER database.
786
751
 
787
 
    DEPRECATED - if needed, this should become a method on the Store.
788
 
 
789
 
    Use None for the user to connect as the default PostgreSQL user.
790
 
    This is not the default because the option should be rarely used.
 
752
    Can be used without first setting up the Component Architecture,
 
753
    unlike the usual stores.
791
754
 
792
755
    Default database name is the one specified in the main configuration file.
793
756
    """
794
 
    con = psycopg2.connect(connect_string(user, dbname))
 
757
    con = psycopg2.connect(connect_string(user=user, dbname=dbname))
795
758
    con.set_isolation_level(isolation)
796
759
    return con
797
760
 
798
761
 
799
 
def connect_string(user, dbname=None):
 
762
def connect_string(user=None, dbname=None):
800
763
    """Return a PostgreSQL connection string.
801
764
 
802
765
    Allows you to pass the generated connection details to external
803
766
    programs like pg_dump or embed in slonik scripts.
804
767
    """
805
 
    from canonical import lp
806
 
 
807
768
    # We must connect to the read-write DB here, so we use rw_main_master
808
769
    # directly.
809
770
    from canonical.database.postgresql import ConnectionString
810
771
    con_str = ConnectionString(dbconfig.rw_main_master)
811
772
    if user is not None:
812
773
        con_str.user = user
813
 
    if lp.dbhost is not None:
814
 
        con_str.host = lp.dbhost
815
 
    if lp.dbport is not None:
816
 
        con_str.port = lp.dbport
817
 
    if dbname is None:
818
 
        dbname = lp.get_dbname()  # Note that lp.dbname may be None
819
774
    if dbname is not None:
820
775
        con_str.dbname = dbname
821
776
    return str(con_str)