1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

# This file is part of Buildbot.  Buildbot is free software: you can 

# redistribute it and/or modify it under the terms of the GNU General Public 

# License as published by the Free Software Foundation, version 2. 

# 

# This program is distributed in the hope that it will be useful, but WITHOUT 

# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 

# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 

# details. 

# 

# You should have received a copy of the GNU General Public License along with 

# this program; if not, write to the Free Software Foundation, Inc., 51 

# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 

# 

# Copyright Buildbot Team Members 

 

import sqlalchemy as sa 

 

def upgrade(migrate_engine): 

    metadata = sa.MetaData() 

    metadata.bind = migrate_engine 

 

    # older build masters stored some of their state with an object named 

    # 'master' with class 'buildbot.master.BuildMaster', while other state was 

    # stored with objects named after each master itself, with class 

    # BuildMaster. 

 

    objects_table = sa.Table('objects', metadata, autoload=True) 

    object_state_table = sa.Table('object_state', metadata, autoload=True) 

 

    # get the old, unwanted ID 

    q = sa.select([ objects_table.c.id ], 

        whereclause=(objects_table.c.name=='master') 

             & (objects_table.c.class_name == 'buildbot.master.BuildMaster')) 

    res = q.execute() 

    old_id = res.scalar() 

 

    # if there's no such ID, there's nothing to change 

    if old_id is not None: 

 

        # get the new ID 

        q = sa.select([ objects_table.c.id ], 

            whereclause=objects_table.c.class_name == 'BuildMaster') 

        res = q.execute() 

        ids = res.fetchall() 

 

        # if there is exactly one ID, update the existing object_states.  If 

        # there are zero or multiple object_states, then we do not know which 

        # master to assign last_processed_change to, so we just delete it. 

        # This indicates to the master that it has processed all changes, which 

        # is probably accurate. 

        if len(ids) == 1: 

            new_id = ids[0][0] 

 

            # update rows with the old id to use the new id 

            q = object_state_table.update( 

                    whereclause=(object_state_table.c.objectid == old_id)) 

            q.execute(objectid=new_id) 

        else: 

            q = object_state_table.delete( 

                    whereclause=(object_state_table.c.objectid == old_id)) 

            q.execute() 

 

        # in either case, delete the old object row 

        q = objects_table.delete( 

                whereclause=(objects_table.c.id == old_id)) 

        q.execute() 

 

    # and update the class name for the new rows 

    q = objects_table.update( 

            whereclause=(objects_table.c.class_name == 'BuildMaster')) 

    q.execute(class_name='buildbot.master.BuildMaster')