def morph_content_to(content, after_type): """ params: content can be a Content object or a string id - as this works at the database level, any content data not commited to the DB before this call will be lost after_type is a string of the type the object is being transformed too return: the new mophed object from the database Notes: This is a VERY expensive operation as it requires up to 3 calls to get_content, each of these calls is joining potentialy over 3 tables """ content = get_content(content) if not content: raise Exception('no content to morph') if content.__type__ == None: return content # If we don't know the source object type then we cant process it if content.__type__ == after_type: return content # If the before and after types are the same then return the content obj as no processing needs to take place if content.id == None: # If the content has not been commited to the DB # then return an object of the correct type? # todo? #log.warn('content to morph not in DB? investigate') raise Exception('content to morph not in DB? investigate') id = content.id prev_type = content.__type__ sql_generator_key = content.__type__+":"+after_type if sql_generator_key not in morph_sql: raise Exception('unable to morph content from %s to %s' % (content.__type__, after_type) ) Session.expunge(content) # Remove content from SQLAlchemys scope for sql_cmd in morph_sql[sql_generator_key](id): Session.execute(sql_cmd) Session.commit() content = get_content(id) assert content.__type__ == after_type # If this is not true then something has gone very wrong! # AllanC - Although the events linked to the commit of this object invalidte the list type for the 'current' content type, they do not take into consideration a content morph from the previous type # In fact .. we need to invalidate the content item manually here because the SQL statement does not associate with the SQLA object and therefor does not trigger the SQLA events # We need to manually invalidate the list that this content object was 'before' the morph invalidate_content(content) invalidate_content_list(prev_type, content.creator_id) return content
def find_content_root(content): content = get_content(content) if not content: raise action_error(_('unable to find content'), code=404) if not content.parent: return False qry = Hierarchy( Session, Content.__table__, select([Content.__table__.c.id, Content.__table__.c.parent_id]), starting_node=content.id, return_leaf=True, ) # FIXME: Greg #print qry ev = Session.execute(qry).first() if ev: return get_content(ev.id) or False else: return False
def upgrade_user_to_group(member_to_upgrade_to_group, new_admins_username, new_group_username=None): """ Only to be called by admins/power users This handled the migration of users to groups at an SQL level """ to_group = get_member(member_to_upgrade_to_group) admin_user = get_member(new_admins_username) # Validation if not to_group or to_group.__type__ != 'user': raise action_error('member_to_upgrade_to_group not a group', code=404) if get_member(new_group_username): raise action_error('new_group_username already taken', code=404) if admin_user: raise action_error('new_admins_username already taken', code=404) # Create new admin user admin_user = User() admin_user.id = new_admins_username admin_user.name = new_admins_username admin_user.status = 'active' admin_user.email = to_group.email admin_user.email_unverifyed = to_group.email_unverified Session.add(admin_user) Session.commit() # needs to be commited to get id sql_cmds = [] if new_group_username: sql_cmds += [ Member.__table__.update().where( Member.__table__.c.id == to_group.id).values( username=new_group_username), ] sql_cmds += [ # UPDATE member set username='******', __type__='group' WHERE id=533; Member.__table__.update().where(Member.__table__.c.id == to_group.id ).values(__type__='group'), # Reassign the login details from the old member to the new admin user UserLogin.__table__.update().where( UserLogin.__table__.c.member_id == to_group.id ).values(member_id=admin_user.id), # DELETE the matching user record that pairs with the member record User.__table__.delete().where(User.__table__.c.id == to_group.id), # INSERT matching group record to pair group name Group.__table__.insert().values(id=to_group.id, join_mode='invite', member_visibility='private', default_content_visibility='public', default_role='admin', num_members=1), # INSERT admin_user as as admin of the group GroupMembership.__table__.insert().values(group_id=to_group.id, member_id=admin_user.id, role='admin', status='active'), ] for sql_cmd in sql_cmds: Session.execute(sql_cmd) Session.commit()