<commit_before>'use strict';

var Attribute = require('./Attribute');
var errors = require('./errors');
var VirtualType = require('./VirtualType');
//var util = require('util');

var debug = require('debug')('dynamoose:schema');



function Schema(obj, options) {
  debug('Creating Schema', obj);

  this.options = options || {};

  this.methods = {};
  this.statics = {};
  this.virtuals = {};
  this.tree = {};

  if(this.options.throughput) {
    var throughput = this.options.throughput;
    if(typeof throughput === 'number') {
      throughput = {read: throughput, write: throughput};
    }
    this.throughput = throughput;
  } else {
    this.throughput = {read: 1, write: 1};
  }

  if((!this.throughput.read || !this.throughput.write) &&
    this.throughput.read >= 1 && this.throughput.write >= 1) {
    throw new errors.SchemaError('Invalid throughput: '+ this.throughput);
  }

  /*
    * Added support for timestamps attribute
    */
  if (this.options.timestamps) {
    var createdAt = null;
    var updatedAt = null;

    if (this.options.timestamps === true) {
      createdAt = 'createdAt';
      updatedAt = 'updatedAt';
    } else if (typeof this.options.timestamps === 'object') {
      if (this.options.timestamps.createdAt && this.options.timestamps.updatedAt) {
        createdAt = this.options.timestamps.createdAt;
        updatedAt = this.options.timestamps.updatedAt;
      } else {
        throw new errors.SchemaError('Missing createdAt and updatedAt timestamps attribute. Maybe set timestamps: true?');
      }
    } else {
      throw new errors.SchemaError('Invalid syntax for timestamp: ' + name);
    }

    obj[createdAt] = { type: Date, default: Date.now };
    obj[updatedAt] = { type: Date, default: Date.now, set: function() { return Date.now(); } };
    this.timestamps = { createdAt: createdAt, updatedAt: updatedAt };
  }

  this.useDocumentTypes = !!this.options.useDocumentTypes;
  this.useNativeBooleans = !!this.options.useNativeBooleans;

  this.attributes = {};
  this.indexes = {local: {}, global: {}};

  for(var n in obj) {

    if(this.attributes[n]) {
      throw new errors.SchemaError('Duplicate attribute: ' + n);
    }

    debug('Adding Attribute to Schema (%s)', n, obj);
    this.attributes[n] = Attribute.create(this, n, obj[n]);
  }
}

/*Schema.prototype.attribute = function(name, obj) {
  debug('Adding Attribute to Schema (%s)', name, obj);

  this Attribute.create(name, obj);

};*/

Schema.prototype.toDynamo = function(model) {

  var dynamoObj = {};

  for(var name in model) {
    if(!model.hasOwnProperty(name)){
      continue;
    }
    var attr = this.attributes[name];

    if(!attr & this.options.saveUnknown) {
      attr = Attribute.create(this, name, typeof model[name]);
      this.attributes[name] = attr;
    }

    if(attr) {
      attr.setDefault(model);
      var dynamoAttr = attr.toDynamo(model[name], undefined, model);
      if(dynamoAttr) {
        dynamoObj[attr.name] = dynamoAttr;
      }
    }
  }

  debug('toDynamo: %s', JSON.stringify(dynamoObj) );
  return dynamoObj;
};

Schema.prototype.parseDynamo = function(model, dynamoObj) {

  for(var name in dynamoObj) {
    var attr = this.attributes[name];

    if(!attr & this.options.saveUnknown) {
      attr = Attribute.create(this, name, Object);
      this.attributes[name] = attr;
    }

    if(attr) {
      var attrVal = attr.parseDynamo(dynamoObj[name]);
      if(attrVal !== undefined && attrVal !== null){
        model[name] = attrVal;<commit_msg>fix not appling default to undefined attributes<commit_after>'use strict';

var Attribute = require('./Attribute');
var errors = require('./errors');
var VirtualType = require('./VirtualType');
//var util = require('util');

var debug = require('debug')('dynamoose:schema');



function Schema(obj, options) {
  debug('Creating Schema', obj);

  this.options = options || {};

  this.methods = {};
  this.statics = {};
  this.virtuals = {};
  this.tree = {};

  if(this.options.throughput) {
    var throughput = this.options.throughput;
    if(typeof throughput === 'number') {
      throughput = {read: throughput, write: throughput};
    }
    this.throughput = throughput;
  } else {
    this.throughput = {read: 1, write: 1};
  }

  if((!this.throughput.read || !this.throughput.write) &&
    this.throughput.read >= 1 && this.throughput.write >= 1) {
    throw new errors.SchemaError('Invalid throughput: '+ this.throughput);
  }

  /*
    * Added support for timestamps attribute
    */
  if (this.options.timestamps) {
    var createdAt = null;
    var updatedAt = null;

    if (this.options.timestamps === true) {
      createdAt = 'createdAt';
      updatedAt = 'updatedAt';
    } else if (typeof this.options.timestamps === 'object') {
      if (this.options.timestamps.createdAt && this.options.timestamps.updatedAt) {
        createdAt = this.options.timestamps.createdAt;
        updatedAt = this.options.timestamps.updatedAt;
      } else {
        throw new errors.SchemaError('Missing createdAt and updatedAt timestamps attribute. Maybe set timestamps: true?');
      }
    } else {
      throw new errors.SchemaError('Invalid syntax for timestamp: ' + name);
    }

    obj[createdAt] = { type: Date, default: Date.now };
    obj[updatedAt] = { type: Date, default: Date.now, set: function() { return Date.now(); } };
    this.timestamps = { createdAt: createdAt, updatedAt: updatedAt };
  }

  this.useDocumentTypes = !!this.options.useDocumentTypes;
  this.useNativeBooleans = !!this.options.useNativeBooleans;

  this.attributes = {};
  this.indexes = {local: {}, global: {}};

  for(var n in obj) {

    if(this.attributes[n]) {
      throw new errors.SchemaError('Duplicate attribute: ' + n);
    }

    debug('Adding Attribute to Schema (%s)', n, obj);
    this.attributes[n] = Attribute.create(this, n, obj[n]);
  }
}

/*Schema.prototype.attribute = function(name, obj) {
  debug('Adding Attribute to Schema (%s)', name, obj);

  this Attribute.create(name, obj);

};*/

Schema.prototype.toDynamo = function(model) {

  var dynamoObj = {};
  var name, attr;

  for(name in model) {
    if(!model.hasOwnProperty(name)){
      continue;
    }
    attr = this.attributes[name];

    if(!attr & this.options.saveUnknown) {
      attr = Attribute.create(this, name, typeof model[name]);
      this.attributes[name] = attr;
    }
  }

  for(name in this.attributes) {
    attr = this.attributes[name];

    attr.setDefault(model);
    var dynamoAttr = attr.toDynamo(model[name], undefined, model);
    if(dynamoAttr) {
      dynamoObj[attr.name] = dynamoAttr;
    }
  }

  debug('toDynamo: %s', JSON.stringify(dynamoObj) );
  return dynamoObj;
};

Schema.prototype.parseDynamo = function(model, dynamoObj) {

  for(var name in dynamoObj) {
    var attr = this.attributes[name];

    if(!attr & this.options.saveUnknown) {
      attr = Attribute.create(this, name, Object);
      this.attributes[name] = attr;
    }

    if(attr) {
      var attrVal = attr.parseDynamo(dynamoObj[name]);
      if(attrVal !== undefined && attrVal !== null){
        model[name] = attrVal;
{'fraction_non_alphanumeric': 0.15198082616664316, 'fraction_numerical': 0.0011278725504018047, 'mean_word_length': 3.2529976019184654, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '4841201', 'n_tokens_mistral': 2300, 'n_tokens_neox': 2207, 'n_words': 488}