Sequelize queries #234
|
@ -64,10 +64,10 @@ function getAssetByLongClaimId (fullClaimId, name) {
|
||||||
}
|
}
|
||||||
logger.debug('no local file found for this name and claimId');
|
logger.debug('no local file found for this name and claimId');
|
||||||
// 2. if no local claim, resolve and get the claim
|
// 2. if no local claim, resolve and get the claim
|
||||||
db
|
db.Claim
|
||||||
.resolveClaim(name, fullClaimId)
|
.resolveClaim(name, fullClaimId)
|
||||||
.then(resolveResult => {
|
.then(resolveResult => {
|
||||||
logger.debug('resolve result >> ', resolveResult);
|
logger.debug('resolve result >> ', resolveResult.dataValues);
|
||||||
// if no result, return early (claim doesn't exist or isn't free)
|
// if no result, return early (claim doesn't exist or isn't free)
|
||||||
if (!resolveResult) {
|
if (!resolveResult) {
|
||||||
resolve(NO_CLAIM);
|
resolve(NO_CLAIM);
|
||||||
|
@ -112,9 +112,9 @@ module.exports = {
|
||||||
getAssetByClaim (claimName, claimId) {
|
getAssetByClaim (claimName, claimId) {
|
||||||
logger.debug(`getAssetByClaim(${claimName}, ${claimId})`);
|
logger.debug(`getAssetByClaim(${claimName}, ${claimId})`);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
db.getLongClaimId(claimName, claimId) // 1. get the long claim id
|
db.Claim.getLongClaimId(claimName, claimId) // 1. get the long claim id
|
||||||
.then(result => { // 2. get the asset using the long claim id
|
.then(result => { // 2. get the asset using the long claim id
|
||||||
logger.debug('getLongClaimId result:', result);
|
logger.debug('long claim id ===', result);
|
||||||
if (result === NO_CLAIM) {
|
if (result === NO_CLAIM) {
|
||||||
logger.debug('resolving NO_CLAIM');
|
logger.debug('resolving NO_CLAIM');
|
||||||
resolve(NO_CLAIM);
|
resolve(NO_CLAIM);
|
||||||
|
@ -130,13 +130,13 @@ module.exports = {
|
||||||
getAssetByChannel (channelName, channelId, claimName) {
|
getAssetByChannel (channelName, channelId, claimName) {
|
||||||
logger.debug('getting asset by channel');
|
logger.debug('getting asset by channel');
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
db.getLongChannelId(channelName, channelId) // 1. get the long channel id
|
db.Certificate.getLongChannelId(channelName, channelId) // 1. get the long channel id
|
||||||
.then(result => { // 2. get the long claim Id
|
.then(result => { // 2. get the long claim Id
|
||||||
if (result === NO_CHANNEL) {
|
if (result === NO_CHANNEL) {
|
||||||
resolve(NO_CHANNEL);
|
resolve(NO_CHANNEL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return db.getClaimIdByLongChannelId(result, claimName);
|
return db.Claim.getClaimIdByLongChannelId(result, claimName);
|
||||||
})
|
})
|
||||||
.then(result => { // 3. get the asset using the long claim id
|
.then(result => { // 3. get the asset using the long claim id
|
||||||
logger.debug('asset claim id =', result);
|
logger.debug('asset claim id =', result);
|
||||||
|
@ -155,20 +155,20 @@ module.exports = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let longChannelId;
|
let longChannelId;
|
||||||
let shortChannelId;
|
let shortChannelId;
|
||||||
db.getLongChannelId(channelName, channelId) // 1. get the long channel Id
|
db.Certificate.getLongChannelId(channelName, channelId) // 1. get the long channel Id
|
||||||
.then(result => { // 2. get all claims for that channel
|
.then(result => { // 2. get all claims for that channel
|
||||||
if (result === NO_CHANNEL) {
|
if (result === NO_CHANNEL) {
|
||||||
return NO_CHANNEL;
|
return NO_CHANNEL;
|
||||||
}
|
}
|
||||||
longChannelId = result;
|
longChannelId = result;
|
||||||
return db.getShortChannelIdFromLongChannelId(longChannelId, channelName);
|
return db.Certificate.getShortChannelIdFromLongChannelId(longChannelId, channelName);
|
||||||
})
|
})
|
||||||
.then(result => { // 3. get all Claim records for this channel
|
.then(result => { // 3. get all Claim records for this channel
|
||||||
if (result === NO_CHANNEL) {
|
if (result === NO_CHANNEL) {
|
||||||
return NO_CHANNEL;
|
return NO_CHANNEL;
|
||||||
}
|
}
|
||||||
shortChannelId = result;
|
shortChannelId = result;
|
||||||
return db.getAllChannelClaims(longChannelId);
|
return db.Claim.getAllChannelClaims(longChannelId);
|
||||||
})
|
})
|
||||||
.then(result => { // 4. add extra data not available from Claim table
|
.then(result => { // 4. add extra data not available from Claim table
|
||||||
if (result === NO_CHANNEL) {
|
if (result === NO_CHANNEL) {
|
||||||
|
@ -216,14 +216,14 @@ module.exports = {
|
||||||
showFileLite(fileInfo, res);
|
showFileLite(fileInfo, res);
|
||||||
return fileInfo;
|
return fileInfo;
|
||||||
case SHOW:
|
case SHOW:
|
||||||
return db
|
return db.Claim
|
||||||
.getShortClaimIdFromLongClaimId(fileInfo.claimId, fileInfo.name)
|
.getShortClaimIdFromLongClaimId(fileInfo.claimId, fileInfo.name)
|
||||||
.then(shortId => {
|
.then(shortId => {
|
||||||
fileInfo['shortId'] = shortId;
|
fileInfo['shortId'] = shortId;
|
||||||
return db.resolveClaim(fileInfo.name, fileInfo.claimId);
|
return db.Claim.resolveClaim(fileInfo.name, fileInfo.claimId);
|
||||||
})
|
})
|
||||||
.then(resolveResult => {
|
.then(resolveResult => {
|
||||||
logger.debug('resolve result >>', resolveResult);
|
logger.debug('resolve result >>', resolveResult.dataValues);
|
||||||
fileInfo['thumbnail'] = chooseThumbnail(resolveResult, DEFAULT_THUMBNAIL);
|
fileInfo['thumbnail'] = chooseThumbnail(resolveResult, DEFAULT_THUMBNAIL);
|
||||||
fileInfo['title'] = resolveResult.title;
|
fileInfo['title'] = resolveResult.title;
|
||||||
fileInfo['description'] = resolveResult.description;
|
fileInfo['description'] = resolveResult.description;
|
||||||
|
|
|
@ -97,7 +97,7 @@ module.exports = {
|
||||||
logger.debug('retrieving most recent claims');
|
logger.debug('retrieving most recent claims');
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// get the raw requests data
|
// get the raw requests data
|
||||||
db.getRecentClaims()
|
db.File.getRecentClaims()
|
||||||
.then(results => {
|
.then(results => {
|
||||||
resolve(results);
|
resolve(results);
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,7 +28,7 @@ module.exports = {
|
||||||
.then(channel => {
|
.then(channel => {
|
||||||
userInfo['channelName'] = channel.channelName;
|
userInfo['channelName'] = channel.channelName;
|
||||||
userInfo['channelClaimId'] = channel.channelClaimId;
|
userInfo['channelClaimId'] = channel.channelClaimId;
|
||||||
return db.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName);
|
return db.Certificate.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName);
|
||||||
})
|
})
|
||||||
.then(shortChannelId => {
|
.then(shortChannelId => {
|
||||||
userInfo['shortChannelId'] = shortChannelId;
|
userInfo['shortChannelId'] = shortChannelId;
|
||||||
|
|
|
@ -1,4 +1,31 @@
|
||||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE }) => {
|
const logger = require('winston');
|
||||||
I think Certificate is accurate because it is actually storing the certificate claims from the blockchain. We have a Channel table for the Channels that are created on spee.ch. It parallels how we have a Claim table for all the stream claims in the blockchain (i guess this table should be Streams to be fully parallel) and a File table for all the files held locally by spee.ch. I think Certificate is accurate because it is actually storing the certificate claims from the blockchain. We have a Channel table for the Channels that are created on spee.ch. It parallels how we have a Claim table for all the stream claims in the blockchain (i guess this table should be Streams to be fully parallel) and a File table for all the files held locally by spee.ch.
@billbitt got it @billbitt got it
|
|||||||
|
const NO_CHANNEL = 'NO_CHANNEL';
|
||||||
|
|
||||||
|
function sortResult (result, longId) {
|
||||||
|
let claimIndex;
|
||||||
This function is called This function is called `sortResult` but it appears to return a short Id.
|
|||||||
|
let shortId = longId.substring(0, 1); // default sort id is the first letter
|
||||||
|
let shortIdLength = 0;
|
||||||
|
// find the index of this certificate
|
||||||
|
claimIndex = result.findIndex(element => {
|
||||||
|
return element.claimId === longId;
|
||||||
|
});
|
||||||
|
if (claimIndex < 0) { throw new Error('channelId not found in possible sorted list') }
|
||||||
|
// get an array of all certificates with lower height
|
||||||
|
let possibleMatches = result.slice(0, claimIndex);
|
||||||
|
// remove certificates with the same prefixes until none are left.
|
||||||
|
while (possibleMatches.length > 0) {
|
||||||
|
shortIdLength += 1;
|
||||||
|
shortId = longId.substring(0, shortIdLength);
|
||||||
|
possibleMatches = possibleMatches.filter(element => {
|
||||||
|
return (element.claimId.substring(0, shortIdLength) === shortId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// return the short Id
|
||||||
|
logger.debug('short channel id ===', shortId);
|
||||||
|
return shortId;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE, Op }) => {
|
||||||
const Certificate = sequelize.define(
|
const Certificate = sequelize.define(
|
||||||
'Certificate',
|
'Certificate',
|
||||||
{
|
{
|
||||||
|
@ -97,5 +124,86 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {
|
||||||
|
logger.debug(`finding short channel id for ${channelName}:${longChannelId}`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: {name: channelName},
|
||||||
|
order: [['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
throw new Error('That is an invalid channel name');
|
||||||
|
default:
|
||||||
|
return resolve(sortResult(result, longChannelId));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: {
|
||||||
|
name : channelName,
|
||||||
|
claimId: {
|
||||||
|
[sequelize.Op.like]: `${channelId}%`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: [['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(NO_CHANNEL);
|
||||||
|
default: // note results must be sorted
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Certificate.getLongChannelIdFromChannelName = function (channelName) {
|
||||||
|
logger.debug(`getLongChannelIdFromChannelName(${channelName})`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { name: channelName },
|
||||||
|
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(NO_CHANNEL);
|
||||||
|
default:
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Certificate.getLongChannelId = function (channelName, channelId) {
|
||||||
|
logger.debug(`getLongChannelId(${channelName}, ${channelId})`);
|
||||||
|
if (channelId && (channelId.length === 40)) { // if a full channel id is provided
|
||||||
|
return new Promise((resolve, reject) => resolve(channelId));
|
||||||
|
} else if (channelId && channelId.length < 40) { // if a short channel id is provided
|
||||||
|
return this.getLongChannelIdFromShortChannelId(channelName, channelId);
|
||||||
|
} else {
|
||||||
|
return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return Certificate;
|
return Certificate;
|
||||||
};
|
};
|
||||||
|
|
179
models/claim.js
|
@ -1,4 +1,31 @@
|
||||||
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE }) => {
|
const logger = require('winston');
|
||||||
|
const NO_CLAIM = 'NO_CLAIM';
|
||||||
|
|
||||||
|
function sortResult (result, longId) {
|
||||||
|
let claimIndex;
|
||||||
This function seems to contain code that could be shared with the other (This function has same naming problem as well.) This function seems to contain code that could be shared with the other `sortResult`.
(This function has same naming problem as well.)
|
|||||||
|
let shortId = longId.substring(0, 1); // default sort id is the first letter
|
||||||
|
let shortIdLength = 0;
|
||||||
|
// find the index of this certificate
|
||||||
|
claimIndex = result.findIndex(element => {
|
||||||
|
return element.claimId === longId;
|
||||||
|
});
|
||||||
|
if (claimIndex < 0) { throw new Error('claimid not found in possible sorted list') }
|
||||||
|
// get an array of all certificates with lower height
|
||||||
|
let possibleMatches = result.slice(0, claimIndex);
|
||||||
|
// remove certificates with the same prefixes until none are left.
|
||||||
|
while (possibleMatches.length > 0) {
|
||||||
|
shortIdLength += 1;
|
||||||
|
shortId = longId.substring(0, shortIdLength);
|
||||||
|
possibleMatches = possibleMatches.filter(element => {
|
||||||
|
return (element.claimId.substring(0, shortIdLength) === shortId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// return the short Id
|
||||||
|
logger.debug('short claim id ===', shortId);
|
||||||
|
return shortId;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, DOUBLE, Op }) => {
|
||||||
const Claim = sequelize.define(
|
const Claim = sequelize.define(
|
||||||
'Claim',
|
'Claim',
|
||||||
{
|
{
|
||||||
|
@ -154,5 +181,155 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER, TEXT, ARRAY, DECIMAL, D
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {
|
||||||
|
logger.debug(`Claim.getShortClaimIdFromLongClaimId for ${claimId}#${claimId}`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { name: claimName },
|
||||||
|
order: [['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
throw new Error('That is an invalid claim name');
|
||||||
|
default:
|
||||||
|
resolve(sortResult(result, claimId));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.getAllChannelClaims = function (channelId) {
|
||||||
|
logger.debug(`Claim.getAllChannelClaims for ${channelId}`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { certificateId: channelId },
|
||||||
|
order: [['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(null);
|
||||||
|
default:
|
||||||
|
return resolve(result);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.getClaimIdByLongChannelId = function (channelId, claimName) {
|
||||||
|
logger.debug(`finding claim id for claim ${claimName} from channel ${channelId}`);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { name: claimName, certificateId: channelId },
|
||||||
|
order: [['id', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(NO_CLAIM);
|
||||||
|
case 1:
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
default:
|
||||||
|
logger.error(`${result.length} records found for ${claimName} from channel ${claimName}`);
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: {
|
||||||
|
name,
|
||||||
|
claimId: {
|
||||||
|
[sequelize.Op.like]: `${shortId}%`,
|
||||||
|
}},
|
||||||
|
order: [['height', 'ASC']],
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(NO_CLAIM);
|
||||||
|
default: // note results must be sorted
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.getTopFreeClaimIdByClaimName = function (name) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { name },
|
||||||
|
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']], // note: maybe height and effective amount need to switch?
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(NO_CLAIM);
|
||||||
|
default:
|
||||||
|
logger.debug('getTopFreeClaimIdByClaimName result:', result.dataValues);
|
||||||
|
return resolve(result[0].claimId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.getLongClaimId = function (claimName, claimId) {
|
||||||
|
logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
|
||||||
|
if (claimId && (claimId.length === 40)) { // if a full claim id is provided
|
||||||
|
return new Promise((resolve, reject) => resolve(claimId));
|
||||||
|
} else if (claimId && claimId.length < 40) {
|
||||||
|
return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided
|
||||||
|
} else {
|
||||||
|
return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Claim.resolveClaim = function (name, claimId) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this
|
||||||
|
.findAll({
|
||||||
|
where: { name, claimId },
|
||||||
|
})
|
||||||
|
.then(result => {
|
||||||
|
switch (result.length) {
|
||||||
|
case 0:
|
||||||
|
return resolve(null);
|
||||||
|
case 1:
|
||||||
|
return resolve(result[0]);
|
||||||
|
default:
|
||||||
|
logger.error('more than one entry matches that name and claimID');
|
||||||
|
return resolve(result[0]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return Claim;
|
return Claim;
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,5 +55,13 @@ module.exports = (sequelize, { STRING, BOOLEAN, INTEGER }) => {
|
||||||
File.hasOne(db.Claim);
|
File.hasOne(db.Claim);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
File.getRecentClaims = function () {
|
||||||
|
return this.findAll({
|
||||||
|
where: { nsfw: false, trendingEligible: true },
|
||||||
|
order: [['createdAt', 'DESC']],
|
||||||
|
limit: 25,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return File;
|
return File;
|
||||||
};
|
};
|
||||||
|
|
254
models/index.js
|
@ -6,12 +6,10 @@ const config = require('config');
|
||||||
const db = {};
|
const db = {};
|
||||||
const logger = require('winston');
|
const logger = require('winston');
|
||||||
|
|
||||||
const NO_CHANNEL = 'NO_CHANNEL';
|
|
||||||
const NO_CLAIM = 'NO_CLAIM';
|
|
||||||
|
|
||||||
const database = config.get('Database.Database');
|
const database = config.get('Database.Database');
|
||||||
const username = config.get('Database.Username');
|
const username = config.get('Database.Username');
|
||||||
const password = config.get('Database.Password');
|
const password = config.get('Database.Password');
|
||||||
|
|
||||||
const sequelize = new Sequelize(database, username, password, {
|
const sequelize = new Sequelize(database, username, password, {
|
||||||
host : 'localhost',
|
host : 'localhost',
|
||||||
dialect: 'mysql',
|
dialect: 'mysql',
|
||||||
|
@ -24,104 +22,6 @@ const sequelize = new Sequelize(database, username, password, {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function sortResult (result, longId) {
|
|
||||||
let claimIndex;
|
|
||||||
let shortId = longId.substring(0, 1); // default sort id is the first letter
|
|
||||||
let shortIdLength = 0;
|
|
||||||
// find the index of this certificate
|
|
||||||
claimIndex = result.findIndex(element => {
|
|
||||||
return element.claimId === longId;
|
|
||||||
});
|
|
||||||
if (claimIndex < 0) { throw new Error('claimid not found in possible sorted list') }
|
|
||||||
// get an array of all certificates with lower height
|
|
||||||
let possibleMatches = result.slice(0, claimIndex);
|
|
||||||
// remove certificates with the same prefixes until none are left.
|
|
||||||
while (possibleMatches.length > 0) {
|
|
||||||
shortIdLength += 1;
|
|
||||||
shortId = longId.substring(0, shortIdLength);
|
|
||||||
possibleMatches = possibleMatches.filter(element => {
|
|
||||||
return (element.claimId.substring(0, shortIdLength) === shortId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// return the short Id
|
|
||||||
logger.debug('short channel id ===', shortId);
|
|
||||||
return shortId;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLongClaimIdFromShortClaimId (name, shortId) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${name}' AND claimId LIKE '${shortId}%' ORDER BY height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(NO_CLAIM);
|
|
||||||
default: // note results must be sorted
|
|
||||||
return resolve(result[0].claimId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTopFreeClaimIdByClaimName (name) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${name}' ORDER BY effectiveAmount DESC, height ASC LIMIT 1`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
logger.debug('getTopFreeClaimIdByClaimName result:', result);
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(NO_CLAIM);
|
|
||||||
default:
|
|
||||||
return resolve(result[0].claimId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function getLongChannelIdFromShortChannelId (channelName, channelId) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId, height FROM Certificate WHERE name = '${channelName}' AND claimId LIKE '${channelId}%' ORDER BY height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(NO_CHANNEL);
|
|
||||||
default: // note results must be sorted
|
|
||||||
return resolve(result[0].claimId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLongChannelIdFromChannelName (channelName) {
|
|
||||||
logger.debug(`getLongChannelIdFromChannelName(${channelName})`);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId, amount, height FROM Certificate WHERE name = '${channelName}' ORDER BY effectiveAmount DESC, height ASC LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(NO_CHANNEL);
|
|
||||||
default:
|
|
||||||
return resolve(result[0].claimId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sequelize
|
sequelize
|
||||||
.authenticate()
|
.authenticate()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -131,6 +31,7 @@ sequelize
|
||||||
logger.error('Sequelize was unable to connect to the database:', err);
|
logger.error('Sequelize was unable to connect to the database:', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// add each model to the db object
|
||||||
fs
|
fs
|
||||||
.readdirSync(__dirname)
|
.readdirSync(__dirname)
|
||||||
.filter(file => {
|
.filter(file => {
|
||||||
|
@ -141,6 +42,7 @@ fs
|
||||||
db[model.name] = model;
|
db[model.name] = model;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// run model.association for each model in the db object that has an association
|
||||||
Object.keys(db).forEach(modelName => {
|
Object.keys(db).forEach(modelName => {
|
||||||
if (db[modelName].associate) {
|
if (db[modelName].associate) {
|
||||||
logger.info('Associating model:', modelName);
|
logger.info('Associating model:', modelName);
|
||||||
|
@ -151,15 +53,15 @@ Object.keys(db).forEach(modelName => {
|
||||||
db.sequelize = sequelize;
|
db.sequelize = sequelize;
|
||||||
db.Sequelize = Sequelize;
|
db.Sequelize = Sequelize;
|
||||||
|
|
||||||
db['upsert'] = (Model, values, condition, tableName) => {
|
db.upsert = (Model, values, condition, tableName) => {
|
||||||
return Model
|
return Model
|
||||||
.findOne({ where: condition })
|
.findOne({ where: condition })
|
||||||
.then(function (obj) {
|
.then(obj => {
|
||||||
if (obj) { // update
|
if (obj) { // update
|
||||||
logger.debug(`updating "${values.name}" "${values.claimId}" in db.${tableName}`);
|
logger.debug(`updating record in db.${tableName}`);
|
||||||
return obj.update(values);
|
return obj.update(values);
|
||||||
} else { // insert
|
} else { // insert
|
||||||
logger.debug(`creating "${values.name}" "${values.claimId}" in db.${tableName}`);
|
logger.debug(`creating record in db.${tableName}`);
|
||||||
return Model.create(values);
|
return Model.create(values);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -168,148 +70,8 @@ db['upsert'] = (Model, values, condition, tableName) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
db['getTrendingClaims'] = (startDate) => {
|
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 });
|
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 });
|
||||||
};
|
};
|
||||||
|
|
||||||
db['getRecentClaims'] = () => {
|
|
||||||
return db.sequelize.query(`SELECT * FROM File WHERE nsfw != 1 AND trendingEligible = 1 ORDER BY createdAt DESC LIMIT 25;`, { type: db.sequelize.QueryTypes.SELECT });
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getShortClaimIdFromLongClaimId'] = (claimId, claimName) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
logger.debug('finding short channel id');
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId, height FROM Claim WHERE name = '${claimName}' ORDER BY height;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
throw new Error('That is an invalid claim name');
|
|
||||||
default:
|
|
||||||
return resolve(sortResult(result, claimId));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getShortChannelIdFromLongChannelId'] = (longChannelId, channelName) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
logger.debug(`finding short channel id for ${longChannelId} ${channelName}`);
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId, height FROM Certificate WHERE name = '${channelName}' ORDER BY height;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
throw new Error('That is an invalid channel name');
|
|
||||||
default:
|
|
||||||
return resolve(sortResult(result, longChannelId));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getAllFreeClaims'] = (name) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT name, claimId, outpoint, height, address FROM Claim WHERE name = '${name}' ORDER BY amount DESC, height ASC`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(null);
|
|
||||||
default:
|
|
||||||
return resolve(result);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['resolveClaim'] = (name, claimId) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT name, claimId, outpoint, height, address, title, description, thumbnail, certificateId, channelName FROM Claim WHERE name = '${name}' AND claimId = '${claimId}'`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(null);
|
|
||||||
case 1:
|
|
||||||
return resolve(result[0]);
|
|
||||||
default:
|
|
||||||
throw new Error('more than one entry matches that name and claimID');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getClaimIdByLongChannelId'] = (channelId, claimName) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
logger.debug(`finding claim id for claim "${claimName}" from channel "${channelId}"`);
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT claimId FROM Claim WHERE name = '${claimName}' AND certificateId = '${channelId}' LIMIT 1;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(NO_CLAIM);
|
|
||||||
default:
|
|
||||||
return resolve(result[0].claimId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getAllChannelClaims'] = (channelId) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
logger.debug(`finding all claims in channel "${channelId}"`);
|
|
||||||
db
|
|
||||||
.sequelize.query(`SELECT name, claimId, outpoint, height, address, contentType, title, description, license, thumbnail FROM Claim WHERE certificateId = '${channelId}' ORDER BY height DESC;`, { type: db.sequelize.QueryTypes.SELECT })
|
|
||||||
.then(result => {
|
|
||||||
switch (result.length) {
|
|
||||||
case 0:
|
|
||||||
return resolve(null);
|
|
||||||
default:
|
|
||||||
return resolve(result);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getLongClaimId'] = (claimName, claimId) => {
|
|
||||||
logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
|
|
||||||
if (claimId && (claimId.length === 40)) { // if a full claim id is provided
|
|
||||||
return new Promise((resolve, reject) => resolve(claimId));
|
|
||||||
} else if (claimId && claimId.length < 40) {
|
|
||||||
return getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided
|
|
||||||
} else {
|
|
||||||
return getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
db['getLongChannelId'] = (channelName, channelId) => {
|
|
||||||
logger.debug(`getLongChannelId (${channelName}, ${channelId})`);
|
|
||||||
if (channelId && (channelId.length === 40)) { // if a full channel id is provided
|
|
||||||
return new Promise((resolve, reject) => resolve(channelId));
|
|
||||||
} else if (channelId && channelId.length < 40) { // if a short channel id is provided
|
|
||||||
return getLongChannelIdFromShortChannelId(channelName, channelId);
|
|
||||||
} else {
|
|
||||||
return getLongChannelIdFromChannelName(channelName); // if no channel id provided
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = db;
|
module.exports = db;
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = new PassportLocalStrategy(
|
||||||
.then(channel => {
|
.then(channel => {
|
||||||
userInfo['channelName'] = channel.channelName;
|
userInfo['channelName'] = channel.channelName;
|
||||||
userInfo['channelClaimId'] = channel.channelClaimId;
|
userInfo['channelClaimId'] = channel.channelClaimId;
|
||||||
return db.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName);
|
return db.Certificate.getShortChannelIdFromLongChannelId(channel.channelClaimId, channel.channelName);
|
||||||
})
|
})
|
||||||
.then(shortChannelId => {
|
.then(shortChannelId => {
|
||||||
userInfo['shortChannelId'] = shortChannelId;
|
userInfo['shortChannelId'] = shortChannelId;
|
||||||
|
|
|
@ -54,7 +54,7 @@ module.exports = new PassportLocalStrategy(
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.verbose('user and certificate successfully associated');
|
logger.verbose('user and certificate successfully associated');
|
||||||
return db.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);
|
return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);
|
||||||
})
|
})
|
||||||
.then(shortChannelId => {
|
.then(shortChannelId => {
|
||||||
userInfo['shortChannelId'] = shortChannelId;
|
userInfo['shortChannelId'] = shortChannelId;
|
||||||
|
|
|
@ -147,7 +147,8 @@ module.exports = (app) => {
|
||||||
// route to get a short claim id from long claim Id
|
// route to get a short claim id from long claim Id
|
||||||
app.get('/api/shortClaimId/:longId/:name', ({ originalUrl, ip, params }, res) => {
|
app.get('/api/shortClaimId/:longId/:name', ({ originalUrl, ip, params }, res) => {
|
||||||
I'm guessing this code isn't actually missing a colon or it wouldn't work, but what's the difference here? I'm guessing this code isn't actually missing a colon or it wouldn't work, but what's the difference here?
the line break was accidental; difference was just adding Claim because getShortClaimId... is now a method of Claim the line break was accidental; difference was just adding Claim because getShortClaimId... is now a method of Claim
|
|||||||
// serve content
|
// serve content
|
||||||
db.getShortClaimIdFromLongClaimId(params.longId, params.name)
|
db.Claim
|
||||||
|
.getShortClaimIdFromLongClaimId(params.longId, params.name)
|
||||||
.then(shortId => {
|
.then(shortId => {
|
||||||
res.status(200).json(shortId);
|
res.status(200).json(shortId);
|
||||||
})
|
})
|
||||||
|
@ -159,7 +160,7 @@ module.exports = (app) => {
|
||||||
// route to get a short channel id from long channel Id
|
// route to get a short channel id from long channel Id
|
||||||
app.get('/api/shortChannelId/:longId/:name', ({ params }, res) => {
|
app.get('/api/shortChannelId/:longId/:name', ({ params }, res) => {
|
||||||
// serve content
|
// serve content
|
||||||
db.getShortChannelIdFromLongChannelId(params.longId, params.name)
|
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name)
|
||||||
.then(shortId => {
|
.then(shortId => {
|
||||||
logger.debug('sending back short channel id', shortId);
|
logger.debug('sending back short channel id', shortId);
|
||||||
res.status(200).json(shortId);
|
res.status(200).json(shortId);
|
||||||
|
|
Would it make sense for this to be
Channel
rather thanCertificate
?