[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
r5925 - in trunk/gnue-common/src: datasources datasources/drivers/Base/S
From: |
johannes |
Subject: |
r5925 - in trunk/gnue-common/src: datasources datasources/drivers/Base/Schema/Creation datasources/drivers/interbase/Schema/Creation datasources/drivers/postgresql/Schema/Creation schema/scripter |
Date: |
Wed, 7 Jul 2004 17:14:05 -0500 (CDT) |
Author: johannes
Date: 2004-06-22 14:21:26 -0500 (Tue, 22 Jun 2004)
New Revision: 5925
Modified:
trunk/gnue-common/src/datasources/GConnections.py
trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Creation/Creation.py
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Creation/Creation.py
trunk/gnue-common/src/schema/scripter/Scripter.py
Log:
* The introspector- and creator-instances are now available to connections
which are not logged in too
* Added a 'createDatabase ()' facility to the schema-creation so a connection
can be used to create complete databases
* Implemented createDatabase () for PostgreSQL driver; more will follow soon
Modified: trunk/gnue-common/src/datasources/GConnections.py
===================================================================
--- trunk/gnue-common/src/datasources/GConnections.py 2004-06-22 07:57:07 UTC
(rev 5924)
+++ trunk/gnue-common/src/datasources/GConnections.py 2004-06-22 19:21:26 UTC
(rev 5925)
@@ -208,53 +208,76 @@
- def getConnection(self, connection_name, login=0):
+ # ---------------------------------------------------------------------------
+ # get a connection instance on optionally log into it
+ # ---------------------------------------------------------------------------
+ def getConnection (self, connection_name, login = False):
+ """
+ This function returns an instance of the requested connection and
+ optionally logs into it. If there's an already opened connection for the
+ requested connectionname this instance will be returned.
- connection_name = connection_name.lower()
+ @param connection_name: name of the connection to be returned
+ @param login: if TRUE, this function automatically tries to open the
+ connection.
+ @return: connection instance
+ @raise GConnection.NotFoundError: if connection_name does not exist
+ """
+ connection_name = connection_name.lower ()
- try:
- return self._openConnections[connection_name]
- except KeyError:
- pass
+ if self._openConnections.has_key (connection_name):
+ return self._openConnections [connection_name]
- # Support for multiple open connections
- # to same database.
- # Specify as 'gnue:1', 'gnue:2', etc, to open
- # two actual connections to 'gnue', each with
- # their own transactions, etc.
- connection_base = connection_name.split(':')[0]
+ # Support for multiple open connections to the same database.
+ # Specify as 'gnue:1', 'gnue:2', etc, to open two actual connections to
+ # 'gnue', each with their own transactions, etc.
+ connection_base = connection_name.split (':') [0]
- # This will throw a GConnections.NotFoundError if an unknown
- # connection name is specified. The calling method should
- # catch this exception and handle it properly (exit w/message)
+ # This will throw a GConnections.NotFoundError if an unknown connection
+ # name is specified. The calling method should catch this exception and
+ # handle it properly (exit w/message)
+ parameters = self.getConnectionParameters (connection_base)
- parameters = self.getConnectionParameters(connection_base)
-
- driver = parameters['provider'].lower().replace('/','.')
- behavior = parameters.get('behavior','').lower().replace('/','.')
-
+ driver = parameters ['provider'].lower ().replace ('/', '.')
+ behavior = parameters.get ('behavior','').lower ().replace ('/', '.')
dbdriver = plugin.find (driver, 'gnue.common.datasources.drivers',
'Connection')
try:
- conn = dbdriver.Connection(self, connection_name, parameters)
+ conn = dbdriver.Connection (self, connection_name, parameters)
+
except TypeError:
# Check for the case that a "Connection" is passed instead of a
- # "Connection" class. This is the case, when the procedure for deferal
- # of the loading of the connection object is overwriten by the
"connection"
- # module. i.e. there is a Connection.py file
- # TODO: remove this extra check by cleaning up the whole loading
procedure
- conn = dbdriver.Connection.Connection(self, connection_name, parameters)
+ # "Connection" class. This is the case, when the procedure for deferal of
+ # the loading of the connection object is overwriten by the "connection"
+ # module. i.e. there is a Connection.py file
+ # TODO: remove this extra check by cleaning up the whole loading
+ # procedure
+ conn = dbdriver.Connection.Connection (self, connection_name, parameters)
- self._openConnections[connection_name] = conn
+ self._openConnections [connection_name] = conn
+ # Create the introspection instance
+ # TODO: add support of the behavior parameter. Does it describe a path to
+ # the introspection module or is it the name of a provider whose
+ # introspector would be used?
+ if hasattr (conn, 'behavior'):
+ behavior = conn.behavior
+ else:
+ behavior = conn.defaultBehavior
+
+ conn.introspector = behavior (conn)
+
+ # Create the schema creator instance
+ if hasattr (conn, 'defaultCreator'):
+ conn.schemaCreator = conn.defaultCreator (conn, conn.introspector)
+ else:
+ conn.schemaCreator = None
+
if login:
- self.loginToConnection(conn)
+ self.loginToConnection (conn)
- # TODO: Process the behavior = and
- # TODO: set conn.behavior= to the
- # TODO: specific Introspection class
return conn
@@ -304,21 +327,27 @@
dataObject.connect()
- def loginToConnection(self, connection):
+ # ---------------------------------------------------------------------------
+ # logon to a connection
+ # ---------------------------------------------------------------------------
+ def loginToConnection (self, connection):
+
connection_name = connection.name
- connection_base = connection_name.split(':')[0]
+ connection_base = connection_name.split (':') [0]
if not self._loginHandler:
- self.setLoginHandler(GLoginHandler.BasicLoginHandler())
+ self.setLoginHandler (GLoginHandler.BasicLoginHandler ())
try:
connected = connection.__connected
+
except AttributeError:
connected = 0
if not connected:
loginData = connection.parameters
+
try:
# load the user's netrc file:
# a sample .netrc could look like:
@@ -330,35 +359,39 @@
# (Remark: if .netrc should work under Win32 you have to
# set the HOME environement variable [SET HOME=...])
- netrcData = netrc.netrc().authenticators(
- "'gnue://%s/'" % connection_base )
- if netrcData!=None:
- GDebug.printMesg(5, 'Read the user\'s .netrc file')
- loginData['_username'] = netrcData[0][1:-1]
- loginData['_password'] = netrcData[2][1:-1]
- GDebug.printMesg(5, 'Found useful stuff for connection %s in the
user\'s .netrc file' % connection_name)
- except (IOError,netrc.NetrcParseError,KeyError):
+ netrcData = netrc.netrc ().authenticators ("'gnue://%s/'" \
+ % connection_base)
+ if netrcData is not None:
+ GDebug.printMesg (5, 'Read the user\'s .netrc file')
+ loginData ['_username'] = netrcData [0][1:-1]
+ loginData ['_password'] = netrcData [2][1:-1]
+
+ GDebug.printMesg (5, "Found useful stuff for connection %s in "
+ "the user\'s .netrc file" % connection_name)
+
+ except (IOError, netrc.NetrcParseError, KeyError):
pass
- if (loginData.has_key('username')):
- loginData['_username'] = loginData['username']
- del loginData['username']
+ if (loginData.has_key ('username')):
+ loginData ['_username'] = loginData ['username']
+ del loginData ['username']
- if (loginData.has_key('password')):
- loginData['_password'] = loginData['password']
- del loginData['password']
+ if (loginData.has_key ('password')):
+ loginData ['_password'] = loginData ['password']
+ del loginData ['password']
# Load
- if loginData.has_key('custom_auth'):
- authenticator = dyn_import(loginData['custom_auth']).Authenticator()
- checkFields = authenticator.getLoginFields(connection.getLoginFields())
+ if loginData.has_key ('custom_auth'):
+ authenticator = dyn_import (loginData ['custom_auth']).Authenticator ()
+ checkFields = authenticator.getLoginFields ( \
+ connection.getLoginFields ())
else:
- checkFields = connection.getLoginFields()
+ checkFields = connection.getLoginFields ()
authenticator = None
- haveAllInformation = 1
+ haveAllInformation = True
for rf, dummy1, dummy2 in checkFields:
- if not (loginData.has_key(rf) and loginData[rf] != None):
+ if not (loginData.has_key (rf) and loginData [rf] is not None):
haveAllInformation = 0
break
@@ -369,9 +402,9 @@
# self._authenticatedUsers[base] = None
if authenticator:
- connection.connect(authenticator.login(loginData))
+ connection.connect (authenticator.login (loginData))
else:
- connection.connect(loginData)
+ connection.connect (loginData)
else:
attempts = 4
@@ -430,22 +463,8 @@
self._eventHandler.dispatchEvent('Connections:Connect',
name=connection_name, base=connection_base)
- # Create the introspection instance
- try:
- behavior = connection.behavior
- except AttributeError:
- behavior = connection.defaultBehavior
- connection.introspector = behavior(connection)
-
- # Create the schema creator instance
- if hasattr (connection, 'defaultCreator'):
- connection.schemaCreator = connection.defaultCreator (connection,
- connection.introspector)
- else:
- connection.schemaCreator = None
-
# Done
- connection.__connected = 1
+ connection.__connected = True
def getAuthenticatedUser(self, connection=None):
Modified:
trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
===================================================================
--- trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
2004-06-22 07:57:07 UTC (rev 5924)
+++ trunk/gnue-common/src/datasources/drivers/Base/Schema/Creation/Creation.py
2004-06-22 19:21:26 UTC (rev 5925)
@@ -29,6 +29,11 @@
class Error (gException):
pass
+class NoCreationError (Error):
+ def __init__ (self):
+ msg = _("Database creation not implemented by this driver")
+ Error.__init__ (self, msg)
+
class DefinitionError (Error):
pass
@@ -125,15 +130,27 @@
# ---------------------------------------------------------------------------
+ # Create a database
+ # ---------------------------------------------------------------------------
+
+ def createDatabase (self):
+ """
+ Descendants can override this function to create a database. Usually all
+ information needed could be gathered from the connection object.
+ """
+ raise NoCreationError
+
+
+ # ---------------------------------------------------------------------------
# Create a table from a table definition
# ---------------------------------------------------------------------------
def createTable (self, tableDefinition, codeOnly = False):
"""
This function creates a table using the given definition and returns a
- code-tuple, which can be used to to this.
+ code-tuple, which can be used to to this.
- @param tableDefinition: a dictionary of the table to be created
+ @param tableDefinition: a dictionary of the table to be created
@param codeOnly: if TRUE no operation takes place, but only the code will
be returned.
@return: a tuple of sequences (prologue, body, epliogue) containing the
Modified:
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Creation/Creation.py
===================================================================
---
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Creation/Creation.py
2004-06-22 07:57:07 UTC (rev 5924)
+++
trunk/gnue-common/src/datasources/drivers/interbase/Schema/Creation/Creation.py
2004-06-22 19:21:26 UTC (rev 5925)
@@ -20,11 +20,21 @@
#
# $Id$
+import os
from gnue.common.datasources.drivers.DBSIG2.Schema.Creation import \
Creation as Base
# =============================================================================
+# Exceptions
+# =============================================================================
+
+class NoBinaryError (gException):
+ def __init__ (self):
+ gException.__init__ (self, u_("No binary for isql(-fb) provided."))
+
+
+# =============================================================================
# Class implementing schema creation for Interbase (5.x/6.x), Firebird (1.x)
# =============================================================================
@@ -34,6 +44,42 @@
ALTER_MULTIPLE = False
# ---------------------------------------------------------------------------
+ # Create a new database
+ # ---------------------------------------------------------------------------
+
+ def __hack__createDatabase (self):
+ """
+ This function is not yet activated, but should somedays create a database
+ as described by the connection.
+ """
+ dbname = self.connection.parameters.get ('dbname', None)
+ username = self.connection.parameters.get ('username', 'gnue')
+ password = self.connection.parameters.get ('password', None)
+ host = self.connection.parameters.get ('host', None)
+ isqlbin = self.connection.parameters.get ('isqlbin', None)
+
+ if not isqlbin:
+ raise NoBinaryError
+
+ if host:
+ dburl = "%s:%s" % (host, dbname)
+ else:
+ dburl = dbname
+
+ code = open ("ib.sql", "w")
+ try:
+ code.write (u"CREATE DATABASE '%s' USER 'sysdba' PASSWORD 'masterkey' "
+ "DEFAULT CHARACTER SET UTF8;\n" % dburl)
+ code.close ()
+
+ if os.system (u"%s -i ib.sql" % isqlbin):
+ raise gException, ("Cannot create database")
+
+ finally:
+ os.unlink ("ib.sql")
+
+
+ # ---------------------------------------------------------------------------
# Process a defaultwith attribute
# ---------------------------------------------------------------------------
Modified:
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Creation/Creation.py
===================================================================
---
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Creation/Creation.py
2004-06-22 07:57:07 UTC (rev 5924)
+++
trunk/gnue-common/src/datasources/drivers/postgresql/Schema/Creation/Creation.py
2004-06-22 19:21:26 UTC (rev 5925)
@@ -20,6 +20,7 @@
#
# $Id$
+import os
from gnue.common.datasources.drivers.DBSIG2.Schema.Creation import \
Creation as Base
@@ -35,6 +36,55 @@
# ---------------------------------------------------------------------------
+ # Create a new database
+ # ---------------------------------------------------------------------------
+
+ def createDatabase (self):
+ """
+ This function creates the requested user and database using the tools
+ 'createuser', 'createdb' and 'dropuser'. Of course this function should
+ better make use of the template1 database using a connection object.
+ """
+ dbname = self.connection.parameters.get ('dbname', None)
+ username = self.connection.parameters.get ('username', 'gnue')
+ password = self.connection.parameters.get ('password', None)
+ host = self.connection.parameters.get ('host', None)
+ port = self.connection.parameters.get ('port', None)
+
+ site = ""
+ if host is not None:
+ site += " --host=%s" % host
+ if port is not None:
+ site += " --port=%s" % port
+
+ # TODO: use a connection object to the template1 database instead of the
+ # shell-scripts. Note: CREATE DATABASE statements must NOT run within a
+ # transaction block, so we cannot use the default connection mechanisms.
+
+ try:
+ os.system (u"dropuser %s%s 2>/dev/null" % (username, site))
+
+ except:
+ pass
+
+ createuser = u"createuser --createdb --adduser %s%s" % (username, site)
+ if os.system (createuser):
+ raise gException, ("User creation failed")
+
+
+ createdb = u"createdb %s --owner=%s%s" % (dbname, username, site)
+ if os.system (createdb):
+ raise gException, ("Database creation failed")
+
+
+ if password is not None and password:
+ self.connection.manager.loginToConnection (self.connection)
+ alterUser = u"ALTER USER %s WITH PASSWORD '%s';" % (username, password)
+ self.connection.makecursor (alterUser)
+ self.connection.commit ()
+
+
+ # ---------------------------------------------------------------------------
# Handle special defaults
# ---------------------------------------------------------------------------
Modified: trunk/gnue-common/src/schema/scripter/Scripter.py
===================================================================
--- trunk/gnue-common/src/schema/scripter/Scripter.py 2004-06-22 07:57:07 UTC
(rev 5924)
+++ trunk/gnue-common/src/schema/scripter/Scripter.py 2004-06-22 19:21:26 UTC
(rev 5925)
@@ -83,6 +83,20 @@
"creation is done. If mode is 'data' only data integration "
"is done."))
+ self.addCommandOption ('username', 'u', argument="user",
+ help = _("Set the username for the database. If the database is to be "
+ "created, this username will be it's owner."))
+
+ self.addCommandOption ('password', 'p', argument="password",
+ help = _("Set the password for the database."))
+
+ self.addCommandOption ('createdb', 'd', default = False,
+ help = _("If this option is set, the database will be created before "
+ "any schema creation is done. There must be a username "
+ "either from the given connection-configuration or from the "
+ "command line. This user becomes the owner of the database "
+ "and will be implicitly created."))
+
ConfigOptions = {}
GClientApp.__init__ (self, connections, 'schema', ConfigOptions)
@@ -119,17 +133,25 @@
print sys.exc_info () [1]
else:
- if self.__doData and len (self.tabledata):
- self.verifyDataKeys ()
+ try:
+ if self.__doData and len (self.tabledata):
+ self.verifyDataKeys ()
- if self.__doSchema:
- self.executeAndGenerateCode ()
+ if self.OPTIONS ['createdb']:
+ if self.connection.schemaCreator is not None:
+ self.connection.schemaCreator.createDatabase ()
- if self.__doData and len (self.tabledata):
- self.updateData ()
+ if self.__doSchema:
+ self.executeAndGenerateCode ()
+ if self.__doData and len (self.tabledata):
+ self.updateData ()
+ except Exception:
+ print sys.exc_info () [1]
+
+
# ---------------------------------------------------------------------------
# Walk through all command line options
# ---------------------------------------------------------------------------
@@ -170,7 +192,19 @@
self.handleStartupError (_("Mode of operation must be one of "
"'both', 'schema' or 'data'."))
+ cName = self.OPTIONS ['connection']
+ self.connection = self.connections.getConnection (cName)
+ # if a username is given on the command line we pass both username and
+ # password to the connection parameters. If the password is not set, it
+ # defaults to an empty string.
+ username = self.OPTIONS ['username'] or 'gnue'
+
+ self.connection.parameters ['username'] = username
+ self.connection.parameters ['password'] = self.OPTIONS ['password'] or ""
+
+
+
# ---------------------------------------------------------------------------
# Get a dictionary with all keys listed in tags and values from sObject
# ---------------------------------------------------------------------------
@@ -426,12 +460,11 @@
given output file (if requested by options).
"""
- connection = self.connections.getConnection (self.OPTIONS ['connection'],
- login = True)
+ self.connections.loginToConnection (self.connection)
print _("Updating schema ...")
- code = connection.updateSchema (self.tables, self.OPTIONS ['file-only'])
-
+ code = self.connection.updateSchema (self.tables,
+ self.OPTIONS ['file-only'])
if self.outfile is not None:
dest = open (self.outfile, 'w')
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- r5925 - in trunk/gnue-common/src: datasources datasources/drivers/Base/Schema/Creation datasources/drivers/interbase/Schema/Creation datasources/drivers/postgresql/Schema/Creation schema/scripter,
johannes <=