<commit_before>import * as mongoose from "mongoose";

/** Class representing a transaction. */
class Transaction {
    /** The states of mongoose collections before run transaction, used for rollback */
    states: Array<{
        /** The executed transaction type */
        originalType: string,
        /** The transaction type to execute for rollback */        
        rollbackType: string,
        /** The mongoose model instance */                
        model: any,
        /** The mongoose model name */                        
        modelName: string,
        /** The mongoose model instance before transaction if exists */                
        oldModels: any,
        /** The object ... */                                
        findObj: object,
        /** The array of data ... */                                        
        data: any
    }> = [];

    /** The actions to execute on mongoose collections when transaction run is called */
    transactions: Array<{
        /** The transaction type to run */   
        type: string,
        /** The mongoose model instance */                
        model: any,
        /** The mongoose model name */                        
        modelName: string,
        /** The object ... */                                
        findObj: object,
        /** The array of data ... */                                        
        data: any
    }> = [];


    /**
   * Create a transaction.
   * @param parameters - The parameters
   */
    constructor(parameters) {

    }

    /**
   * Create the insert transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param data - The object or array containing data to insert into mongoose model.
   */
    insert(modelName, data) {
        const model = mongoose.model(modelName);
        if (data instanceof Array) {
            data.forEach(currentObj => {
                if (!currentObj._id) {
                    const id = mongoose.Types.ObjectId().toString();
                    currentObj._id = id;
                }
            });
        } else {
            if (!data._id) {
                const id = mongoose.Types.ObjectId().toString();
                data._id = id;
            }
            data = [data];
        }
        const transactionObj = {
            type: "insert",
            model: model,
            modelName: modelName,
            findObj: {},
            data: data
        };
        const stateObj = {
            originalType: "insert",
            rollbackType: "remove",
            model: model,
            modelName: modelName,
            oldModels:null,
            findObj: {},
            data: {}
        };
        this.transactions.push(transactionObj);
        this.states.push(stateObj);
    }

    /**
   * Create the findOneAndUpdate transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param findObj - The object containing data to find mongoose collection.
   * @param dataObj - The object containing data to update into mongoose model.
   */
    update(modelName, findObj, data) {
        const model = mongoose.model(modelName);
        const oldModels = model.find(findObj);
        const transactionObj = {
            type: "findOneAndUpdate",
            model: model,
            modelName: modelName,
            findObj: findObj,
            data: data
        };
        const stateObj = {
            originalType: "findOneAndUpdate",
            rollbackType: "findOneAndUpdate",
            model: model,
            modelName: modelName,
            oldModels:oldModels,
            findObj: findObj,
            data: data
        };
        this.transactions.push(transactionObj);
        this.states.push(stateObj);
    }

    /**
   * Create the remove transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param findObj - The object containing data to find mongoose collection.
   */
    remove(modelName, findObj) {
        const model = mongoose.model(modelName);
        const oldModels = model.findOne(findObj);
        const transactionObj = {
            type: "remove",
            model: model,
            modelName: modelName,
            findObj: findObj,
            data: null
        };
        const stateObj = {
            originalType: "remove",
            rollbackType: "insert",
            model: model,
            modelName: modelName,
            oldModels:oldModels,
            findObj: findObj,
            data: null
        };
        this.transactions.push(transactionObj);
        this.states.push(stateObj);
    }

    /**
   * Run the transaction and check errors.
   */
    run() {

    }

    /**
   * Rollback the executed transactions if any error occurred.
   */
    rollback() {

    }

}<commit_msg>First implementation of run and rollback functions<commit_after>import * as mongoose from "mongoose";


/** Class representing a transaction. */
class Transaction {

    /** The actions to execute on mongoose collections when transaction run is called */
    transactions: Array<{
        /** The transaction type to run */
        type: string,
        /** The transaction type to execute for rollback */
        rollbackType: string,
        /** The mongoose model instance */
        model: any,
        /** The mongoose model name */
        modelName: string,
        /** The mongoose model instance before transaction if exists */
        oldModels: any,
        /** The object ... */
        findObj: object,
        /** The array of data ... */
        data: any
    }> = [];


    /**
   * Create a transaction.
   * @param parameters - The parameters
   */
    constructor(parameters) {

    }

    /**
   * Create the insert transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param data - The object or array containing data to insert into mongoose model.
   */
    insert(modelName, data) {
        const model = mongoose.model(modelName);
        if (data instanceof Array) {
            data.forEach(currentObj => {
                if (!currentObj._id) {
                    const id = mongoose.Types.ObjectId().toString();
                    currentObj._id = id;
                }
            });
        } else {
            if (!data._id) {
                const id = mongoose.Types.ObjectId().toString();
                data._id = id;
            }
            data = [data];
        }
        const transactionObj = {
            type: "insert",
            rollbackType: "remove",
            model: model,
            modelName: modelName,
            oldModels: null,
            findObj: {},
            data: data
        };

        this.transactions.push(transactionObj);

    }

    /**
   * Create the findOneAndUpdate transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param findObj - The object containing data to find mongoose collection.
   * @param dataObj - The object containing data to update into mongoose model.
   * @param options - The object containing the options for update query:
   *                     safe (boolean) safe mode (defaults to value set in schema (true))
   *                     upsert (boolean) whether to create the doc if it doesn't match (false)
   *                     multi (boolean) whether multiple documents should be updated (false)
   *                     runValidators: if true, runs update validators on this command. Update validators validate the update operation against the model's schema.
   *                     setDefaultsOnInsert: if this and upsert are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB's $setOnInsert operator.
   *                     strict (boolean) overrides the strict option for this update
   *                     overwrite (boolean) disables update-only mode, allowing you to overwrite the doc (false)
   */
    update(modelName, findObj, data, options = {}) {
        const model = mongoose.model(modelName);
        const oldModels = model.find(findObj);
        const transactionObj = {
            type: "update",
            rollbackType: "update",
            model: model,
            modelName: modelName,
            oldModels: oldModels,
            findObj: findObj,
            data: data
        };

        this.transactions.push(transactionObj);

    }

    /**
   * Create the remove transaction and rollback states.
   * @param modelName - The string containing the mongoose model name.
   * @param findObj - The object containing data to find mongoose collection.
   */
    remove(modelName, findObj) {
        const model = mongoose.model(modelName);
        const oldModels = model.findOne(findObj);
        const transactionObj = {
            type: "remove",
            rollbackType: "insert",
            model: model,
            modelName: modelName,
            oldModels: oldModels,
            findObj: findObj,
            data: null
        };

        this.transactions.push(transactionObj);

    }

    /**
   * Run the transaction and check errors.
   */
    run() {
        const deferredQueries = []
        try {
            this.transactions.forEach(transaction => {
                switch (transaction.type) {
                    case "insert":
                        deferredQueries.push(this.insertTransaction(transaction.model, transaction.data))
                        break;
                    case "update":
                        deferredQueries.push(this.updateTransaction(transaction.model, transaction.findObj, transaction.data))
                        break;
                    case "remove":
                        deferredQueries.push(this.removeTransaction(transaction.model, transaction.findObj))
                        break;
                }
            })
            Promise.all(deferredQueries)
                .then(data => {

                })
                .catch(err => {
                    this.rollback(err)
                })
        } catch (err) {
            this.rollback(err)
        }
    }

    private insertTransaction(model, data) {
        return new Promise(function (resolve, reject) {
            model.create(data, function (err, data) {
                if (err) {
                    return reject(err)
                } else {
                    return resolve(data)
                }
            });
        });
    }

    private updateTransaction(model, find, data) {
        return new Promise(function (resolve, reject) {
            model.update(find, data, function (err, data) {
                if (err) {
                    return reject(err)
                } else {
                    return resolve(data)
                }
            });
        });
    }

    private removeTransaction(model, find) {
        return new Promise(function (resolve, reject) {
            model.remove(find, function (err, data) {
                if (err) {
                    return reject(err)
                } else {
                    return resolve(data)
                }
            });
        });
    }

    /**
   * Rollback the executed transactions if any error occurred.
   */
    rollback(err) {
        const deferredQueries = []
        try {
            this.transactions.forEach(transaction => {
                switch (transaction.type) {
                    case "insert":
                        //Rollback remove with insert
                        transaction.oldModels.forEach(oldModel => {
                            deferredQueries.push(this.insertTransaction(transaction.model, oldModel))
                        })
                        break;
                    case "update":
                        //Rollback update with update
                        transaction.oldModels.forEach(oldModel => {
                            const find = {
                                _id: oldModel._id
                            }
                            deferredQueries.push(this.updateTransaction(transaction.model, find, oldModel))
                        })
                        break;
                    case "remove":
                        //Rollback insert with remove
                        transaction.oldModels.forEach(oldModel => {
                            const find = {
                                _id: oldModel._id
                            }
                            deferredQueries.push(this.removeTransaction(transaction.model, find))
                        })
                        break;
                }
            })
            Promise.all(deferredQueries)
                .then(data => {

                })
                .catch(err => {
                    
                })
        } catch (err) {
            
        }
    }

}
{'fraction_non_alphanumeric': 0.08892463235294118, 'fraction_numerical': 0.00015318627450980392, 'mean_word_length': 1.3748635867588215, 'pattern_counts': {'":': 6, '<': 6, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2570741', 'n_tokens_mistral': 3128, 'n_tokens_neox': 3044, 'n_words': 905}