const mysql = require('mysql'); const con = mysql.createConnection({ host: "localhost", user: "realmsdivided", password: "realmsdivided", database: "realms_divided" }); function connect(){ con.connect(function(err) { if (err) { console.log(err); } else { console.log('DB Connected'); } }); } function disconnect(){ con.end(); } // Is calling a promise in a promise the best way to do this? // Keeping because this is how I've figured to call other funcs from database function getCardById(cardId){ const dPromise = new Promise((resolve, reject) => { getCards(' card.id = '+cardId).then(cards => { resolve(cards); }) .catch(err => { throw err; reject(new Error(err)); }); }); return dPromise; } function getCards(whereClause){ const cPromise = new Promise((resolve, reject) => { // Get main card info let cards = []; let sql = `SELECT card.id AS cardId -- TEMP UNTIL UID ,cardName ,cardCost ,typeName ,cardAttack ,rarityName FROM card LEFT JOIN type ON type.id = card.id LEFT JOIN rarity ON rarity.id = card.cardRarity `; // TODO: Rewrite this so it's not so insecure!!!! if(whereClause){ sql = sql + " WHERE "+whereClause; } con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } cards = dbResultToCards(result); //console.log(cards); resolve(cards); }); // Now get the // class // colour requirements // card effects }); return cPromise; } // May want a FromDecks to get the SQL done in one blast // then filter the results according? function getCardsFromDeck(playerId, deckId){ const cPromise = new Promise((resolve, reject) => { if(playerId == null || deckId == null){ reject(new Error('Player/Deck Id not provided')); } let cards = []; // TODO: Change rarity, and maybe cardName to be the id (prolly card name for fancy effects) // Then have a SQL loop at start of game that adds [name, id], [rariry, id] etc. let sql = `SELECT cardName ,cardCost ,typeName ,cardAttack ,rarityName ,cardCount FROM deck INNER JOIN deck_cards ON deck_cards.deckId = deck.deckId AND deck_cards.playerId = deck.playerId INNER JOIN card ON card.id = deck_cards.cardId LEFT JOIN type ON type.id = card.id LEFT JOIN rarity ON rarity.id = card.cardRarity`; // TODO: Make more secure!! sql += ' WHERE deck.deckId ='+deckId+' AND deck.playerId = '+playerId; sql += ';'; con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } cards = dbResultToCards(result); resolve(cards); }); // Card list has been built // Resolve/return the data of the cards Array/deck }); return cPromise; } // This may be more jank than I'd like. Was going procedure route, or JOINs // but thinking of future effects that could have 4-5 effects, that check 2-3 colours // and X amounts of cards/classes, to finally trigger something, those feel like they // wouldn't work. So this is it for now, and when I think of something better I'll rewrite function dbGetCardClasses(cardId){ // Maybe this isn't too bad as async? // But I imagine for lets say 100 1v1s 200 loops of 35cards each, eekers const cPromise = new Promise((resolve, reject) => { if(cardId == null){ reject(new Error('cardId not provided')); } let classes = []; // Just getting the class IDs, as intend to load all the class data [id, name] into // an array or file on game load. This way just the ID is needed, and no text compares let sql = `SELECT classId FROM card_class WHERE cardId = `+cardId ; // TODO: As all these SQL, need to make more secure con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } result.forEach((card) => { // Add the classId to array to be used in card buildery doodad classes.push(result[0]); }); }); // Card list has been built // Resolve/return the data of the cards Array/deck resolve(classes); }); return cPromise; } // Don't really want this in DB layer, but it wouldn't play // in the main server file, so it's here until I figure out why function dbResultToCards(result){ let cards = []; result.forEach((card) => { let tempCard = {}; tempCard.id = card.cardId; tempCard.name = card.cardName; tempCard.colour = null; tempCard.cost = card.cardCost; tempCard.type = card.typeName; tempCard.atk = card.cardAttack; tempCard.rarity = card.rarityName; tempCard.effect = null; // TODO: Will need more SQL statements, or some function/procedure // class // colour requirements // card effects // Add the 'completed' cards into the deck if(card.cardCount){ // Add as many cards into the deck as is in cardCount for(let i = 0; i < card.cardCount; i++){ cards.push(tempCard); } }else{ // Or just one cards.push(tempCard); } }); return cards; } // Testing, and trialing rewrites function dbGetDecks(){ const dPromise = new Promise((resolve, reject) => { let cards = []; let sql = `SELECT deckId ,playerId ,deckName FROM deck LIMIT 10 `; // TODO: Remove limit when happy/this accepts params con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } resolve(result); }); }); return dPromise; } function dbGetDeckList(){ const dPromise = new Promise((resolve, reject) => { let cards = []; let sql = `SELECT deckId ,playerId ,cardId ,cardCount FROM deck_cards `; con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } resolve(result); }); }); return dPromise; } function dbGetCards(){ // Start with basic stuff in card table const dPromise = new Promise((resolve, reject) => { let sql = `SELECT id ,cardName ,cardCost ,cardType ,cardAttack ,cardRarity FROM card `; con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } resolve(result); }); }); return dPromise; } function dbGetCardClasses(){ // Get the classes assoc. on each card const dPromise = new Promise((resolve, reject) => { let sql = `SELECT cardId ,classId FROM card_class `; con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } resolve(result); }); }); return dPromise; } function dbGetCardColourRequirement(){ // Get the classes assoc. on each card const dPromise = new Promise((resolve, reject) => { let sql = `SELECT cardId ,colourId ,cost FROM card_colour_requirement `; con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } resolve(result); }); }); return dPromise; } module.exports = { connect, disconnect , getCards , getCardById , getCardsFromDeck // Testing, and trailing , dbGetDecks , dbGetDeckList , dbGetCards , dbGetCardClasses , dbGetCardColourRequirement };