From 041dba66146f2353de25437545aca95c1c24ed2e Mon Sep 17 00:00:00 2001 From: Nathan Date: Thu, 17 Oct 2024 21:34:14 +0100 Subject: [PATCH] Changes to DB functions + DB export dump --- database.js | 130 +++++++++++++++++++++++++----- db/db_export.sql | 206 +++++++++++++++++++++++++++++++++++++++++++++++ server.js | 2 +- 3 files changed, 319 insertions(+), 19 deletions(-) create mode 100644 db/db_export.sql diff --git a/database.js b/database.js index e209548..fd02343 100644 --- a/database.js +++ b/database.js @@ -35,6 +35,7 @@ function getCardById(cardId){ 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 @@ -52,33 +53,126 @@ function getCards(whereClause){ con.query(sql, function (err, result, fields) { if (err) { throw err; reject(new Error(err)); } - result.forEach((card) => { - let tempCard = {}; - tempCard.id = card.cardId; - tempCard.name = card.cardName; - tempCard.colour = 'temp'; - tempCard.cost = card.cardCost; - tempCard.type = card.typeName; - tempCard.atk = card.cardAttack; - tempCard.rarity = card.rarityName; - tempCard.effect = 'temp effect'; - // TODO: Will need more SQL statements, or some function/procedure - // class - // colour requirements - // card effects - - cards.push(tempCard); - }); - + 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; +} + module.exports = { connect, disconnect , getCards , getCardById + , getCardsFromDeck }; diff --git a/db/db_export.sql b/db/db_export.sql new file mode 100644 index 0000000..eb8a41d --- /dev/null +++ b/db/db_export.sql @@ -0,0 +1,206 @@ +-- -------------------------------------------------------- +-- Host: 127.0.0.1 +-- Server version: 10.7.8-MariaDB-1:10.7.8+maria~ubu2004 - mariadb.org binary distribution +-- Server OS: debian-linux-gnu +-- HeidiSQL Version: 12.6.0.6765 +-- -------------------------------------------------------- + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET NAMES utf8 */; +/*!50503 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + + +-- Dumping database structure for realms_divided +CREATE DATABASE IF NOT EXISTS `realms_divided` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */; +USE `realms_divided`; + +-- Dumping structure for table realms_divided.card +CREATE TABLE IF NOT EXISTS `card` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `cardName` varchar(255) NOT NULL, + `cardCost` tinyint(4) NOT NULL DEFAULT 2, + `cardType` tinyint(4) DEFAULT NULL, + `cardAttack` int(11) DEFAULT NULL, + `cardRarity` tinyint(4) NOT NULL DEFAULT 1, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.card: ~5 rows (approximately) +INSERT INTO `card` (`id`, `cardName`, `cardCost`, `cardType`, `cardAttack`, `cardRarity`) VALUES + (1, 'Red1', 1, 1, 500, 1), + (2, 'White1', 1, 1, 1000, 1), + (3, 'Blue1', 2, 1, 1000, 1), + (4, 'White 8', 3, 2, NULL, 2), + (5, 'Red7', 2, 2, NULL, 2); + +-- Dumping structure for table realms_divided.card_class +CREATE TABLE IF NOT EXISTS `card_class` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `cardId` int(11) DEFAULT NULL, + `classId` smallint(6) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.card_class: ~4 rows (approximately) +INSERT INTO `card_class` (`id`, `cardId`, `classId`) VALUES + (1, 1, 1), + (2, 2, 1), + (3, 3, 1), + (4, 1, 2); + +-- Dumping structure for table realms_divided.card_colour_requirement +CREATE TABLE IF NOT EXISTS `card_colour_requirement` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `cardId` int(11) DEFAULT NULL, + `colourId` tinyint(4) DEFAULT NULL, + `cost` tinyint(4) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.card_colour_requirement: ~5 rows (approximately) +INSERT INTO `card_colour_requirement` (`id`, `cardId`, `colourId`, `cost`) VALUES + (1, 1, 3, 1), + (2, 2, 1, 1), + (3, 3, 2, 1), + (4, 4, 1, 2), + (5, 5, 3, 2); + +-- Dumping structure for table realms_divided.card_effect +CREATE TABLE IF NOT EXISTS `card_effect` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `cardId` int(11) DEFAULT NULL, + `effectId` smallint(6) DEFAULT NULL, + `value` smallint(6) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.card_effect: ~5 rows (approximately) +INSERT INTO `card_effect` (`id`, `cardId`, `effectId`, `value`) VALUES + (1, 1, 2, NULL), + (2, 3, 1, NULL), + (3, 2, 3, NULL), + (4, 4, 4, 1000), + (5, 5, 5, 3000); + +-- Dumping structure for table realms_divided.class +CREATE TABLE IF NOT EXISTS `class` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `parentId` tinyint(4) DEFAULT NULL, + `className` tinytext NOT NULL, + `primaryColour` smallint(6) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.class: ~10 rows (approximately) +INSERT INTO `class` (`id`, `parentId`, `className`, `primaryColour`) VALUES + (1, NULL, 'Goblin', 3), + (2, NULL, 'Human', 1), + (3, NULL, 'Spirit', 2), + (4, NULL, 'Warrior', 1), + (5, NULL, 'Orc', 3), + (6, NULL, 'Beast', 5), + (7, NULL, 'Plant', 5), + (8, NULL, 'Undead', 4), + (9, NULL, 'Mechanical', 6), + (10, NULL, 'Void', 7); + +-- Dumping structure for table realms_divided.colour +CREATE TABLE IF NOT EXISTS `colour` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `colourName` tinytext DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.colour: ~7 rows (approximately) +INSERT INTO `colour` (`id`, `colourName`) VALUES + (1, 'White'), + (2, 'Blue'), + (3, 'Red'), + (4, 'Black'), + (5, 'Green'), + (6, 'Brown'), + (7, 'Void'); + +-- Dumping structure for table realms_divided.deck +CREATE TABLE IF NOT EXISTS `deck` ( + `deckId` int(11) NOT NULL, + `playerId` int(11) NOT NULL, + `deckName` tinytext NOT NULL, + PRIMARY KEY (`deckId`,`playerId`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.deck: ~2 rows (approximately) +INSERT INTO `deck` (`deckId`, `playerId`, `deckName`) VALUES + (1, 1, 'Deck 1 P1'), + (1, 2, 'Deck 1 P2'); + +-- Dumping structure for table realms_divided.deck_cards +CREATE TABLE IF NOT EXISTS `deck_cards` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `deckId` int(11) DEFAULT NULL, + `playerId` int(11) DEFAULT NULL, + `cardId` int(11) DEFAULT NULL, + `cardCount` tinyint(4) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.deck_cards: ~5 rows (approximately) +INSERT INTO `deck_cards` (`id`, `deckId`, `playerId`, `cardId`, `cardCount`) VALUES + (1, 1, 1, 1, 25), + (2, 1, 1, 5, 10), + (3, 1, 2, 2, 15), + (4, 1, 2, 3, 14), + (5, 1, 2, 4, 6); + +-- Dumping structure for table realms_divided.effect +CREATE TABLE IF NOT EXISTS `effect` ( + `id` smallint(6) NOT NULL AUTO_INCREMENT, + `effectName` tinytext DEFAULT NULL, + `effectDescription` varchar(250) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.effect: ~5 rows (approximately) +INSERT INTO `effect` (`id`, `effectName`, `effectDescription`) VALUES + (1, 'Flight', 'Can ignore Taunt, cannot be tagetted by attack'), + (2, 'Reach', 'Can attack Flight units'), + (3, 'Equip', 'Add this cards attack, and effect(s) to another'), + (4, 'Heal', 'Untap X shield(s)'), + (5, 'Hurt', 'Deal X damage to target unit, this combat'); + +-- Dumping structure for table realms_divided.rarity +CREATE TABLE IF NOT EXISTS `rarity` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `rarityName` tinytext DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.rarity: ~2 rows (approximately) +INSERT INTO `rarity` (`id`, `rarityName`) VALUES + (1, 'Common'), + (2, 'Uncommon'), + (3, 'Rare'); + +-- Dumping structure for table realms_divided.type +CREATE TABLE IF NOT EXISTS `type` ( + `id` tinyint(4) NOT NULL AUTO_INCREMENT, + `typeName` tinytext DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +-- Dumping data for table realms_divided.type: ~2 rows (approximately) +INSERT INTO `type` (`id`, `typeName`) VALUES + (1, 'Unit'), + (2, 'Spell'), + (3, 'Token'); + +/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */; +/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; +/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */; diff --git a/server.js b/server.js index c851f1a..a1d79b4 100644 --- a/server.js +++ b/server.js @@ -209,7 +209,7 @@ function requestGetCards(socket){ response.success = true; // Await promise, once it's done get the data, if errors send err - database.getCardById(1).then(data => { + database.getCardsFromDeck(1,1).then(data => { response.message = data; io.to(socket.id).emit('responseGetCards', response); })