1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """C{sql [DB] QUERY}
19
20 Executes a sql query on a specified database. Occurrences of
21 formatting directives (e.g. C{%s}) will be replaced by input values.
22
23 The database is selected by C{DB}. If C{DB} matches an C{osh.sql}
24 profile in C{.oshrc}, then the database is specified by that
25 profile. If C{DB} is omitted, then the default profile is used.
26
27 If C{QUERY} is a SELECT statement, then the query is executed and
28 output rows, represented by tuples, are written to output. If C{QUERY}
29 is any other type of SQL statement, then no output is written.
30 """
31
32 import os
33
34 import osh.loader
35 import osh.core
36
37
40
41
42 -def sql(query, db = None):
43 """Executes a sql query on a specified database. Occurrences of
44 formatting directives (e.g. C{%s}) will be replaced by input values.
45 The database is selected by C{db}. If C{db} matches an C{osh.sql}
46 profile in C{.oshrc}, then the database is specified by that
47 profile. If C{db} is C{None}, then the default profile is used.
48 If C{QUERY} is a I{select} statement, then the query is executed and
49 output rows, represented by tuples, are written to output. If C{QUERY}
50 is any other type of SQL statement, then no output is written.
51 """
52 args = []
53 if db:
54 args.append(db)
55 args.append(query)
56 return _Sql().process_args(*args)
57
59 return isinstance(object, list) or isinstance(object, tuple)
60
61 -class _Sql(osh.core.Generator):
62
63 _db_type = None
64 _host = None
65 _db = None
66 _header = None
67 _user = None
68 _password = None
69 _connection = None
70 _query = None
71
72
73
74
77
78
79
80
83
85 args = self.args()
86 db_profile = None
87 if args.has_next():
88 query = args.next_string()
89 if args.has_next():
90 db_profile = query
91 query = args.next_string()
92 if args.has_next():
93 self.usage()
94 else:
95 self.usage()
96 if not db_profile:
97 db_profile_from_env = osh.core.default_db_profile
98 if db_profile_from_env:
99 db_profile = db_profile_from_env
100 else:
101 db_profile = osh.core.config_value('sql')
102 if not db_profile:
103 raise Exception('No db profile selected')
104
105 self._query = query
106
107 if self.thread_state and type(self.thread_state) is osh.cluster.Host:
108 schema = self.thread_state.schema
109 else:
110 schema = None
111
112 driver = osh.core.config_value('sql', db_profile, 'driver')
113 dbtype = osh.core.config_value('sql', db_profile, 'dbtype')
114 if dbtype is None and driver is None:
115 raise Exception('Database configuration osh.sql.%s must configure either dbtype or driver' %
116 db_profile)
117 elif driver:
118 connect_info = osh.core.config_subset('sql.%s' % db_profile)
119
120 try:
121 del connect_info['set_schema']
122 except KeyError:
123 pass
124 import sqladapter.dbapi
125 self._db_type = sqladapter.dbapi.DBAPI()
126 self._connection = self._db_type.connect(connect_info)
127 elif dbtype:
128 host = osh.core.config_value('sql', db_profile, 'host')
129 if host is None:
130 host = 'localhost'
131 db = osh.core.config_value('sql', db_profile, 'db')
132 user = osh.core.config_value('sql', db_profile, 'user')
133 password = osh.core.config_value('sql', db_profile, 'password')
134
135 self._db_type = osh.loader.load_and_create(dbtype)
136 self._connection = self._db_type.connect(db, host, user, password)
137 else:
138 assert False
139 set_schema_query = osh.core.config_value('sql', db_profile, 'set_schema')
140 if set_schema_query and self.thread_state:
141 schema = self.thread_state.schema
142 self._db_type.run_update(self._connection, set_schema_query % schema, [])
143
144
145
146
148
149
150 self._execute_query([])
151
152
153
155 self._execute_query(object)
156
158 self._connection.close()
159 self.send_complete()
160
161
162
164 for row in self._db_type.run_query(self._connection,
165 self._query,
166 inputs):
167 self.send(row)
168
170
171 - def connect(self, db, host, user, password):
173
174 - def run_query(self, connection, query, inputs):
176
179