Added searching for cards

This commit is contained in:
Hamcha 2019-09-03 17:01:36 +02:00
parent 2677a51872
commit 8f5e327b82
Signed by: hamcha
GPG key ID: 44AD3571EB09A39E
6 changed files with 156 additions and 44 deletions

View file

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"buefy": "^0.8.2", "buefy": "^0.8.2",
"core-js": "^2.6.5", "core-js": "^2.6.5",
"idb": "^4.0.4", "dexie": "^2.0.4",
"register-service-worker": "^1.6.2", "register-service-worker": "^1.6.2",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-class-component": "^7.0.2", "vue-class-component": "^7.0.2",

View file

@ -28,6 +28,7 @@ import { Action, Getter } from "vuex-class";
import TopBar from "@/components/Navigation/TopBar.vue"; import TopBar from "@/components/Navigation/TopBar.vue";
import { loadSets } from "@/mlpccg/set"; import { loadSets } from "@/mlpccg/set";
import { AppState } from "./store/types"; import { AppState } from "./store/types";
import { getCards } from "./mlpccg/database";
@Component({ @Component({
components: { components: {

View file

@ -1,35 +1,137 @@
import { DBSchema, openDB } from "idb"; import Dexie from "dexie";
import { Card } from "./types"; import { Card, CardFilter } from "./types";
interface CardDB extends DBSchema { class CardDatabase extends Dexie {
card: { public cards: Dexie.Table<Card, string>;
key: string;
value: Card;
indexes: {
"by-set": string;
"by-element": string[];
"by-type": string;
"by-cost": number;
"by-power": number;
"by-rarity": string;
};
};
}
const cardDBName = "card-db"; public constructor() {
super("CardDatabase");
export async function openCardDB() { this.version(1).stores({
return await openDB<CardDB>(cardDBName, 1, { cards: "ID,Set,Type,Cost,Power"
upgrade(db) {
const cardStore = db.createObjectStore("card", {
keyPath: "ID"
}); });
cardStore.createIndex("by-set", "Set"); this.cards = this.table("cards");
cardStore.createIndex("by-element", "Element");
cardStore.createIndex("by-type", "Type");
cardStore.createIndex("by-cost", "Cost");
cardStore.createIndex("by-power", "Power");
cardStore.createIndex("by-rarity", "Rarity");
} }
}); }
export let Database = new CardDatabase();
export async function getCards(filter: CardFilter) {
let table = Database.cards;
// Get best IDB index
let query: Dexie.Collection<Card, string>;
if (filter.Powers && filter.Powers.length > 0) {
query = table.where("Power").anyOf(filter.Powers);
} else if (filter.Costs && filter.Costs.length > 0) {
query = table.where("Cost").anyOf(filter.Costs);
} else if (filter.Sets && filter.Sets.length > 0) {
query = table.where("Set").anyOf(filter.Sets);
} else if (filter.Types && filter.Types.length > 0) {
query = table.where("Type").anyOf(filter.Types);
} else {
if (
filter.Name ||
filter.Rules ||
filter.Traits ||
filter.Rarities ||
filter.Elements
) {
query = table.toCollection();
} else {
// Nothing to query, return everything
return await table.toArray();
}
}
return await query
.filter(x => {
if (filter.Name) {
if (
!`${x.Name}, ${x.Subname}`
.toLowerCase()
.includes(filter.Name.toLowerCase())
) {
return false;
}
}
if (filter.Rules) {
if (
!`${x.Keywords.join(" ~ ")} ~ ${x.Text}`
.toLowerCase()
.includes(filter.Rules.toLowerCase())
) {
return false;
}
}
if (filter.Traits && filter.Traits.length > 0) {
let found = false;
for (const trait of x.Traits) {
if (filter.Traits.includes(trait)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
if (filter.Sets && filter.Sets.length > 0) {
if (!filter.Sets.includes(x.Set)) {
return false;
}
}
if (filter.Types && filter.Types.length > 0) {
if (!filter.Types.includes(x.Type)) {
return false;
}
}
if (filter.Elements && filter.Elements.length > 0) {
let found = false;
for (const element of x.Element) {
if (filter.Elements.includes(element)) {
found = true;
break;
}
}
if (x.Requirement) {
for (const element in x.Requirement) {
if (filter.Elements.includes(element)) {
found = true;
break;
}
}
}
if (x.ProblemRequirement) {
for (const element in x.ProblemRequirement) {
if (filter.Elements.includes(element)) {
found = true;
break;
}
}
}
if (!found) {
return false;
}
}
if (filter.Powers && filter.Powers.length > 0) {
if (
typeof x.Power === "undefined" ||
!filter.Powers.includes(x.Power)
) {
return false;
}
}
if (filter.Costs && filter.Costs.length > 0) {
if (typeof x.Cost === "undefined" || !filter.Costs.includes(x.Cost)) {
return false;
}
}
if (filter.Rarities && filter.Rarities.length > 0) {
if (!filter.Rarities.includes(x.Rarity)) {
return false;
}
}
return true;
})
.toArray();
} }

View file

@ -1,5 +1,5 @@
import { SetFile } from "./types"; import { SetFile } from "./types";
import { openCardDB } from "./database"; import { Database } from "./database";
const baseURL = "https://mcg.zyg.ovh/setdata/"; const baseURL = "https://mcg.zyg.ovh/setdata/";
const allSets = [ const allSets = [
@ -19,20 +19,17 @@ const allSets = [
]; ];
export async function loadSets() { export async function loadSets() {
const db = await openCardDB(); const itemcount = await Database.cards.count();
const itemcount = await db.count("card");
if (itemcount > 100) { if (itemcount > 100) {
// DB already filled, exit early // DB already filled, exit early
return; return;
} }
const sets = await Promise.all(allSets.map(set => downloadSet(set))); const sets = await Promise.all(allSets.map(set => downloadSet(set)));
await Promise.all( await Promise.all(
sets.map( sets.map(async set => {
async set => console.log(`Processing cards from ${set.Name}`);
await Promise.all( return await Database.cards.bulkPut(set.Cards);
set.Cards.map(async card => await db.put("card", card)) })
)
)
); );
} }

View file

@ -26,3 +26,15 @@ export interface Card {
ProblemRequirement?: PowerRequirement; ProblemRequirement?: PowerRequirement;
Boosted?: Card; Boosted?: Card;
} }
export interface CardFilter {
Name?: string;
Traits?: string[];
Rules?: string;
Elements?: string[];
Sets?: string[];
Types?: string[];
Costs?: number[];
Powers?: number[];
Rarities?: string[];
}

View file

@ -2955,6 +2955,11 @@ detect-node@^2.0.4:
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c"
integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw== integrity sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==
dexie@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/dexie/-/dexie-2.0.4.tgz#6027a5e05879424e8f9979d8c14e7420f27e3a11"
integrity sha512-aQ/s1U2wHxwBKRrt2Z/mwFNHMQWhESerFsMYzE+5P5OsIe5o1kgpFMWkzKTtkvkyyEni6mWr/T4HUJuY9xIHLA==
diff@^3.2.0: diff@^3.2.0:
version "3.5.0" version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@ -4453,11 +4458,6 @@ icss-utils@^2.1.0:
dependencies: dependencies:
postcss "^6.0.1" postcss "^6.0.1"
idb@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/idb/-/idb-4.0.4.tgz#f0c06f58bd78fe557e4de944fd6ba6a3240faa8e"
integrity sha512-ZYsaBSNub2yAnjvmRKudQlMIPqZQIefAOwNIPeXC+RLIeXYFc0UNQqONKNuQeBNf8oBOV5L75yJ9zFISjHVj4g==
ieee754@^1.1.4: ieee754@^1.1.4:
version "1.1.13" version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"