<commit_before>var fs = require('fs'),
    path = require('path'),
    async = require('async'),
    Saveable = require('./base').Saveable,
    Removeable  = require('./base').Removeable,
    Queriable = require('./query'),
    db_helper = require('./connection'),
    logger = require('./logger');

var defined_models = {};

var Document = function () {
  var self =  this;

  this.serialise = function () {
    var self = this;
    var serialised_doc = {};

    serialised_doc.dateCreated = self.dateCreated;
    serialised_doc.lastUpdated = self.lastUpdated;
    serialised_doc.model_type = self.model_type;


    // refactor to run through schema
    Object.keys(self.schema).forEach(function (key) {

      if (self.schema[key].type.has_one) {
        return serialised_doc[key] = self[key].serialise();
      }

      if (self.schema[key].type.has_many) {
        var many_docs = [];
        self[key].forEach( function (item) {
          many_docs.push(item.serialise());
        });

        return serialised_doc[key] = many_docs;
      }

      serialised_doc[key] = self[key] 

    });

    return serialised_doc;
  };

};

Saveable.call(Document.prototype);
Removeable.call(Document.prototype);

var ModelDocument = function (model_type, schema, views) {

  var self = this;
  var base = self;

  self.model_type = model_type;
  self.schema = schema;
  self.views = views;
  
  this.beforeSave = function (fn) {
    self.beforeSaveFn = fn;
  };

  this.afterSave = function (fn) {
    self.afterSaveFn = fn;
  };

  this.beforeCreate = function (fn) {
    self.beforeCreateFn = fn;
  };

  this.addView = function (view_name, view) {
    self.views[view_name] = view;
  };

  this.view = function (view_name, options, cb) {
    if (cb) {
      this._view(self.model_type + '/' + view_name, options, cb);
    } else {
      this._view(self.model_type + '/' + view_name, options);
    }
  };

  self.load = function (model_data) { 
    logger.info("Create model %s for %s", self.schema, model_data);

    var model = new Document();

    // TODO put into constructor
    model.beforeSaveFn = self.beforeSaveFn;
    model.afterSaveFn = self.beforeAfterFn;
    model.schema = self.schema;
    model.model_type = self.model_type;
    

    if (!model_data) return model;

    // TODO convert to correct type if needed
    Object.keys(self.schema).forEach(function (key) { 
        
        if (self.schema[key].type.has_one) {
          model[key] = self.schema[key].type.has_one.load(model_data[key]);
        
        } else if (self.schema[key].type.has_many) {
          var created_docs = [];
          var key_store = key;
          
          if(model_data[key]) {

            model_data[key].forEach(function (item) {
              created_docs.push(Model(item.model_type).load(item));
            });
          }
          
          model[key] = created_docs;
        
        } else if (model_data[key]) {
          model[key] = model_data[key]; 
        
        } else {
        model[key] = schema[key].default;
      }
    });

    if (model_data._id) {
      model.id = model_data._id;
    }

    model.dateCreated = model_data.dateCreated;
    model.lastUpdated = model_data.lastUpdated;
    
    
    return model;
  };

  self.create = function (model_data) {
    
    var model = self.load(model_data);
    self.beforeCreateFn && self.beforeCreateFn(model);
    
    return model;
  };

  self.onDocLoad(self.load);

};


// Mixins http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/
Queriable.call(ModelDocument.prototype);


var Model = function (model_type) {
  var model_document = defined_models[model_type];

  if (!model_document) {
    logger.error("No schema defined for", model_type);
    throw {
      message: "Model does not exist"
    }
  }

  if (model_document.instance) {
    return model_document.instance;
  }

  model_document.instance = new ModelDocument(model_type, model_document.schema); 

  return model_document.instance;
};

Model.create_connection= function (db_name) {
  return db_helper.create_connection(db_name);
}

Model.connect = Model.create_connection;

Model.create_views = function (model_type, model_schema) {
  logger.info("creating views for %s", model_type);
  var db = db_helper.connection();

  var model_views = {};

  Object.keys(model_schema).forEach(function (property) {
    model_views[property] = {};
    model_views[property].map = 'function (doc) {if (doc.model_type === \''+model_type+'\' && doc.' +property +') { emit(doc.' +property +',doc)} }'
  });

  model_views.all = {};
  model_views.all.map = 'function (doc) { if (doc.model_type === \''+model_type+'\'){emit(null, doc)}}';

  return model_views
};

Model.load = function () {
  if (arguments.length > 0) {
    var dir = path.normalize(arguments[0]);
    fs.readdirSync(dir).forEach(function (file) {
      var full_path = path.join(process.cwd(), dir,file);
      logger.info("loading " + full_path);
      require(full_path);
    });

  };

  logger.info("saving views");
  var db = db_helper.connection();

  Object.keys(defined_models).forEach(function (model_type) {
    var model_document = defined_models[model_type]

    db.save('_design/'+model_type, model_document.views, function (err, res) {
      if (err) {
        logger.error("Error creating views for $s %s",model_type, err);
      }
    });
  });
};<commit_msg>clean up file resolving on loading of models<commit_after>var fs = require('fs'),
    path = require('path'),
    async = require('async'),
    Saveable = require('./base').Saveable,
    Removeable  = require('./base').Removeable,
    Queriable = require('./query'),
    db_helper = require('./connection'),
    logger = require('./logger');

var defined_models = {};

var Document = function () {
  var self =  this;

  this.serialise = function () {
    var self = this;
    var serialised_doc = {};

    serialised_doc.dateCreated = self.dateCreated;
    serialised_doc.lastUpdated = self.lastUpdated;
    serialised_doc.model_type = self.model_type;


    // refactor to run through schema
    Object.keys(self.schema).forEach(function (key) {

      if (self.schema[key].type.has_one) {
        return serialised_doc[key] = self[key].serialise();
      }

      if (self.schema[key].type.has_many) {
        var many_docs = [];
        self[key].forEach( function (item) {
          many_docs.push(item.serialise());
        });

        return serialised_doc[key] = many_docs;
      }

      serialised_doc[key] = self[key] 

    });

    return serialised_doc;
  };

};

Saveable.call(Document.prototype);
Removeable.call(Document.prototype);

var ModelDocument = function (model_type, schema, views) {

  var self = this;
  var base = self;

  self.model_type = model_type;
  self.schema = schema;
  self.views = views;
  
  this.beforeSave = function (fn) {
    self.beforeSaveFn = fn;
  };

  this.afterSave = function (fn) {
    self.afterSaveFn = fn;
  };

  this.beforeCreate = function (fn) {
    self.beforeCreateFn = fn;
  };

  this.addView = function (view_name, view) {
    self.views[view_name] = view;
  };

  this.view = function (view_name, options, cb) {
    if (cb) {
      this._view(self.model_type + '/' + view_name, options, cb);
    } else {
      this._view(self.model_type + '/' + view_name, options);
    }
  };

  self.load = function (model_data) { 
    logger.info("Create model %s for %s", self.schema, model_data);

    var model = new Document();

    // TODO put into constructor
    model.beforeSaveFn = self.beforeSaveFn;
    model.afterSaveFn = self.beforeAfterFn;
    model.schema = self.schema;
    model.model_type = self.model_type;
    

    if (!model_data) return model;

    // TODO convert to correct type if needed
    Object.keys(self.schema).forEach(function (key) { 
        
        if (self.schema[key].type.has_one) {
          model[key] = self.schema[key].type.has_one.load(model_data[key]);
        
        } else if (self.schema[key].type.has_many) {
          var created_docs = [];
          var key_store = key;
          
          if(model_data[key]) {

            model_data[key].forEach(function (item) {
              created_docs.push(Model(item.model_type).load(item));
            });
          }
          
          model[key] = created_docs;
        
        } else if (model_data[key]) {
          model[key] = model_data[key]; 
        
        } else {
        model[key] = schema[key].default;
      }
    });

    if (model_data._id) {
      model.id = model_data._id;
    }

    model.dateCreated = model_data.dateCreated;
    model.lastUpdated = model_data.lastUpdated;
    
    
    return model;
  };

  self.create = function (model_data) {
    
    var model = self.load(model_data);
    self.beforeCreateFn && self.beforeCreateFn(model);
    
    return model;
  };

  self.onDocLoad(self.load);

};


// Mixins http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/
Queriable.call(ModelDocument.prototype);


var Model = function (model_type) {
  var model_document = defined_models[model_type];

  if (!model_document) {
    logger.error("No schema defined for", model_type);
    throw {
      message: "Model does not exist"
    }
  }

  if (model_document.instance) {
    return model_document.instance;
  }

  model_document.instance = new ModelDocument(model_type, model_document.schema); 

  return model_document.instance;
};

Model.create_connection= function (db_name) {
  return db_helper.create_connection(db_name);
}

Model.connect = Model.create_connection;

Model.create_views = function (model_type, model_schema) {
  logger.info("creating views for %s", model_type);
  var db = db_helper.connection();

  var model_views = {};

  Object.keys(model_schema).forEach(function (property) {
    model_views[property] = {};
    model_views[property].map = 'function (doc) {if (doc.model_type === \''+model_type+'\' && doc.' +property +') { emit(doc.' +property +',doc)} }'
  });

  model_views.all = {};
  model_views.all.map = 'function (doc) { if (doc.model_type === \''+model_type+'\'){emit(null, doc)}}';

  return model_views
};

Model.load = function () {
  if (arguments.length > 0) {
    var dir = path.resolve(process.cwd(),arguments[0]);
    fs.readdirSync(dir).forEach(function (file) {
      var full_path = path.join(dir,file);
      logger.info("loading " + full_path);
      require(full_path);
    });

  };

  logger.info("saving views");
  var db = db_helper.connection();

  Object.keys(defined_models).forEach(function (model_type) {
    var model_document = defined_models[model_type]

    db.save('_design/'+model_type, model_document.views, function (err, res) {
      if (err) {
        logger.error("Error creating views for $s %s",model_type, err);
      }
    });
  });
};
{'fraction_non_alphanumeric': 0.14346381093057606, 'fraction_numerical': 0.001846381093057607, 'mean_word_length': 2.8346902654867256, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6219691', 'n_tokens_mistral': 3574, 'n_tokens_neox': 3464, 'n_words': 658}