11import re
2+ import os .path
23from .._compat import PY2 , with_metaclass , iterkeys , to_unicode , long
34from .._globals import IDENTITY , THREAD_LOCAL
45from ..drivers import psycopg2_adapt
@@ -11,6 +12,7 @@ class PostgreMeta(AdapterMeta):
1112 def __call__ (cls , * args , ** kwargs ):
1213 if cls not in [Postgre , PostgreNew , PostgreBoolean ]:
1314 return AdapterMeta .__call__ (cls , * args , ** kwargs )
15+ # choose driver according uri
1416 available_drivers = [
1517 driver for driver in cls .drivers
1618 if driver in iterkeys (kwargs ['db' ]._drivers_available )]
@@ -34,9 +36,9 @@ class Postgre(
3436 support_distributed_transaction = True
3537
3638 REGEX_URI = re .compile (
37- '^(?P<user>[^:@]+)(\ :(?P<password>[^@]*))?@(?P<host>\[[^/]+\]|' +
38- '[^\:@ ]*)(\ :(?P<port>[0-9]+))?/(?P<db>[^\ ?]+)' +
39- '(\?sslmode=(?P<sslmode>.+ ))?(\?unix_socket=(?P<socket>.+))?$' )
39+ '^(?P<user>[^:@]+)(:(?P<password>[^@]*))?'
40+ '@(?P<host>[^:/ ]*)(:(?P<port>[0-9]+))?/(?P<db>[^?]+)'
41+ '(\?sslmode=(?P<sslmode>[^?]+))?(\?(?P<ssl_flag>ssl ))?(\?unix_socket=(?P<socket>.+))?$' )
4042
4143 def __init__ (self , db , uri , pool_size = 0 , folder = None , db_codec = 'UTF-8' ,
4244 credential_decoder = IDENTITY , driver_args = {},
@@ -54,29 +56,36 @@ def _initialize_(self, do_connect):
5456 if not m :
5557 raise SyntaxError ("Invalid URI string in DAL" )
5658 user = self .credential_decoder (m .group ('user' ))
57- if not user :
58- raise SyntaxError ('User required' )
5959 password = self .credential_decoder (m .group ('password' ))
60- if not password :
61- password = ''
6260 host = m .group ('host' )
6361 socket = m .group ('socket' )
6462 if not host and not socket :
65- raise SyntaxError ('Host name required' )
63+ raise SyntaxError ('Host or UNIX socket name required' )
6664 db = m .group ('db' )
67- if not db and not socket :
68- raise SyntaxError ('Database name required' )
69- port = int (m .group ('port' ) or '5432' )
70- sslmode = m .group ('sslmode' )
65+ self .driver_args .update (user = user , database = db )
66+ if password is not None :
67+ self .driver_args ['password' ] = password
7168 if socket :
72- self .driver_args .update (user = user , host = socket , port = port , password = password )
73- if db :
74- self .driver_args ['database' ] = db
69+ if not os .path .exists (socket ):
70+ raise ValueError ("UNIX socket %r not found" % socket )
71+ if self .driver_name == 'psycopg2' :
72+ # the psycopg2 driver let you configure the socket directory
73+ # only (not the socket file name) by passing it as the host
74+ # (must be an absolute path otherwise the driver tries a TCP/IP
75+ # connection to host); this behaviour is due to the underlying
76+ # libpq used by the driver
77+ socket_dir = os .path .abspath (os .path .dirname (socket ))
78+ self .driver_args ['host' ] = socket_dir
79+ elif self .driver_name == 'pg8000' :
80+ self .driver_args ['unix_sock' ] = socket
7581 else :
76- self .driver_args .update (database = db , user = user , host = host , port = port , password = password )
77- if sslmode :
82+ port = int (m .group ('port' ) or 5432 )
83+ self .driver_args .update (host = host , port = port )
84+ sslmode = m .group ('sslmode' )
85+ if sslmode and self .driver_name == 'psycopg2' :
7886 self .driver_args ['sslmode' ] = sslmode
79- # choose diver according uri
87+ if m .group ('ssl_flag' ) and self .driver_name == 'pg8000' :
88+ self .driver_args ['ssl' ] = True
8089 if self .driver :
8190 self .__version__ = "%s %s" % (self .driver .__name__ ,
8291 self .driver .__version__ )
@@ -237,8 +246,8 @@ class JDBCPostgre(Postgre):
237246 drivers = ('zxJDBC' ,)
238247
239248 REGEX_URI = re .compile (
240- '^(?P<user>[^:@]+)(\ :(?P<password>[^@]*))?@(?P<host>\[[^/]+\]|' +
241- '[^\ :/]+)(\ :(?P<port>[0-9]+))?/(?P<db>.+)$' )
249+ '^(?P<user>[^:@]+)(:(?P<password>[^@]*))?'
250+ '@(?P<host>[^ :/]+)(:(?P<port>[0-9]+))?/(?P<db>.+)$' )
242251
243252 def _initialize_ (self , do_connect ):
244253 super (Postgre , self )._initialize_ (do_connect )
0 commit comments