Merge pull request #263 from lbryio/db-datatypes-migration
Db datatypes migration
This commit is contained in:
commit
ab3d6243e8
19 changed files with 150 additions and 101 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
node_modules
|
||||
.idea
|
||||
config/config.json
|
||||
config/sequelizeCliConfig.js
|
||||
config/speechConfig.js
|
5
.sequelizerc
Normal file
5
.sequelizerc
Normal file
|
@ -0,0 +1,5 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
'config': path.resolve('config', 'sequelizeCliConfig.js'),
|
||||
}
|
23
config/sequelizeCliConfig.js.example
Normal file
23
config/sequelizeCliConfig.js.example
Normal file
|
@ -0,0 +1,23 @@
|
|||
module.exports = {
|
||||
development: {
|
||||
username: '',
|
||||
password: '',
|
||||
database: '',
|
||||
host : '127.0.0.1',
|
||||
dialect : 'mysql',
|
||||
},
|
||||
test: {
|
||||
username: '',
|
||||
password: '',
|
||||
database: '',
|
||||
host : '127.0.0.1',
|
||||
dialect : 'mysql',
|
||||
},
|
||||
production: {
|
||||
username: '',
|
||||
password: '',
|
||||
database: '',
|
||||
host : '127.0.0.1',
|
||||
dialect : 'mysql',
|
||||
},
|
||||
};
|
|
@ -19,4 +19,7 @@ module.exports = {
|
|||
session: {
|
||||
sessionKey: null, // enter a secret key to be used for session encryption
|
||||
},
|
||||
files: {
|
||||
uploadDirectory: null, // enter file path to where uploads/publishes should be stored
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
// logic for transforming into the new state
|
||||
const p1 = queryInterface.addColumn(
|
||||
'Claim',
|
||||
'channelName',
|
||||
{
|
||||
type : Sequelize.STRING,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
return Promise.all([p1]);
|
||||
},
|
||||
down: (queryInterface, Sequelize) => {
|
||||
// logic for reverting the changes
|
||||
const p1 = queryInterface.removeColumn(
|
||||
'Claim',
|
||||
'channelName'
|
||||
);
|
||||
return Promise.all([p1]);
|
||||
},
|
||||
};
|
42
migrations/ChangeCertificateColumnTypes2.js
Normal file
42
migrations/ChangeCertificateColumnTypes2.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
// logic for transforming into the new state
|
||||
const p1 = queryInterface.changeColumn(
|
||||
'Certificate',
|
||||
'amount',
|
||||
{
|
||||
type : Sequelize.DECIMAL(19, 8),
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
const p2 = queryInterface.changeColumn(
|
||||
'Certificate',
|
||||
'effectiveAmount',
|
||||
{
|
||||
type : Sequelize.DECIMAL(19, 8),
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
return Promise.all([p1, p2]);
|
||||
},
|
||||
down: (queryInterface, Sequelize) => {
|
||||
// logic for reverting the changes
|
||||
const p1 = queryInterface.changeColumn(
|
||||
'Certificate',
|
||||
'amount',
|
||||
{
|
||||
type : Sequelize.DOUBLE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
const p2 = queryInterface.changeColumn(
|
||||
'Certificate',
|
||||
'effectiveAmount',
|
||||
{
|
||||
type : Sequelize.DOUBLE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
return Promise.all([p1, p2]);
|
||||
},
|
||||
};
|
42
migrations/ChangeClaimColumnTypes.js
Normal file
42
migrations/ChangeClaimColumnTypes.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
// logic for transforming into the new state
|
||||
const p1 = queryInterface.changeColumn(
|
||||
'Claim',
|
||||
'amount',
|
||||
{
|
||||
type : Sequelize.DECIMAL(19, 8),
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
const p2 = queryInterface.changeColumn(
|
||||
'Claim',
|
||||
'effectiveAmount',
|
||||
{
|
||||
type : Sequelize.DECIMAL(19, 8),
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
return Promise.all([p1, p2]);
|
||||
},
|
||||
down: (queryInterface, Sequelize) => {
|
||||
// logic for reverting the changes
|
||||
const p1 = queryInterface.changeColumn(
|
||||
'Claim',
|
||||
'amount',
|
||||
{
|
||||
type : Sequelize.DOUBLE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
const p2 = queryInterface.changeColumn(
|
||||
'Claim',
|
||||
'effectiveAmount',
|
||||
{
|
||||
type : Sequelize.DOUBLE,
|
||||
allowNull: true,
|
||||
}
|
||||
);
|
||||
return Promise.all([p1, p2]);
|
||||
},
|
||||
};
|
|
@ -1,46 +0,0 @@
|
|||
const db = require('../models');
|
||||
const bcrypt = require('bcrypt');
|
||||
const logger = require('winston');
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
// get all the users
|
||||
return db.User
|
||||
.findAll()
|
||||
.then((users) => {
|
||||
// create an array of promises, with each promise bcrypting a password and updating the record
|
||||
const promises = users.map((record) => {
|
||||
// bcrypt
|
||||
// generate a salt string to use for hashing
|
||||
return new Promise((resolve, reject) => {
|
||||
bcrypt.genSalt((saltError, salt) => {
|
||||
if (saltError) {
|
||||
logger.error('salt error', saltError);
|
||||
reject(saltError);
|
||||
return;
|
||||
}
|
||||
// generate a hashed version of the user's password
|
||||
bcrypt.hash(record.password, salt, (hashError, hash) => {
|
||||
// if there is an error with the hash generation return the error
|
||||
if (hashError) {
|
||||
logger.error('hash error', hashError);
|
||||
reject(hashError);
|
||||
return;
|
||||
}
|
||||
// replace the password string with the hash password value
|
||||
resolve(queryInterface.sequelize.query(`UPDATE User SET User.password = "${hash}" WHERE User.id = ${record.id}`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
// return the array of promises
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('error prepping promises array', error);
|
||||
});
|
||||
},
|
||||
down: (queryInterface, Sequelize) => {
|
||||
// logic for reverting the changes
|
||||
},
|
||||
};
|
|
@ -2,7 +2,7 @@ const logger = require('winston');
|
|||
const { returnShortId } = require('../helpers/sequelizeHelpers.js');
|
||||
const NO_CHANNEL = 'NO_CHANNEL';
|
||||
|
||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
|
||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||
const Certificate = sequelize.define(
|
||||
'Certificate',
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
|
|||
default: null,
|
||||
},
|
||||
amount: {
|
||||
type : STRING,
|
||||
type : DECIMAL(19, 8),
|
||||
default: null,
|
||||
},
|
||||
claimId: {
|
||||
|
@ -31,7 +31,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
|
|||
default: null,
|
||||
},
|
||||
effectiveAmount: {
|
||||
type : STRING,
|
||||
type : DECIMAL(19, 8),
|
||||
default: null,
|
||||
},
|
||||
hasSignature: {
|
||||
|
@ -39,7 +39,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
|
|||
default: null,
|
||||
},
|
||||
height: {
|
||||
type : STRING,
|
||||
type : INTEGER,
|
||||
default: null,
|
||||
},
|
||||
hex: {
|
||||
|
@ -59,7 +59,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT }) => {
|
|||
default: null,
|
||||
},
|
||||
validAtHeight: {
|
||||
type : STRING,
|
||||
type : INTEGER,
|
||||
default: null,
|
||||
},
|
||||
outpoint: {
|
||||
|
|
|
@ -2,7 +2,7 @@ const logger = require('winston');
|
|||
const { returnShortId } = require('../helpers/sequelizeHelpers.js');
|
||||
const NO_CLAIM = 'NO_CLAIM';
|
||||
|
||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE, Op }) => {
|
||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, DECIMAL }) => {
|
||||
const Claim = sequelize.define(
|
||||
'Claim',
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
|||
default: null,
|
||||
},
|
||||
amount: {
|
||||
type : STRING,
|
||||
type : DECIMAL(19, 8),
|
||||
default: null,
|
||||
},
|
||||
claimId: {
|
||||
|
@ -31,7 +31,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
|||
default: null,
|
||||
},
|
||||
effectiveAmount: {
|
||||
type : STRING,
|
||||
type : DECIMAL(19, 8),
|
||||
default: null,
|
||||
},
|
||||
hasSignature: {
|
||||
|
@ -39,7 +39,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
|||
default: null,
|
||||
},
|
||||
height: {
|
||||
type : STRING,
|
||||
type : INTEGER,
|
||||
default: null,
|
||||
},
|
||||
hex: {
|
||||
|
@ -59,7 +59,7 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
|||
default: null,
|
||||
},
|
||||
validAtHeight: {
|
||||
type : STRING,
|
||||
type : INTEGER,
|
||||
default: null,
|
||||
},
|
||||
outpoint: {
|
||||
|
|
|
@ -2,19 +2,20 @@ const fs = require('fs');
|
|||
const path = require('path');
|
||||
const Sequelize = require('sequelize');
|
||||
const basename = path.basename(module.filename);
|
||||
const config = require('../config/speechConfig.js');
|
||||
const db = {};
|
||||
const logger = require('winston');
|
||||
|
||||
const config = require('../config/speechConfig.js');
|
||||
const database = config.sql.database;
|
||||
const username = config.sql.username;
|
||||
const password = config.sql.password;
|
||||
const db = {};
|
||||
|
||||
// set sequelize options
|
||||
const sequelize = new Sequelize(database, username, password, {
|
||||
host : 'localhost',
|
||||
dialect: 'mysql',
|
||||
logging: false,
|
||||
pool : {
|
||||
host : 'localhost',
|
||||
dialect : 'mysql',
|
||||
dialectOptions: {decimalNumbers: true}, // fix to ensure DECIMAL will not be stored as a string
|
||||
logging : false,
|
||||
pool : {
|
||||
max : 5,
|
||||
min : 0,
|
||||
idle : 10000,
|
||||
|
@ -53,6 +54,7 @@ Object.keys(db).forEach(modelName => {
|
|||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
// add an 'upsert' method to the db object
|
||||
db.upsert = (Model, values, condition, tableName) => {
|
||||
return Model
|
||||
.findOne({ where: condition })
|
||||
|
@ -70,6 +72,7 @@ db.upsert = (Model, values, condition, tableName) => {
|
|||
});
|
||||
};
|
||||
|
||||
// add a 'getTrendingClaims' method to the db object
|
||||
db.getTrendingClaims = (startDate) => {
|
||||
return db.sequelize.query(`SELECT COUNT(*), File.* FROM Request LEFT JOIN File ON Request.FileId = File.id WHERE FileId IS NOT NULL AND nsfw != 1 AND trendingEligible = 1 AND Request.createdAt > "${startDate}" GROUP BY FileId ORDER BY COUNT(*) DESC LIMIT 25;`, { type: db.sequelize.QueryTypes.SELECT });
|
||||
};
|
||||
|
|
|
@ -75,7 +75,7 @@ body, .flex-container--column {
|
|||
|
||||
/* TEXT */
|
||||
|
||||
body, button, input, textarea, label, select, option {
|
||||
body, button, input, textarea, label, select, option, #channel-publish-in-progress > p, #channel-publish-done > p {
|
||||
font-family: 'Lekton', monospace;
|
||||
font-size: large;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// display the content that shows channel creation has started
|
||||
function showChannelCreateInProgressDisplay () {
|
||||
const publishChannelForm = document.getElementById('publish-channel-form');
|
||||
publishChannelForm.hidden = true;
|
||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
||||
const channelProgressBar = document.getElementById('create-channel-progress-bar');
|
||||
publishChannelForm.hidden = true;
|
||||
inProgress.hidden = false;
|
||||
createProgressBar(document.getElementById('create-channel-progress-bar'), 12);
|
||||
createProgressBar(channelProgressBar, 12);
|
||||
}
|
||||
|
||||
// display the content that shows channle creation is done
|
||||
function showChannelCreateDoneDisplay() {
|
||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
||||
inProgress.hidden=true;
|
||||
|
@ -38,7 +41,6 @@ function publishNewChannel (event) {
|
|||
if (window.location.pathname === '/') {
|
||||
// remove old channel and replace with new one & select it
|
||||
replaceChannelOptionInPublishChannelSelect();
|
||||
// remove old channel and replace with new one & select it
|
||||
replaceChannelOptionInNavBarChannelSelect();
|
||||
} else {
|
||||
window.location = '/';
|
||||
|
@ -47,7 +49,7 @@ function publishNewChannel (event) {
|
|||
.catch(error => {
|
||||
if (error.name === 'ChannelNameError' || error.name === 'ChannelPasswordError'){
|
||||
const channelNameErrorDisplayElement = document.getElementById('input-error-channel-name');
|
||||
showError(channelNameErrorDisplayElement, error.message);
|
||||
validationFunctions.showError(channelNameErrorDisplayElement, error.message);
|
||||
} else {
|
||||
console.log('signup failure:', error);
|
||||
showChannelCreationError('Unfortunately, Spee.ch encountered an error while creating your channel. Please let us know in slack!');
|
||||
|
|
|
@ -151,7 +151,7 @@ function copyToClipboard(event){
|
|||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
showError(errorElement, 'Oops, unable to copy');
|
||||
validationFunctions.showError(errorElement, 'Oops, unable to copy');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ const validationFunctions = {
|
|||
},
|
||||
// validation function that checks to make sure the claim name is valid
|
||||
validateClaimName: function (name) {
|
||||
console.log('validating the claim name');
|
||||
// ensure a name was entered
|
||||
if (name.length < 1) {
|
||||
throw new NameError("You must enter a name for your url");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const logger = require('winston');
|
||||
const multipart = require('connect-multiparty');
|
||||
const multipartMiddleware = multipart({uploadDir: '/home/lbry/test/'});
|
||||
const config = require('../config/speechConfig.js');
|
||||
const multipartMiddleware = multipart({uploadDir: config.files.uploadDirectory});
|
||||
const db = require('../models');
|
||||
const { publish } = require('../controllers/publishController.js');
|
||||
const { getClaimList, resolveUri } = require('../helpers/lbryApi.js');
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// load dependencies
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const siofu = require('socketio-file-upload');
|
||||
const expressHandlebars = require('express-handlebars');
|
||||
const Handlebars = require('handlebars');
|
||||
const handlebarsHelpers = require('./helpers/handlebarsHelpers.js');
|
||||
|
@ -32,7 +31,6 @@ app.use(helmet()); // set HTTP headers to protect against well-known web vulnera
|
|||
app.use(express.static(`${__dirname}/public`)); // 'express.static' to serve static files from public directory
|
||||
app.use(bodyParser.json()); // 'body parser' for parsing application/json
|
||||
app.use(bodyParser.urlencoded({ extended: true })); // 'body parser' for parsing application/x-www-form-urlencoded
|
||||
app.use(siofu.router); // 'socketio-file-upload' router for uploading with socket.io
|
||||
app.use((req, res, next) => { // custom logging middleware to log all incoming http requests
|
||||
logger.verbose(`Request on ${req.originalUrl} from ${req.ip}`);
|
||||
logger.debug('req.body:', req.body);
|
||||
|
@ -76,7 +74,7 @@ db.sequelize
|
|||
.then(hostedContentPath => {
|
||||
// add the hosted content folder at a static path
|
||||
app.use('/media', express.static(hostedContentPath));
|
||||
// require routes & wrap in socket.io
|
||||
// require routes
|
||||
require('./routes/auth-routes.js')(app);
|
||||
require('./routes/api-routes.js')(app);
|
||||
require('./routes/page-routes.js')(app);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="row row--tall flex-container--column">
|
||||
<form>
|
||||
<input class="input-file" type="file" id="siofu_input" name="siofu_input" accept="video/*,image/*" onchange="publishFileFunctions.previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
<input class="input-file" type="file" id="file_input" name="file_input" accept="video/*,image/*" onchange="publishFileFunctions.previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
||||
</form>
|
||||
<div id="primary-dropzone" class="dropzone row row--margined row--padded row--tall flex-container--column flex-container--center-center" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="dragenter_handler(event)" ondragleave="dragexit_handler(event)" onclick="publishFileFunctions.triggerFileChooser('siofu_input', event)">
|
||||
<div id="primary-dropzone" class="dropzone row row--margined row--padded row--tall flex-container--column flex-container--center-center" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="dragenter_handler(event)" ondragleave="dragexit_handler(event)" onclick="publishFileFunctions.triggerFileChooser('file_input', event)">
|
||||
<div id="primary-dropzone-instructions">
|
||||
<p class="info-message-placeholder info-message--failure" id="input-error-file-selection" hidden="true"></p>
|
||||
<p>Drag & drop image or video here to publish</p>
|
||||
|
@ -22,7 +22,7 @@
|
|||
<div class="column column--5 column--sml-10" >
|
||||
<!-- preview -->
|
||||
<div class="row row--padded">
|
||||
<div id="asset-preview-holder" class="dropzone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="preview_onmouseenter_handler()" ondragleave="preview_onmouseleave_handler()" onmouseenter="preview_onmouseenter_handler()" onmouseleave="preview_onmouseleave_handler()" onclick="publishFileFunctions.triggerFileChooser('siofu_input', event)">
|
||||
<div id="asset-preview-holder" class="dropzone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="preview_onmouseenter_handler()" ondragleave="preview_onmouseleave_handler()" onmouseenter="preview_onmouseenter_handler()" onmouseleave="preview_onmouseleave_handler()" onclick="publishFileFunctions.triggerFileChooser('file_input', event)">
|
||||
<div id="asset-preview-dropzone-instructions" class="hidden">
|
||||
<p>Drag & drop image or video here</p>
|
||||
<p class="fine-print">OR</p>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
// hide the login and new channel forms
|
||||
loginToChannelTool.hidden = true;
|
||||
createChannelTool.hidden = true;
|
||||
hideError(document.getElementById('input-error-channel-select'));
|
||||
validationFunctions.hideError(document.getElementById('input-error-channel-select'));
|
||||
}
|
||||
// update url
|
||||
updateUrl(selectedChannel);
|
||||
|
|
Loading…
Reference in a new issue