250 lines
7.2 KiB
JavaScript
250 lines
7.2 KiB
JavaScript
const logger = require('winston');
|
|
|
|
const returnShortId = (claimsArray, longId) => {
|
|
let claimIndex;
|
|
let shortId = longId.substring(0, 1); // default short id is the first letter
|
|
let shortIdLength = 0;
|
|
// find the index of this claim id
|
|
claimIndex = claimsArray.findIndex(element => {
|
|
return element.claim_id === longId;
|
|
});
|
|
if (claimIndex < 0) {
|
|
throw new Error('claim id not found in claims list');
|
|
}
|
|
// get an array of all claims with lower height
|
|
let possibleMatches = claimsArray.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.claim_id && (element.claim_id.substring(0, shortIdLength) === shortId));
|
|
});
|
|
}
|
|
return shortId;
|
|
};
|
|
|
|
const isLongClaimId = (claimId) => {
|
|
return (claimId && (claimId.length === 40));
|
|
}
|
|
|
|
const isShortClaimId = (claimId) => {
|
|
return (claimId && (claimId.length < 40));
|
|
}
|
|
|
|
export default (db, table, sequelize) => ({
|
|
|
|
getClaimChannelName: async (publisher_id) => {
|
|
return await table.findAll({
|
|
where : { claim_id: publisher_id },
|
|
attributes: ['name'],
|
|
}).then(result => {
|
|
if(result.length === 0) {
|
|
throw new Error(`no record found for ${claimId}`);
|
|
} else if(result.length !== 1) {
|
|
logger.warn(`more than one record matches ${claimId} in db.Claim`);
|
|
}
|
|
|
|
return result[0].name;
|
|
});
|
|
},
|
|
|
|
getShortClaimIdFromLongClaimId: async (claimId, claimName, pendingClaim) => {
|
|
logger.debug(`claim.getShortClaimIdFromLongClaimId for ${claimName}#${claimId}`);
|
|
return await table.findAll({
|
|
where: { name: claimName },
|
|
order: [['height', 'ASC']],
|
|
}).then(result => {
|
|
if(result.length === 0) {
|
|
throw new Error('No claim(s) found with that claim name');
|
|
}
|
|
|
|
let list = result.map(claim => claim.dataValues);
|
|
if (pendingClaim) {
|
|
list = list.concat(pendingClaim);
|
|
}
|
|
|
|
return returnShortId(list, claimId);
|
|
});
|
|
},
|
|
|
|
getAllChannelClaims: async (channelClaimId, params) => {
|
|
logger.debug(`claim.getAllChannelClaims for ${channelClaimId}`);
|
|
|
|
const defaultWhereClauses = {
|
|
bid_state: { [sequelize.Op.or]: ['Controlling', 'Active', 'Accepted'] }
|
|
};
|
|
|
|
const addWhereClauses = (whereClauses, params) => {
|
|
/*
|
|
input params = { col: ['Val', 'Val']}
|
|
output = { col: { Op.or : [ { Op.eq: 'Value'},...]}, col2:...}
|
|
*/
|
|
const cols = Object.keys(params)
|
|
for (let colKey in cols){
|
|
let col = Object.keys(params)[colKey]
|
|
|
|
whereClauses[col] = {}
|
|
whereClauses[col][sequelize.Op.or] = []
|
|
for (let itemKey in params[col] ){
|
|
let itemsArr = params[col]
|
|
whereClauses[col][sequelize.Op.or].push({ [sequelize.Op.eq]: itemsArr[itemKey] })
|
|
}
|
|
}
|
|
return whereClauses;
|
|
}
|
|
|
|
const whereClause = addWhereClauses(defaultWhereClauses, params);
|
|
|
|
const selectWhere = {
|
|
...whereClause,
|
|
publisher_id: channelClaimId,
|
|
};
|
|
return await table.findAll({
|
|
where: selectWhere,
|
|
order: [['height', 'DESC'],['claim_id', 'ASC']],
|
|
})
|
|
.then(channelClaimsArray => {
|
|
if (channelClaimsArray.length === 0) {
|
|
return null;
|
|
}
|
|
return channelClaimsArray;
|
|
});
|
|
},
|
|
|
|
getClaimIdByLongChannelId: async (channelClaimId, claimName) => {
|
|
logger.debug(`finding claim id for claim ${claimName} from channel ${channelClaimId}`);
|
|
return await table.findAll({
|
|
where: { name: claimName, publisher_id: channelClaimId, bid_state: { [sequelize.Op.or]: ['Controlling', 'Active', 'Accepted'] } },
|
|
order: [['id', 'ASC']],
|
|
})
|
|
.then(result => {
|
|
switch (result.length) {
|
|
case 0:
|
|
return null;
|
|
case 1:
|
|
return result[0].claim_id;
|
|
default:
|
|
// Does this actually happen??? (from converted code)
|
|
logger.warn(`${result.length} records found for "${claimName}" in channel "${channelClaimId}"`);
|
|
return result[0].claim_id;
|
|
}
|
|
});
|
|
},
|
|
|
|
validateLongClaimId: async (name, claimId) => {
|
|
return await table.findOne({
|
|
where: {
|
|
name,
|
|
claim_id: claimId,
|
|
},
|
|
}).then(result => {
|
|
if (!result) {
|
|
return false;
|
|
}
|
|
return claimId;
|
|
});
|
|
},
|
|
|
|
getLongClaimIdFromShortClaimId: async (name, shortId) => {
|
|
return await table.findAll({
|
|
where: {
|
|
name,
|
|
claim_id: {
|
|
[sequelize.Op.like]: `${shortId}%`,
|
|
}},
|
|
order: [['height', 'ASC']],
|
|
})
|
|
.then(result => {
|
|
if(result.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return result[0].claim_id;
|
|
});
|
|
},
|
|
|
|
getTopFreeClaimIdByClaimName: async (name) => {
|
|
return await table.findAll({
|
|
// TODO: Limit 1
|
|
where: { name, bid_state: { [sequelize.Op.or]: ['Controlling', 'Active', 'Accepted'] } },
|
|
order: [['effective_amount', 'DESC'], ['height', 'ASC']],
|
|
}).then(result => {
|
|
if(result.length === 0) {
|
|
return null;
|
|
}
|
|
return result[0].claim_id;
|
|
})
|
|
},
|
|
|
|
getLongClaimId: async (claimName, claimId) => {
|
|
// TODO: Add failure case
|
|
logger.debug(`getLongClaimId(${claimName}, ${claimId})`);
|
|
if (isLongClaimId(claimId)) {
|
|
return table.queries.validateLongClaimId(claimName, claimId);
|
|
} else if (isShortClaimId(claimId)) {
|
|
return table.queries.getLongClaimIdFromShortClaimId(claimName, claimId);
|
|
} else {
|
|
return table.queries.getTopFreeClaimIdByClaimName(claimName);
|
|
}
|
|
},
|
|
|
|
resolveClaim: async (name, claimId) => {
|
|
logger.debug(`Claim.resolveClaim: ${name} ${claimId}`);
|
|
return table.findAll({
|
|
where: { name, claim_id: claimId },
|
|
}).then(claimArray => {
|
|
if(claimArray.length === 0) {
|
|
return null;
|
|
} else if(claimArray.length !== 1) {
|
|
logger.warn(`more than one record matches ${name}#${claimId} in db.Claim`);
|
|
}
|
|
|
|
return claimArray[0];
|
|
});
|
|
},
|
|
|
|
resolveClaimInChannel: async (claimName, channelId) => {
|
|
logger.debug(`Claim.resolveClaimByNames: ${claimName} in ${channelId}`);
|
|
return table.findAll({
|
|
where: {
|
|
name: claimName,
|
|
publisher_id: channelId,
|
|
},
|
|
}).then(claimArray => {
|
|
if (claimArray.length === 0) {
|
|
return null;
|
|
} else if (claimArray.length !== 1) {
|
|
logger.warn(`more than one record matches ${claimName} in ${channelId}`);
|
|
}
|
|
|
|
return claimArray[0];
|
|
});
|
|
},
|
|
|
|
getOutpoint: async (name, claimId) => {
|
|
logger.debug(`finding outpoint for ${name}#${claimId}`);
|
|
|
|
return await table.findAll({
|
|
where : { name, claim_id: claimId },
|
|
attributes: ['transaction_hash_id'],
|
|
}).then(result => {
|
|
if(result.length === 0) {
|
|
throw new Error(`no record found for ${name}#${claimId}`);
|
|
} else if(result.length !== 1) {
|
|
logger.warn(`more than one record matches ${name}#${claimId} in db.Claim`);
|
|
}
|
|
|
|
return result[0].transaction_hash_id;
|
|
});
|
|
},
|
|
|
|
getCurrentHeight: async () => {
|
|
return await table
|
|
.max('height')
|
|
.then(result => {
|
|
return (result || 100000);
|
|
});
|
|
},
|
|
|
|
})
|