4 from sqlalchemy
import engine_from_config
, orm
6 from ..defaults
import get_default_db_uri
7 from .tables
import Language
, metadata
8 from .multilang
import MultilangSession
, MultilangScopedSession
11 def connect(uri
=None, session_args
={}, engine_args
={}, engine_prefix
=''):
12 """Connects to the requested URI. Returns a session object.
14 With the URI omitted, attempts to connect to a default SQLite database
15 contained within the package directory.
17 Calling this function also binds the metadata object to the created engine.
20 # If we didn't get a uri, fall back to the default
22 uri
= engine_args
.get(engine_prefix
+ 'url', None)
24 uri
= get_default_db_uri()
26 ### Do some fixery for MySQL
27 if uri
.startswith('mysql:'):
28 # MySQL uses latin1 for connections by default even if the server is
29 # otherwise oozing with utf8; charset fixes this
30 if 'charset' not in uri
:
31 uri
+= '?charset=utf8'
33 # Tables should be InnoDB, in the event that we're creating them, and
34 # use UTF-8 goddammit!
35 for table
in metadata
.tables
.values():
36 table
.kwargs
['mysql_engine'] = 'InnoDB'
37 table
.kwargs
['mysql_charset'] = 'utf8'
40 engine_args
[engine_prefix
+ 'url'] = uri
41 engine
= engine_from_config(engine_args
, prefix
=engine_prefix
)
42 conn
= engine
.connect()
43 metadata
.bind
= engine
45 all_session_args
= dict(autoflush
=True, autocommit
=False, bind
=engine
)
46 all_session_args
.update(session_args
)
47 sm
= orm
.sessionmaker(class_
=MultilangSession
, language_class
=Language
,
49 session
= MultilangScopedSession(sm
)
51 # Default to English. Warning, magic constant, messing with internals,
52 # blah blah. Trying to fetch English here would kinda break on new
53 # databases. TODO still not an ideal solution, I guess.
54 session
.registry()._default_language_id
= 9
58 def identifier_from_name(name
):
59 """Make a string safe to use as an identifier.
61 Valid characters are lowercase alphanumerics and "-". This function may
62 raise ValueError if it can't come up with a suitable identifier.
64 This function is useful for scripts which add things with names.
66 if isinstance(name
, str):
67 identifier
= name
.decode('utf-8')
70 identifier
= identifier
.lower()
71 identifier
= identifier
.replace(u
'+', u
' plus ')
72 identifier
= re
.sub(u
'[ _–]+', u
'-', identifier
)
73 identifier
= re
.sub(u
"['./;’(),:]", u
'', identifier
)
74 identifier
= identifier
.replace(u
'é', u
'e')
75 identifier
= identifier
.replace(u
'♀', u
'-f')
76 identifier
= identifier
.replace(u
'♂', u
'-m')
77 if identifier
in (u
'???', u
'????'):
78 identifier
= u
'unknown'
79 elif identifier
== u
'!':
80 identifier
= u
'exclamation'
81 elif identifier
== u
'?':
82 identifier
= u
'question'
84 if not identifier
.replace(u
"-", u
"").isalnum():
85 raise ValueError(identifier
)