1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import sqlalchemy as sa
17 import migrate
18 import migrate.versioning.schema
19 import migrate.versioning.repository
20 from twisted.python import util, log
21 from buildbot.db import base
22
23 try:
24 from migrate.versioning import exceptions
25 _hush_pyflakes = exceptions
26 except ImportError:
27 from migrate import exceptions
28
29 -class Model(base.DBConnectorComponent):
30
31
32
33
34 metadata = sa.MetaData()
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 buildrequests = sa.Table('buildrequests', metadata,
55 sa.Column('id', sa.Integer, primary_key=True),
56 sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
57 nullable=False),
58 sa.Column('buildername', sa.String(length=256), nullable=False),
59 sa.Column('priority', sa.Integer, nullable=False,
60 server_default=sa.DefaultClause("0")),
61
62
63 sa.Column('complete', sa.Integer,
64 server_default=sa.DefaultClause("0")),
65
66
67
68 sa.Column('results', sa.SmallInteger),
69
70
71 sa.Column('submitted_at', sa.Integer, nullable=False),
72
73
74 sa.Column('complete_at', sa.Integer),
75 )
76
77
78
79 buildrequest_claims = sa.Table('buildrequest_claims', metadata,
80 sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
81 index=True, unique=True),
82 sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id'),
83 index=True, nullable=True),
84 sa.Column('claimed_at', sa.Integer, nullable=False),
85 )
86
87
88
89
90
91 builds = sa.Table('builds', metadata,
92 sa.Column('id', sa.Integer, primary_key=True),
93 sa.Column('number', sa.Integer, nullable=False),
94 sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
95 nullable=False),
96 sa.Column('start_time', sa.Integer, nullable=False),
97 sa.Column('finish_time', sa.Integer),
98 )
99
100
101
102
103 buildset_properties = sa.Table('buildset_properties', metadata,
104 sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id'),
105 nullable=False),
106 sa.Column('property_name', sa.String(256), nullable=False),
107
108 sa.Column('property_value', sa.String(1024), nullable=False),
109 )
110
111
112
113 buildsets = sa.Table('buildsets', metadata,
114 sa.Column('id', sa.Integer, primary_key=True),
115
116
117
118 sa.Column('external_idstring', sa.String(256)),
119
120
121 sa.Column('reason', sa.String(256)),
122 sa.Column('submitted_at', sa.Integer, nullable=False),
123
124
125 sa.Column('complete', sa.SmallInteger, nullable=False,
126 server_default=sa.DefaultClause("0")),
127 sa.Column('complete_at', sa.Integer),
128
129
130
131 sa.Column('results', sa.SmallInteger),
132
133
134 sa.Column('sourcestampsetid', sa.Integer,
135 sa.ForeignKey('sourcestampsets.id')),
136 )
137
138
139
140
141 change_files = sa.Table('change_files', metadata,
142 sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
143 nullable=False),
144 sa.Column('filename', sa.String(1024), nullable=False),
145 )
146
147
148 change_properties = sa.Table('change_properties', metadata,
149 sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
150 nullable=False),
151 sa.Column('property_name', sa.String(256), nullable=False),
152
153 sa.Column('property_value', sa.String(1024), nullable=False),
154 )
155
156
157
158
159 change_users = sa.Table("change_users", metadata,
160 sa.Column("changeid", sa.Integer, sa.ForeignKey('changes.changeid'),
161 nullable=False),
162
163 sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
164 nullable=False)
165 )
166
167
168 changes = sa.Table('changes', metadata,
169
170 sa.Column('changeid', sa.Integer, primary_key=True),
171
172
173 sa.Column('author', sa.String(256), nullable=False),
174
175
176 sa.Column('comments', sa.String(1024), nullable=False),
177
178
179 sa.Column('is_dir', sa.SmallInteger, nullable=False),
180
181
182
183 sa.Column('branch', sa.String(256)),
184
185
186 sa.Column('revision', sa.String(256)),
187
188 sa.Column('revlink', sa.String(256)),
189
190
191
192
193 sa.Column('when_timestamp', sa.Integer, nullable=False),
194
195
196 sa.Column('category', sa.String(256)),
197
198
199
200 sa.Column('repository', sa.String(length=512), nullable=False,
201 server_default=''),
202
203
204 sa.Column('codebase', sa.String(256), nullable=False,
205 server_default=sa.DefaultClause("")),
206
207
208
209 sa.Column('project', sa.String(length=512), nullable=False,
210 server_default=''),
211 )
212
213
214
215
216 patches = sa.Table('patches', metadata,
217 sa.Column('id', sa.Integer, primary_key=True),
218
219
220 sa.Column('patchlevel', sa.Integer, nullable=False),
221
222
223 sa.Column('patch_base64', sa.Text, nullable=False),
224
225
226 sa.Column('patch_author', sa.Text, nullable=False),
227
228
229 sa.Column('patch_comment', sa.Text, nullable=False),
230
231
232 sa.Column('subdir', sa.Text),
233 )
234
235
236 sourcestamp_changes = sa.Table('sourcestamp_changes', metadata,
237 sa.Column('sourcestampid', sa.Integer,
238 sa.ForeignKey('sourcestamps.id'), nullable=False),
239 sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
240 nullable=False),
241 )
242
243
244
245 sourcestampsets = sa.Table('sourcestampsets', metadata,
246 sa.Column('id', sa.Integer, primary_key=True),
247 )
248
249
250
251
252
253 sourcestamps = sa.Table('sourcestamps', metadata,
254 sa.Column('id', sa.Integer, primary_key=True),
255
256
257
258 sa.Column('branch', sa.String(256)),
259
260
261 sa.Column('revision', sa.String(256)),
262
263
264 sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
265
266
267 sa.Column('repository', sa.String(length=512), nullable=False,
268 server_default=''),
269
270
271 sa.Column('codebase', sa.String(256), nullable=False,
272 server_default=sa.DefaultClause("")),
273
274
275 sa.Column('project', sa.String(length=512), nullable=False,
276 server_default=''),
277
278
279 sa.Column('sourcestampsetid', sa.Integer,
280 sa.ForeignKey('sourcestampsets.id')),
281 )
282
283
284
285
286
287
288
289
290 scheduler_changes = sa.Table('scheduler_changes', metadata,
291 sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id')),
292 sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid')),
293
294 sa.Column('important', sa.Integer),
295 )
296
297
298
299
300
301 objects = sa.Table("objects", metadata,
302
303 sa.Column("id", sa.Integer, primary_key=True),
304
305 sa.Column('name', sa.String(128), nullable=False),
306
307 sa.Column('class_name', sa.String(128), nullable=False),
308 )
309
310
311
312 object_state = sa.Table("object_state", metadata,
313
314 sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
315 nullable=False),
316
317 sa.Column("name", sa.String(length=256), nullable=False),
318
319 sa.Column("value_json", sa.Text, nullable=False),
320 )
321
322
323
324
325
326 users = sa.Table("users", metadata,
327
328 sa.Column("uid", sa.Integer, primary_key=True),
329
330
331 sa.Column("identifier", sa.String(256), nullable=False),
332
333
334 sa.Column("bb_username", sa.String(128)),
335
336
337 sa.Column("bb_password", sa.String(128)),
338 )
339
340
341
342 users_info = sa.Table("users_info", metadata,
343
344 sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
345 nullable=False),
346
347
348 sa.Column("attr_type", sa.String(128), nullable=False),
349
350
351 sa.Column("attr_data", sa.String(128), nullable=False),
352 )
353
354
355
356
357 sa.Index('buildrequests_buildsetid', buildrequests.c.buildsetid)
358 sa.Index('buildrequests_buildername', buildrequests.c.buildername)
359 sa.Index('buildrequests_complete', buildrequests.c.complete)
360 sa.Index('builds_number', builds.c.number)
361 sa.Index('builds_brid', builds.c.brid)
362 sa.Index('buildsets_complete', buildsets.c.complete)
363 sa.Index('buildsets_submitted_at', buildsets.c.submitted_at)
364 sa.Index('buildset_properties_buildsetid',
365 buildset_properties.c.buildsetid)
366 sa.Index('changes_branch', changes.c.branch)
367 sa.Index('changes_revision', changes.c.revision)
368 sa.Index('changes_author', changes.c.author)
369 sa.Index('changes_category', changes.c.category)
370 sa.Index('changes_when_timestamp', changes.c.when_timestamp)
371 sa.Index('change_files_changeid', change_files.c.changeid)
372 sa.Index('change_properties_changeid', change_properties.c.changeid)
373 sa.Index('scheduler_changes_objectid', scheduler_changes.c.objectid)
374 sa.Index('scheduler_changes_changeid', scheduler_changes.c.changeid)
375 sa.Index('scheduler_changes_unique', scheduler_changes.c.objectid,
376 scheduler_changes.c.changeid, unique=True)
377 sa.Index('sourcestamp_changes_sourcestampid',
378 sourcestamp_changes.c.sourcestampid)
379 sa.Index('sourcestamps_sourcestampsetid', sourcestamps.c.sourcestampsetid,
380 unique=False)
381 sa.Index('users_identifier', users.c.identifier, unique=True)
382 sa.Index('users_info_uid', users_info.c.uid)
383 sa.Index('users_info_uid_attr_type', users_info.c.uid,
384 users_info.c.attr_type, unique=True)
385 sa.Index('users_info_attrs', users_info.c.attr_type,
386 users_info.c.attr_data, unique=True)
387 sa.Index('change_users_changeid', change_users.c.changeid)
388 sa.Index('users_bb_user', users.c.bb_username, unique=True)
389 sa.Index('object_identity', objects.c.name, objects.c.class_name,
390 unique=True)
391 sa.Index('name_per_object', object_state.c.objectid, object_state.c.name,
392 unique=True)
393
394
395
396
397
398 implied_indexes = [
399 ('change_users',
400 dict(unique=False, column_names=['uid'], name='uid')),
401 ('sourcestamps',
402 dict(unique=False, column_names=['patchid'], name='patchid')),
403 ('sourcestamp_changes',
404 dict(unique=False, column_names=['changeid'], name='changeid')),
405 ('buildsets',
406 dict(unique=False, column_names=['sourcestampsetid'],
407 name='buildsets_sourcestampsetid_fkey')),
408 ]
409
410
411
412
413
414
415
416
417
418
419
420 repo_path = util.sibpath(__file__, "migrate")
421
423 def thd(engine):
424
425
426 repo = migrate.versioning.repository.Repository(self.repo_path)
427 repo_version = repo.latest
428 try:
429
430 schema = migrate.versioning.schema.ControlledSchema(engine,
431 self.repo_path)
432 db_version = schema.version
433 except exceptions.DatabaseNotControlledError:
434 return False
435
436 return db_version == repo_version
437 return self.db.pool.do_with_engine(thd)
438
440
441
442
443
444
445
446
447 def table_exists(engine, tbl):
448 try:
449 r = engine.execute("select * from %s limit 1" % tbl)
450 r.close()
451 return True
452 except:
453 return False
454
455
456
457
458
459 def upgrade(engine):
460 schema = migrate.versioning.schema.ControlledSchema(engine,
461 self.repo_path)
462 changeset = schema.changeset(None)
463 for version, change in changeset:
464 log.msg('migrating schema version %s -> %d'
465 % (version, version + 1))
466 schema.runchange(version, change, 1)
467
468 def check_sqlalchemy_migrate_version():
469
470
471
472 version = getattr(migrate, '__version__', 'old')
473 if version == 'old':
474 try:
475 from migrate.versioning import schemadiff
476 if hasattr(schemadiff, 'ColDiff'):
477 version = "0.6.1"
478 else:
479 version = "0.6"
480 except:
481 version = "0.0"
482 version_tup = tuple(map(int, version.split('.')))
483 log.msg("using SQLAlchemy-Migrate version %s" % (version,))
484 if version_tup < (0,6,1):
485 raise RuntimeError("You are using SQLAlchemy-Migrate %s. "
486 "The minimum version is 0.6.1." % (version,))
487
488 def version_control(engine, version=None):
489 migrate.versioning.schema.ControlledSchema.create(engine,
490 self.repo_path, version)
491
492
493 def thd(engine):
494
495
496 if table_exists(engine, 'migrate_version'):
497 upgrade(engine)
498
499
500
501
502 elif table_exists(engine, 'version'):
503
504 r = engine.execute("select version from version limit 1")
505 old_version = r.scalar()
506
507
508 version_control(engine, old_version)
509
510
511
512 table = sa.Table('version', self.metadata,
513 sa.Column('x', sa.Integer))
514 table.drop(bind=engine)
515
516
517 self.metadata.remove(table)
518
519
520 upgrade(engine)
521
522
523
524 else:
525 version_control(engine)
526 upgrade(engine)
527
528 check_sqlalchemy_migrate_version()
529 return self.db.pool.do_with_engine(thd)
530
531
532
533
534 try:
535 import migrate.versioning.exceptions as ex1
536 import migrate.changeset.exceptions as ex2
537 ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning
538 except (ImportError,AttributeError):
539 pass
540