<commit_before>var config = require('../config/config.js'); 
var pg = require('pg');
var Sequelize = require('sequelize');
var bcrypt = require('bcrypt-nodejs');
var Promise = require('bluebird');


var connectionString = (process.env.NODE_ENV === 'test') ? config.testConnectionString : config.connectionString;
var sqldebug = process.env.SQL_DEBUG || false;
var db = new Sequelize(connectionString, {logging: sqldebug});

// Define table schemas
var User = db.define('user', {
  email: {
    type: Sequelize.STRING,
    unique: true,
    allowNull: false,
    validate: {isEmail: {msg: 'Invalid email'}}
  },
  displayName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false
  },
  avatarURL: {
    type: Sequelize.STRING,
    defaultValue: '' // Change to random default on signup
  },
  currentGroupId: {
    type: Sequelize.INTEGER,
    allowNull: false
  }
}, {
  classMethods: {
    hashPassword: function(password) {
      var hashAsync = Promise.promisify(bcrypt.hash);
      return hashAsync(password, null, null).bind(this);
    } 
  },
  instanceMethods: {
    comparePassword: function(attemptedPassword) {
      var compareAsync = Promise.promisify(bcrypt.compare);
      return compareAsync(attemptedPassword, this.password);
    } 
  },
  hooks: {
    beforeCreate: function(user, options) {
      return this.hashPassword(user.password)
        .then(function(hash) {
          user.password = hash;
        });
    },
  }
});

var Group = db.define('group', {
  name: {
    type: Sequelize.STRING,
    allowNull: false
  },
  bannerUrl: {
    type: Sequelize.STRING,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  }
});

var Song = db.define('song', {
  title: {
    type: Sequelize.STRING,
    allowNull: false
  },
  description: {
    type: Sequelize.STRING,
    allowNull: false
  },
  dateRecorded: {
    type: Sequelize.DATE,
    allowNull: false
  },
  duration: {
    type: Sequelize.INTEGER,
    allowNull: false
  },
  address: {
    type: Sequelize.STRING,
    allowNull: false,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  },
  imageUrl: {
    type: Sequelize.STRING,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  }
});

var Playlist = db.define('playlist', {
  title: {
    type: Sequelize.STRING,
    allowNull: false
  },
  description: {
    type: Sequelize.STRING,
  }
});

var Comment = db.define('comment', {
  time: {
    type: Sequelize.INTEGER
  },
  note: {
    type: Sequelize.STRING
  }
});

// Define join tables
var UserGroups = db.define('userGroups', {
  role: {
    type: Sequelize.STRING,
  }}, 
  {timestamps: false}
);

var PlaylistSongs = db.define('playlistSongs', {
  listPosition: {
    type: Sequelize.INTEGER,
  }}
);

// Define associations
Group.belongsToMany(User, {through: 'userGroups'});
User.belongsToMany(Group, {through: 'userGroups'});

Group.hasMany(Song);
Song.belongsTo(Group);

Group.hasMany(Playlist);
Playlist.belongsTo(Group);

Playlist.belongsToMany(User, {through: 'playlistSongs'});
Song.belongsToMany(Group, {through: 'playlistSongs'});

User.hasMany(Comment);
Comment.belongsTo(User);

Song.hasMany(Comment);
Comment.belongsTo(Song);


var logSync = false; //(process.env.NODE_ENV === 'test') ? false : console.log;

// Sync models to define postgres tables and capture associations
User.sync()
  .then(function() {
    return Group.sync();
  })
  .then(function() {
    return Playlist.sync();
  })
  .then(function() {
    return Song.sync();
  })
  .then(function() {
    return UserGroups.sync();
  })
  .then(function() {
    return PlaylistSongs.sync();
  })
  .then(function() {
    return Comment.sync();
  });

module.exports = {
  db: db,
  User: User,
  Group: Group,
  UserGroups: UserGroups,
  Song: Song,
  Playlist: Playlist,
  PlaylistSongs: PlaylistSongs,
  Comment: Comment
};

// Command to drop all tables in postgres
// drop table users cascade; drop table groups cascade; drop table users; drop table groups; drop table "userGroups"; drop table playlists; drop table songs; drop table "playlistSongs";<commit_msg>(fix) Fix typo and update drop comment in DB<commit_after>var config = require('../config/config.js'); 
var pg = require('pg');
var Sequelize = require('sequelize');
var bcrypt = require('bcrypt-nodejs');
var Promise = require('bluebird');


var connectionString = (process.env.NODE_ENV === 'test') ? config.testConnectionString : config.connectionString;
var sqldebug = process.env.SQL_DEBUG || false;
var db = new Sequelize(connectionString, {logging: sqldebug});

// Define table schemas
var User = db.define('user', {
  email: {
    type: Sequelize.STRING,
    unique: true,
    allowNull: false,
    validate: {isEmail: {msg: 'Invalid email'}}
  },
  displayName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false
  },
  avatarURL: {
    type: Sequelize.STRING,
    defaultValue: '' // Change to random default on signup
  },
  currentGroupId: {
    type: Sequelize.INTEGER,
    allowNull: false
  }
}, {
  classMethods: {
    hashPassword: function(password) {
      var hashAsync = Promise.promisify(bcrypt.hash);
      return hashAsync(password, null, null).bind(this);
    } 
  },
  instanceMethods: {
    comparePassword: function(attemptedPassword) {
      var compareAsync = Promise.promisify(bcrypt.compare);
      return compareAsync(attemptedPassword, this.password);
    } 
  },
  hooks: {
    beforeCreate: function(user, options) {
      return this.hashPassword(user.password)
        .then(function(hash) {
          user.password = hash;
        });
    },
  }
});

var Group = db.define('group', {
  name: {
    type: Sequelize.STRING,
    allowNull: false
  },
  bannerUrl: {
    type: Sequelize.STRING,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  }
});

var Song = db.define('song', {
  title: {
    type: Sequelize.STRING,
    allowNull: false
  },
  description: {
    type: Sequelize.STRING,
    allowNull: false
  },
  dateRecorded: {
    type: Sequelize.DATE,
    allowNull: false
  },
  duration: {
    type: Sequelize.INTEGER,
    allowNull: false
  },
  address: {
    type: Sequelize.STRING,
    allowNull: false,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  },
  imageUrl: {
    type: Sequelize.STRING,
    defaultValue: 'http://i.imgur.com/QI8f5gx.jpg' // Update
  }
});

var Playlist = db.define('playlist', {
  title: {
    type: Sequelize.STRING,
    allowNull: false
  },
  description: {
    type: Sequelize.STRING,
  }
});

var Comment = db.define('comment', {
  time: {
    type: Sequelize.INTEGER
  },
  note: {
    type: Sequelize.STRING
  }
});

// Define join tables
var UserGroups = db.define('userGroups', {
  role: {
    type: Sequelize.STRING,
  }}, 
  {timestamps: false}
);

var PlaylistSongs = db.define('playlistSongs', {
  listPosition: {
    type: Sequelize.INTEGER,
  }}
);

// Define associations
Group.belongsToMany(User, {through: 'userGroups'});
User.belongsToMany(Group, {through: 'userGroups'});

Group.hasMany(Song);
Song.belongsTo(Group);

Group.hasMany(Playlist);
Playlist.belongsTo(Group);

Playlist.belongsToMany(Song, {through: 'playlistSongs'});
Song.belongsToMany(Playlist, {through: 'playlistSongs'});

User.hasMany(Comment);
Comment.belongsTo(User);

Song.hasMany(Comment);
Comment.belongsTo(Song);


var logSync = false; //(process.env.NODE_ENV === 'test') ? false : console.log;

// Sync models to define postgres tables and capture associations
User.sync()
  .then(function() {
    return Group.sync();
  })
  .then(function() {
    return Playlist.sync();
  })
  .then(function() {
    return Song.sync();
  })
  .then(function() {
    return UserGroups.sync();
  })
  .then(function() {
    return PlaylistSongs.sync();
  })
  .then(function() {
    return Comment.sync();
  });

module.exports = {
  db: db,
  User: User,
  Group: Group,
  UserGroups: UserGroups,
  Song: Song,
  Playlist: Playlist,
  PlaylistSongs: PlaylistSongs,
  Comment: Comment
};

// Command to drop all tables in postgres
// drop table users cascade; drop table groups cascade; drop table users; drop table groups; drop table "userGroups"; drop table playlists; drop table songs cascade; drop table "playlistSongs";
{'fraction_non_alphanumeric': 0.14588348579682234, 'fraction_numerical': 0.0014443909484833895, 'mean_word_length': 3.4196808510638297, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5178310', 'n_tokens_mistral': 2850, 'n_tokens_neox': 2794, 'n_words': 602}