Пример #1
0
def capture_rollback(db_id, db_name, coll_name, change, coll_id = None):
    """"Capture diff which will allow roll-back of edits

    db_id -- ID of DB change applies to
    db_name -- Name of DB change applies to
    coll_name -- Name of collection change applies to
    change -- The change to be made, as a diff item ( entry in diff['diffs'])

    coll_id -- Supply if this is a field edit and so coll_id is known
    Roll-backs can be applied using apply_rollback. Their format is a diff, with extra 'post' field storing the state after change, and the live field which should be unset if they are applied
    """

    return {}

    is_record = False
    #Fetch the current state
    if coll_id is None and coll_name is not None:
        current_record = idc.get_coll(db_id, coll_name)
    elif coll_id is None:
        current_record = idc.get_db(db_name)
    else:
        try:
            current_record = idc.get_field(coll_id, change['item'], type = 'human')
            #Try as a field first
            assert current_record is not None and current_record['err'] is False
        except:
            #Now try as a record
            current_record = idc.get_record(coll_id, change['item'])
            is_record = True
    if current_record is None:
        #Should not happen really, but if it does we can't do anything
        return None

    #Create a roll-back document
    field = change["field"]
    prior = change.copy()

    if coll_id is None and coll_name is not None:
        if ih.is_special_field(change["item"]):
            prior['content'] = current_record['data'][change["item"][2:-2]][field]
        elif ih.is_toplevel_field(change['item']):
            prior['content'] = current_record['data'][field]
        else:
            prior['content'] = current_record['data'][change["item"]][field]
    elif coll_id is None:
        prior['content'] = current_record['data'][field]
    elif is_record:
        prior['content'] = current_record['data'][field]
    else:
        prior['content'] = current_record['data']['data'][field]

    #This can be applied like the diffs from the web-frontend, but has an extra field
    rollback_diff = {"db":db_name, "collection":coll_name, "diffs":[prior], "post":change, "live":True}

    return rollback_diff
Пример #2
0
def capture_rollback(inv_db, db_id, db_name, coll_name, change, coll_id = None):
    """"Capture diff which will allow roll-back of edits

    inv_db -- connection to inventory_db
    db_id -- ID of DB change applies to
    db_name -- Name of DB change applies to
    coll_name -- Name of collection change applies to
    change -- The change to be made, as a diff item ( entry in diff['diffs'])

    coll_id -- Supply if this is a field edit and so coll_id is known
    Roll-backs can be applied using apply_rollback. Their format is a diff, with extra 'post' field storing the state after change, and the live field which should be unset if they are applied
    """

    is_record = False
    #Fetch the current state
    if coll_id is None and coll_name is not None:
        current_record = idc.get_coll(inv_db, db_id, coll_name)
    elif coll_id is None:
        current_record = idc.get_db(inv_db, db_name)
    else:
        try:
            current_record = idc.get_field(inv_db, coll_id, change['item'], type = 'human')
            #Try as a field first
            assert current_record is not None and current_record['err'] is False
        except:
            #Now try as a record
            current_record = idc.get_record(inv_db, coll_id, change['item'])
            is_record = True
    if current_record is None:
        #Should not happen really, but if it does we can't do anything
        return None

    #Create a roll-back document
    field = change["field"]
    prior = change.copy()

    if coll_id is None and coll_name is not None:
        if ih.is_special_field(change["item"]):
            prior['content'] = current_record['data'][change["item"][2:-2]][field]
        elif ih.is_toplevel_field(change['item']):
            prior['content'] = current_record['data'][field]
        else:
            prior['content'] = current_record['data'][change["item"]][field]
    elif coll_id is None:
        prior['content'] = current_record['data'][field]
    elif is_record:
        prior['content'] = current_record['data'][field]
    else:
        prior['content'] = current_record['data']['data'][field]

    #This can be applied like the diffs from the web-frontend, but has an extra field
    rollback_diff = {"db":db_name, "collection":coll_name, "diffs":[prior], "post":change, "live":True}

    return rollback_diff
Пример #3
0
def capture_rollback(db_id, db_name, table_name, change, table_id = None):
    """"Capture diff which will allow roll-back of edits

    db_id -- ID of DB change applies to
    db_name -- Name of DB change applies to
    table_name -- Name of table change applies to
    change -- The change to be made, as a diff item ( entry in diff['diffs'])

    table_id -- Supply if this is a field edit and so table_id is known
    Roll-backs can be applied using apply_rollback. Their format is a diff, with extra 'post' field storing the state after change, and the live field which should be unset if they are applied
    """

    #Fetch the current state
    if table_id is None and table_name is not None:
        current_record = idc.get_table(table_name)
    elif table_id is None:
        current_record = idc.get_db(db_name)
    else:
        current_record = idc.get_field(table_id, change['item'], type = 'human')
    if current_record is None:
        #Should not happen really, but if it does we can't do anything
        return None

    #Create a roll-back document
    field = change["field"]
    prior = change.copy()

    if table_id is None and table_name is not None:
        if ih.is_special_field(change["item"]):
            prior['content'] = current_record['data'][change["item"][2:-2]][field]
        elif ih.is_toplevel_field(change['item']):
            prior['content'] = current_record['data'][field]
        else:
            prior['content'] = current_record['data'][change["item"]][field]
    elif table_id is None:
        prior['content'] = current_record['data'][field]
    else:
        prior['content'] = current_record['data']['data'][field]

    #This can be applied like the diffs from the web-frontend, but has an extra field
    rollback_diff = {"db":db_name, "table":table_name, "diffs":[prior], "post":change, "live":True}

    return rollback_diff
Пример #4
0
def process_edits(diff):
#This has to reverse anything we did to display info
#We also edit the diff if there's anything to be done

    diffs = diff["diffs"]
    for index, diff_item in enumerate(diffs):
        if diff_item['field'] == "example":
            str = diff_item['content']
            str = ih.transform_examples(str, True)
            diffs[index]['content'] = str

    #We allow editing of nice_names in two ways, so we patch the diff accordingly here
    #If current state is {"item":"__INFO__","field":"nice_name"... we want to change __INFO__ to 'top_level'
    for index, diff_item in enumerate(diffs):
        if diff_item['item'] == '__INFO__' and diff_item['field'] == 'nice_name':
            diff_item['item'] = 'top_level'
            if not ih.is_toplevel_field(diff_item['item']):
                raise DiffKeyError("Cannot identify top-level state")

    return diff
Пример #5
0
def process_edits(diff):
#This has to reverse anything we did to display info
#We also edit the diff if there's anything to be done

    diffs = diff["diffs"]
    for index, diff_item in enumerate(diffs):
        if diff_item['field'] == "example":
            str = diff_item['content']
            str = ih.transform_examples(str, True)
            inv.log_dest.info(str)
            diffs[index]['content'] = str

    #We allow editing of nice_names in two ways, so we patch the diff accordingly here
    #If current state is {"item":"__INFO__","field":"nice_name"... we want to change __INFO__ to 'top_level'
    for index, diff_item in enumerate(diffs):
        if diff_item['item'] == '__INFO__' and diff_item['field'] == 'nice_name':
            diff_item['item'] = 'top_level'
            if not ih.is_toplevel_field(diff_item['item']):
                raise DiffKeyError("Cannot identify top-level state")

    return diff
Пример #6
0
def update_fields(diff, storeRollback=True):
    """Update a record from a diff object.

    diff -- should be a fully qualified difference, containing db, table names and then a list of changes, each being a dict containing the item, the field and the new content. Item corresponds to an entry in an object, field to the piece of information this specifies (for example, type, description, example)
    e.g. {"db":"hgcwa","table":"hgcwa_passports","diffs":[{"item":"total_label","field":"type","content":"string"}]}
    If this is a record entry, then the 'item' field will be a record hash.
    storeRollback -- determine whether to store the undiff and diff to allow rollback of the change
    """

    try:
        if diff['table'] is not None:
            inv.log_dest.info("Updating descriptions for " + diff["table"])
        else:
            inv.log_dest.info("Updating descriptions for " + diff["db"])
        db_id = idc.get_db_id(diff["db"])
        rollback = None
        try:
            for change in diff["diffs"]:
                if ih.is_special_field(change["item"]):
                    if storeRollback:
                        rollback = capture_rollback(db_id, diff["db"], diff["table"], change)
                    change["item"] = change["item"][2:-2] #Trim special fields. TODO this should be done better somehow
                    updated = idc.update_table_data(db_id, diff["table"], change["item"], change["field"], change["content"])
                elif ih.is_toplevel_field(change["item"]):
                    #Here we have item == "toplevel", field the relevant field, and change the new value
                    if storeRollback:
                        rollback = capture_rollback(db_id, diff["db"], diff["table"], change)
                    #Only nice_name is currently an option
                    if(change["field"] not in ['nice_name', 'status']):
                        updated = {'err':True}
                    else:
                        if(diff["table"]):
                            if(change['field']) == 'nice_name':
                                new_nice = change['content']
                                new_stat = None
                            else:
                                new_nice = None
                                new_stat = ih.status_to_code(change['content'])
                            table_id = idc.get_table_id(diff['table'])
                            updated = idc.update_table(table_id, nice_name=new_nice, status=new_stat)
                        else:
                            #Is database nice_name
                            updated = idc.update_db(db_id, nice_name=change["content"])
                else:
                    table_id = idc.get_table_id(diff["table"])
                    if storeRollback:
                        rollback = capture_rollback(db_id, diff["db"], diff["table"], change, table_id = table_id)
                    updated = idc.update_field(table_id, change["item"], change["field"], change["content"], type="human")

                if updated['err']:
                    raise KeyError("Cannot update, item not present")
                else:
                    if storeRollback:
                        store_rollback(rollback)

        except Exception as e:
            inv.log_dest.error("Error applying diff "+ str(change)+' '+str(e))
            raise UpdateFailed(str(e))

    except Exception as e:
        inv.log_dest.error("Error updating fields "+ str(e))
Пример #7
0
def update_fields(diff, storeRollback=True):
    """Update a record from a diff object.

    diff -- should be a fully qualified difference, containing db, table names and then a list of changes, each being a dict containing the item, the field and the new content. Item corresponds to an entry in an object, field to the piece of information this specifies (for example, type, description, example)
    e.g. {"db":"hgcwa","table":"hgcwa_passports","diffs":[{"item":"total_label","field":"type","content":"string"}]}
    If this is a record entry, then the 'item' field will be a record hash.
    storeRollback -- determine whether to store the undiff and diff to allow rollback of the change
    """

    try:
        if diff['table'] is not None:
            inv.log_dest.info("Updating descriptions for " + diff["table"])
        else:
            inv.log_dest.info("Updating descriptions for " + diff["db"])
        db_id = idc.get_db_id(diff["db"])
        rollback = None
        try:
            for change in diff["diffs"]:
                if ih.is_special_field(change["item"]):
                    if storeRollback:
                        rollback = capture_rollback(db_id, diff["db"],
                                                    diff["table"], change)
                    change["item"] = change["item"][
                        2:
                        -2]  #Trim special fields. TODO this should be done better somehow
                    updated = idc.update_table_data(db_id, diff["table"],
                                                    change["item"],
                                                    change["field"],
                                                    change["content"])
                elif ih.is_toplevel_field(change["item"]):
                    #Here we have item == "toplevel", field the relevant field, and change the new value
                    if storeRollback:
                        rollback = capture_rollback(db_id, diff["db"],
                                                    diff["table"], change)
                    #Only nice_name is currently an option
                    if (change["field"] not in ['nice_name', 'status']):
                        updated = {'err': True}
                    else:
                        if (diff["table"]):
                            if (change['field']) == 'nice_name':
                                new_nice = change['content']
                                new_stat = None
                            else:
                                new_nice = None
                                new_stat = ih.status_to_code(change['content'])
                            table_id = idc.get_table_id(diff['table'])
                            updated = idc.update_table(table_id,
                                                       nice_name=new_nice,
                                                       status=new_stat)
                        else:
                            #Is database nice_name
                            updated = idc.update_db(
                                db_id, nice_name=change["content"])
                else:
                    table_id = idc.get_table_id(diff["table"])
                    if storeRollback:
                        rollback = capture_rollback(db_id,
                                                    diff["db"],
                                                    diff["table"],
                                                    change,
                                                    table_id=table_id)
                    updated = idc.update_field(table_id,
                                               change["item"],
                                               change["field"],
                                               change["content"],
                                               type="human")

                if updated['err']:
                    raise KeyError("Cannot update, item not present")
                else:
                    if storeRollback:
                        store_rollback(rollback)

        except Exception as e:
            inv.log_dest.error("Error applying diff " + str(change) + ' ' +
                               str(e))
            raise UpdateFailed(str(e))

    except Exception as e:
        inv.log_dest.error("Error updating fields " + str(e))
Пример #8
0
def update_fields(diff, storeRollback=True):
    """Update a record from a diff object.

    diff -- should be a fully qualified difference, containing db, collection names and then a list of changes, each being a dict containing the item, the field and the new content. Item corresponds to an entry in an object, field to the piece of information this specifies (for example, type, description, example)
    e.g. {"db":"curve_automorphisms","collection":"passports","diffs":[{"item":"total_label","field":"type","content":"string"}]}
    If this is a record entry, then the 'item' field will be a record hash.
    storeRollback -- determine whether to store the undiff and diff to allow rollback of the change
    """

    try:
        _id = idc.get_db_id(diff["db"])
        rollback = None

        storeRollback = False
        try:
            for change in diff["diffs"]:
                if ih.is_special_field(change["item"]):
                    if storeRollback:
                        rollback = capture_rollback(_id['id'], diff["db"], diff["collection"], change)
                    change["item"] = change["item"][2:-2] #Trim special fields. TODO this should be done better somehow
                    updated = idc.update_coll_data(_id['id'], diff["collection"], change["item"], change["field"], change["content"])
                elif ih.is_toplevel_field(change["item"]):
                    #Here we have item == "toplevel", field the relevant field, and change the new value
                    if storeRollback:
                        rollback = capture_rollback(_id['id'], diff["db"], diff["collection"], change)
                    #Only nice_name is currently an option
                    print(change['field'])
                    if(change["field"] not in ['nice_name', 'status']):
                        updated = {'err':True}
                    else:
                        if(diff["collection"]):
                            if(change['field']) == 'nice_name':
                                new_nice = change['content']
                                new_stat = None
                            else:
                                new_nice = None
                                new_stat = ih.status_to_code(change['content'])
                            c_id = idc.get_coll_id(_id['id'], diff['collection'])
                            updated = idc.update_coll(c_id['id'], nice_name=new_nice, status=new_stat)
                        else:
                            #Is database nice_name
                            print(_id)
                            updated = idc.update_db(_id['id'], nice_name=change["content"])
                else:
                    _c_id = idc.get_coll_id(_id['id'], diff["collection"])
                    if storeRollback:
                        rollback = capture_rollback(_id['id'], diff["db"], diff["collection"], change, coll_id = _c_id['id'])
                    succeeded = False
                    #if it looks like a record, try treating as one
                    #If this fails try it as a field
                    if ih.is_probable_record_hash(change['item']):
                        updated = idc.update_record_description(_c_id['id'], {'hash':change["item"], change["field"]:change["content"]})
                        if updated['err'] == False:
                            succeeded = True;
                    if not succeeded:
                        updated = idc.update_field(_c_id['id'], change["item"], change["field"], change["content"], type="human")

                if updated['err']:
                    raise KeyError("Cannot update, item not present")
                else:
                    if storeRollback:
                        store_rollback(rollback)

        except Exception as e:
            raise UpdateFailed(str(e))

    except Exception as e:
        #inv.log_dest.error("Error updating fields "+ str(e))
        pass
Пример #9
0
def update_fields(diff, storeRollback=True):
    """Update a record from a diff object.

    diff -- should be a fully qualified difference, containing db, collection names and then a list of changes, each being a dict containing the item, the field and the new content. Item corresponds to an entry in an object, field to the piece of information this specifies (for example, type, description, example)
    e.g. {"db":"curve_automorphisms","collection":"passports","diffs":[{"item":"total_label","field":"type","content":"string"}]}
    If this is a record entry, then the 'item' field will be a record hash.
    storeRollback -- determine whether to store the undiff and diff to allow rollback of the change
    """

    try:
        got_client = inv.setup_internal_client(editor=True)
        assert(got_client == True)
        db = inv.int_client[inv.get_inv_db_name()]
    except Exception as e:
        inv.log_dest.error("Error getting Db connection "+ str(e))
        return

    try:
        if diff['collection'] is not None:
            inv.log_dest.info("Updating descriptions for " + diff["db"]+'.'+diff["collection"])
        else:
            inv.log_dest.info("Updating descriptions for " + diff["db"])
        _id = idc.get_db_id(db, diff["db"])
        rollback = None
        try:
            for change in diff["diffs"]:
                if ih.is_special_field(change["item"]):
                    if storeRollback:
                        rollback = capture_rollback(db, _id['id'], diff["db"], diff["collection"], change)
                    change["item"] = change["item"][2:-2] #Trim special fields. TODO this should be done better somehow
                    updated = idc.update_coll_data(db, _id['id'], diff["collection"], change["item"], change["field"], change["content"])
                elif ih.is_toplevel_field(change["item"]):
                    #Here we have item == "toplevel", field the relevant field, and change the new value
                    if storeRollback:
                        rollback = capture_rollback(db, _id['id'], diff["db"], diff["collection"], change)
                    #Only nice_name is currently an option
                    if(change["field"] not in ['nice_name', 'status']):
                        updated = {'err':True}
                    else:
                        if(diff["collection"]):
                            if(change['field']) == 'nice_name':
                                new_nice = change['content']
                                new_stat = None
                            else:
                                new_nice = None
                                new_stat = ih.status_to_code(change['content'])
                            c_id = idc.get_coll_id(db, _id['id'], diff['collection'])
                            updated = idc.update_coll(db, c_id['id'], nice_name=new_nice, status=new_stat)
                        else:
                            #Is database nice_name
                            updated = idc.update_db(db, _id['id'], nice_name=change["content"])
                else:
                    _c_id = idc.get_coll_id(db, _id['id'], diff["collection"])
                    if storeRollback:
                        rollback = capture_rollback(db, _id['id'], diff["db"], diff["collection"], change, coll_id = _c_id['id'])
                    succeeded = False
                    #if it looks like a record, try treating as one
                    #If this fails try it as a field
                    if ih.is_probable_record_hash(change['item']):
                        updated = idc.update_record_description(db, _c_id['id'], {'hash':change["item"], change["field"]:change["content"]})
                        if updated['err'] == False:
                            succeeded = True;
                    if not succeeded:
                        updated = idc.update_field(db, _c_id['id'], change["item"], change["field"], change["content"], type="human")

                if updated['err']:
                    raise KeyError("Cannot update, item not present")
                else:
                    if storeRollback:
                        store_rollback(db, rollback)

        except Exception as e:
            inv.log_dest.error("Error applying diff "+ str(change)+' '+str(e))
            raise UpdateFailed(str(e))

    except Exception as e:
        inv.log_dest.error("Error updating fields "+ str(e))