server/serverctl.py
changeset 6882 b5e34836f84e
parent 6782 b5d6f5391695
parent 6867 f691757792f9
child 6948 013f81b729de
--- a/server/serverctl.py	Thu Jan 20 10:10:22 2011 +0100
+++ b/server/serverctl.py	Mon Jan 24 17:02:38 2011 +0100
@@ -25,6 +25,7 @@
 import sys
 import os
 
+from logilab.common import nullobject
 from logilab.common.configuration import Configuration
 from logilab.common.shellutils import ASK
 
@@ -56,16 +57,14 @@
         else:
             print dbname,
     if dbhelper.users_support:
-        if not verbose or (not special_privs and source.get('db-user')):
+        if not special_privs and source.get('db-user'):
             user = source['db-user']
             if verbose:
                 print 'as', user
-            if source.get('db-password'):
-                password = source['db-password']
-            else:
-                password = getpass('password: ')
+            password = source.get('db-password')
         else:
-            print
+            if verbose:
+                print
             if special_privs:
                 print 'WARNING'
                 print ('the user will need the following special access rights '
@@ -74,8 +73,8 @@
                 print
             default_user = source.get('db-user', os.environ.get('USER', ''))
             user = raw_input('Connect as user ? [%r]: ' % default_user)
-            user = user or default_user
-            if user == source.get('db-user') and source.get('db-password'):
+            user = user.strip() or default_user
+            if user == source.get('db-user'):
                 password = source['db-password']
             else:
                 password = getpass('password: ')
@@ -108,22 +107,18 @@
         return source_cnx(source, system_db, special_privs=special_privs, verbose=verbose)
     return source_cnx(source, special_privs=special_privs, verbose=verbose)
 
-def _db_sys_cnx(source, what, db=None, user=None, verbose=True):
-    """return a connection on the RDMS system table (to create/drop a user
-    or a database
+def _db_sys_cnx(source, special_privs, verbose=True):
+    """return a connection on the RDMS system table (to create/drop a user or a
+    database)
     """
     import logilab.common as lgp
     from logilab.database import get_db_helper
     lgp.USE_MX_DATETIME = False
-    special_privs = ''
     driver = source['db-driver']
     helper = get_db_helper(driver)
-    if user is not None and helper.users_support:
-        special_privs += '%s USER' % what
-    if db is not None:
-        special_privs += ' %s DATABASE' % what
     # connect on the dbms system base to create our base
-    cnx = system_source_cnx(source, True, special_privs=special_privs, verbose=verbose)
+    cnx = system_source_cnx(source, True, special_privs=special_privs,
+                            verbose=verbose)
     # disable autocommit (isolation_level(1)) because DROP and
     # CREATE DATABASE can't be executed in a transaction
     try:
@@ -194,6 +189,16 @@
             print ('-> nevermind, you can do it later with '
                    '"cubicweb-ctl db-create %s".' % self.config.appid)
 
+ERROR = nullobject()
+
+def confirm_on_error_or_die(msg, func, *args, **kwargs):
+    try:
+        return func(*args, **kwargs)
+    except Exception, ex:
+        print 'ERROR', ex
+        if not ASK.confirm('An error occurred while %s. Continue anyway?' % msg):
+            raise ExecutionError(str(ex))
+    return ERROR
 
 class RepositoryDeleteHandler(CommandHandler):
     cmdname = 'delete'
@@ -207,19 +212,29 @@
         helper = get_db_helper(source['db-driver'])
         if ASK.confirm('Delete database %s ?' % dbname):
             if source['db-driver'] == 'sqlite':
-                os.unlink(source['db-name'])
+                if confirm_on_error_or_die(
+                    'deleting database file %s' % dbname,
+                    os.unlink, source['db-name']) is not ERROR:
+                    print '-> database %s dropped.' % dbname
                 return
             user = source['db-user'] or None
-            cnx = _db_sys_cnx(source, 'DROP DATABASE', user=user)
+            cnx = confirm_on_error_or_die('connecting to database %s' % dbname,
+                                          _db_sys_cnx, source, 'DROP DATABASE', user=user)
+            if cnx is ERROR:
+                return
             cursor = cnx.cursor()
             try:
-                cursor.execute('DROP DATABASE %s' % dbname)
-                print '-> database %s dropped.' % dbname
+                if confirm_on_error_or_die(
+                    'dropping database %s' % dbname,
+                    cursor.execute, 'DROP DATABASE "%s"' % dbname) is not ERROR:
+                    print '-> database %s dropped.' % dbname
                 # XXX should check we are not connected as user
                 if user and helper.users_support and \
                        ASK.confirm('Delete user %s ?' % user, default_is_yes=False):
-                    cursor.execute('DROP USER %s' % user)
-                    print '-> user %s dropped.' % user
+                    if confirm_on_error_or_die(
+                        'dropping user %s' % user,
+                        cursor.execute, 'DROP USER %s' % user) is not ERROR:
+                        print '-> user %s dropped.' % user
                 cnx.commit()
             except:
                 cnx.rollback()
@@ -313,7 +328,7 @@
         elif self.config.create_db:
             print '\n'+underline_title('Creating the system database')
             # connect on the dbms system base to create our base
-            dbcnx = _db_sys_cnx(source, 'CREATE DATABASE and / or USER', verbose=verbose)
+            dbcnx = _db_sys_cnx(source, 'CREATE/DROP DATABASE and / or USER', verbose=verbose)
             cursor = dbcnx.cursor()
             try:
                 if helper.users_support:
@@ -333,7 +348,8 @@
             except:
                 dbcnx.rollback()
                 raise
-        cnx = system_source_cnx(source, special_privs='LANGUAGE C', verbose=verbose)
+        cnx = system_source_cnx(source, special_privs='CREATE LANGUAGE',
+                                verbose=verbose)
         cursor = cnx.cursor()
         helper.init_fti_extensions(cursor)
         # postgres specific stuff