diff --git a/README.md b/README.md
index 7078f81..761e747 100644
Binary files a/README.md and b/README.md differ
diff --git a/client/public/components/basket.mjs b/client/public/components/basket.mjs
index 6d7ff3c..25de764 100644
--- a/client/public/components/basket.mjs
+++ b/client/public/components/basket.mjs
@@ -7,6 +7,18 @@ class Basket extends Component {
super(Basket);
}
+ OnMount() {
+ const basket = localStorage.getItem('basket');
+ if (basket) {
+ const basketItems = JSON.parse(basket);
+ this.setState({
+ ...basketItems,
+ }, false);
+ console.log(basketItems, this.state);
+ }
+
+ }
+
Render() {
return {
template: /* html */`
diff --git a/client/public/index.html b/client/public/index.html
index b4a1388..a45a065 100644
--- a/client/public/index.html
+++ b/client/public/index.html
@@ -25,7 +25,6 @@
-
diff --git a/docs/DATABASE.md b/docs/DATABASE.md
index e69de29..df8f2dd 100644
--- a/docs/DATABASE.md
+++ b/docs/DATABASE.md
@@ -0,0 +1,3 @@
+# Database
+
+I decided to go with a RDBMS, PostgreSql as I am familiar with it.
diff --git a/src/controllers/brick-controller.js b/src/controllers/brick-controller.js
index 96d3a63..f2af91e 100644
--- a/src/controllers/brick-controller.js
+++ b/src/controllers/brick-controller.js
@@ -1,19 +1,29 @@
const ControllerMaster = require('./controller-master.js');
const Database = require('../database/database.js');
+const Logger = require('../logger.js');
const PgFormat = require('pg-format');
-async function Search(fuzzyString) {
+async function Search(fuzzyStrings) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(`
- SELECT lego_brick.id, lego_brick.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
- FROM lego_brick
- LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
- WHERE lego_brick.id ~* $1 OR lego_brick.name ~* $1 OR tag.name ~* $1
- `, [fuzzyString]);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(PgFormat(`
+ SELECT lego_brick.id, lego_brick.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
+ FROM lego_brick
+ LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
+ WHERE lego_brick.id ~* ANY(ARRAY[%L]) OR lego_brick.name ~* ANY(ARRAY[%L]) OR tag.name ~* ANY(ARRAY[%L])
+ `, fuzzyStrings, fuzzyStrings, fuzzyStrings), []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -30,8 +40,8 @@ async function Search(fuzzyString) {
const bName = b.name.toLowerCase();
const aTag = a.tag.toLowerCase();
const bTag = b.tag.toLowerCase();
- const aFuzzy = fuzzyString.toLowerCase();
- const bFuzzy = fuzzyString.toLowerCase();
+ const aFuzzy = fuzzyStrings[0].toLowerCase();
+ const bFuzzy = fuzzyStrings[0].toLowerCase();
const aDist = ControllerMaster.LevenshteinDistance(aName, aFuzzy);
const bDist = ControllerMaster.LevenshteinDistance(bName, bFuzzy);
@@ -64,13 +74,22 @@ async function Search(fuzzyString) {
async function SumPrices(bricksArr, quantityArray) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(PgFormat(`
- SELECT COALESCE(new_price, price) AS "price"
- FROM lego_brick
- LEFT JOIN lego_brick_inventory AS brick_inventory ON brick_inventory.brick_id = lego_brick.id
- WHERE lego_brick.id IN (%L);
- `, bricksArr), []);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(PgFormat(`
+ SELECT COALESCE(new_price, price) AS "price"
+ FROM lego_brick
+ LEFT JOIN lego_brick_inventory AS brick_inventory ON brick_inventory.brick_id = lego_brick.id
+ WHERE lego_brick.id IN (%L);
+ `, bricksArr), []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -90,15 +109,24 @@ async function SumPrices(bricksArr, quantityArray) {
async function GetBulkBricks(bricksArr) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(PgFormat(`
- SELECT lego_brick.id, lego_brick.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
- FROM lego_brick
- LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
- WHERE lego_brick.id IN (%L);
- `, bricksArr), []);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(PgFormat(`
+ SELECT lego_brick.id, lego_brick.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
+ FROM lego_brick
+ LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
+ WHERE lego_brick.id IN (%L);
+ `, bricksArr), []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -120,25 +148,34 @@ async function GetBulkBricks(bricksArr) {
async function GetBrick(brickId) {
await Database.Query('BEGIN TRANSACTION;');
-
- const dbres = await Database.Query(`
- SELECT lego_brick.id, lego_brick.name, tag.name AS "tag",
- inv.price, inv.new_price AS "discount", inv.stock,
- inv.last_updated AS "last_stock_update",
- weight, dimensions_x, dimensions_y, dimensions_z
- FROM lego_brick
- LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
- LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- WHERE lego_brick.id = $1;
- `, [brickId]);
- const colDbres = await Database.Query(`
- SELECT lego_brick_colour.id, lego_brick_colour.name, lego_brick_colour.hexrgb,
- colour_type.name AS "colour_type"
- FROM lego_brick_colour
- LEFT JOIN colour_type AS colour_type ON lego_brick_colour.col_type = colour_type.id
- `, []);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ let colDbres;
+ try {
+ dbres = await Database.Query(`
+ SELECT lego_brick.id, lego_brick.name, tag.name AS "tag",
+ inv.price, inv.new_price AS "discount", inv.stock,
+ inv.last_updated AS "last_stock_update",
+ weight, dimensions_x, dimensions_y, dimensions_z
+ FROM lego_brick
+ LEFT JOIN lego_brick_inventory AS inv ON inv.brick_id = lego_brick.id
+ LEFT JOIN lego_brick_tag AS tags ON tags.brick_id = lego_brick.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ WHERE lego_brick.id = $1;
+ `, [brickId]);
+ colDbres = await Database.Query(`
+ SELECT lego_brick_colour.id, lego_brick_colour.name, lego_brick_colour.hexrgb,
+ colour_type.name AS "colour_type"
+ FROM lego_brick_colour
+ LEFT JOIN colour_type AS colour_type ON lego_brick_colour.col_type = colour_type.id
+ `, []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
diff --git a/src/controllers/n-grams.js b/src/controllers/n-grams.js
deleted file mode 100644
index b02e604..0000000
--- a/src/controllers/n-grams.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const axios = require("axios");
-
-let StaticDictionary = [];
-
-async function Init() {
- await axios.get('http://www.mieliestronk.com/corncob_lowercase.txt').then(response => {
- StaticDictionary = response.data;
- });
-}
-
-// probability of trigram/bigram
-const BigramCommonality = {
- th: 1.52,
- he: 1.28,
- in: 0.94,
- er: 0.94,
- an: 0.82,
- re: 0.68,
- nd: 0.63,
- at: 0.59,
- on: 0.57,
- nt: 0.56,
- ha: 0.56,
- es: 0.56,
- st: 0.55,
- en: 0.55,
- ed: 0.53,
- to: 0.52,
- it: 0.50,
- ou: 0.50,
- ea: 0.47,
- hi: 0.46,
- is: 0.46,
- or: 0.43,
- ti: 0.34,
- as: 0.33,
- te: 0.27,
- et: 0.19,
- ng: 0.18,
- of: 0.16,
- al: 0.09,
- de: 0.09,
- se: 0.08,
- le: 0.08,
- sa: 0.06,
- si: 0.05,
- ar: 0.04,
- ve: 0.04,
- ra: 0.04,
- ld: 0.02,
- ur: 0.02,
-};
-
-const TrigramCommonality = {
- the: 1.81,
- and: 0.73,
- tha: 0.33,
- ent: 0.42,
- ing: 0.72,
- ion: 0.42,
- tio: 0.31,
- for: 0.34,
- oft: 0.22,
- sth: 0.21,
-};
-
-function MostProbableAlternateQueries(query) {
- const words = query.split(' ');
-
- const reconstruction = [];
-
- for (let i = 0; i < words.length; i++) {
- const mostLikely = MostProbableMissSpelling(words[i]);
- reconstruction.push([...mostLikely]);
- }
-
- console.log(reconstruction)
-
- // work out a bit of context to determine the most likely sentence
-}
-
-function MostProbableMissSpelling(word) {
- // First work out if it's intended to be a word
-
- console.log(word);
- return BiGrams(word);
-}
-
-function ConditionalTrigramProbability(token) {
-
-}
-
-function ConditionalBigramProbability(token) {
-
-}
-
-// returns list of tokens
-function TriGrams(word) {
- return NGrams(word, 3);
-}
-
-function BiGrams(word) {
- return NGrams(word, 2);
-}
-
-function NGrams(word, n) {
- const tokens = [];
- for (let i = 0; i < word.length - n + 1; i++) {
- tokens.push(word.substring(i, i + n));
- }
- return tokens;
-}
-
-module.exports = {
- Init,
- MostProbableAlternateQueries,
- MostProbableMissSpelling,
-};
diff --git a/src/controllers/set-controller.js b/src/controllers/set-controller.js
index b4486e0..8deb79f 100644
--- a/src/controllers/set-controller.js
+++ b/src/controllers/set-controller.js
@@ -1,19 +1,29 @@
const ControllerMaster = require('./controller-master.js');
const Database = require('../database/database.js');
+const Logger = require('../logger.js');
const PgFormat = require('pg-format');
-async function Search(fuzzyString) {
+async function Search(fuzzyStrings) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(`
- SELECT lego_set.id, lego_set.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
- FROM lego_set
- LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- LEFT JOIN lego_set_inventory AS inv ON inv.set_id = lego_set.id
- WHERE lego_set.id ~* $1 OR lego_set.name ~* $1 OR tag.name ~* $1
- `, [fuzzyString]);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(PgFormat(`
+ SELECT lego_set.id, lego_set.name, tag.name AS "tag", inv.price, inv.new_price AS "discount"
+ FROM lego_set
+ LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ LEFT JOIN lego_set_inventory AS inv ON inv.set_id = lego_set.id
+ WHERE lego_set.id ~* ANY(ARRAY[%L]) OR lego_set.name ~* ANY(ARRAY[%L]) OR tag.name ~* ANY(ARRAY[%L])
+ `, fuzzyStrings, fuzzyStrings, fuzzyStrings), []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -30,8 +40,8 @@ async function Search(fuzzyString) {
const bName = b.name.toLowerCase();
const aTag = a.tag.toLowerCase();
const bTag = b.tag.toLowerCase();
- const aFuzzy = fuzzyString.toLowerCase();
- const bFuzzy = fuzzyString.toLowerCase();
+ const aFuzzy = fuzzyStrings[0].toLowerCase();
+ const bFuzzy = fuzzyStrings[0].toLowerCase();
const aDist = ControllerMaster.LevenshteinDistance(aName, aFuzzy);
const bDist = ControllerMaster.LevenshteinDistance(bName, bFuzzy);
@@ -74,13 +84,22 @@ async function Search(fuzzyString) {
async function SumPrices(setsArray, quantityArray) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(PgFormat(`
- SELECT COALESCE(new_price, price) AS "price"
- FROM lego_set
- LEFT JOIN lego_set_inventory AS set_inventory ON set_inventory.set_id = lego_set.id
- WHERE lego_set.id IN (%L);
- `, setsArray), []);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(PgFormat(`
+ SELECT COALESCE(new_price, price) AS "price"
+ FROM lego_set
+ LEFT JOIN lego_set_inventory AS set_inventory ON set_inventory.set_id = lego_set.id
+ WHERE lego_set.id IN (%L);
+ `, setsArray), []);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -101,19 +120,28 @@ async function SumPrices(setsArray, quantityArray) {
async function GetSet(setId) {
await Database.Query('BEGIN TRANSACTION;');
- const dbres = await Database.Query(`
- SELECT lego_set.id, lego_set.name, description, tag.name AS "tag",
- set_contents.brick_id, set_contents.amount, inv.price,
- date_released, weight, dimensions_x, dimensions_y, dimensions_z,
- new_price AS "discount", inv.stock, inv.last_updated AS "last_stock_update"
- FROM lego_set
- LEFT JOIN lego_set_inventory AS inv ON inv.set_id = lego_set.id
- LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- LEFT JOIN set_descriptor AS set_contents ON set_contents.set_id = lego_set.id
- WHERE lego_set.id = $1;
- `, [setId]);
- await Database.Query('END TRANSACTION;');
+ let dbres;
+ try {
+ dbres = await Database.Query(`
+ SELECT lego_set.id, lego_set.name, description, tag.name AS "tag",
+ set_contents.brick_id, set_contents.amount, inv.price,
+ date_released, weight, dimensions_x, dimensions_y, dimensions_z,
+ new_price AS "discount", inv.stock, inv.last_updated AS "last_stock_update"
+ FROM lego_set
+ LEFT JOIN lego_set_inventory AS inv ON inv.set_id = lego_set.id
+ LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ LEFT JOIN set_descriptor AS set_contents ON set_contents.set_id = lego_set.id
+ WHERE lego_set.id = $1;
+ `, [setId]);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
// validate database response
if (dbres.rows.length === 0) {
@@ -142,22 +170,31 @@ async function GetSet(setId) {
}
async function GetSets(page, resPerPage) {
- // query for the set
await Database.Query('BEGIN TRANSACTION;');
- const countRes = await Database.Query('SELECT COUNT (*) FROM lego_set;');
- const total = parseInt(countRes.rows[0].count);
- const dbres = await Database.Query(`
+ let countRes;
+ let dbres;
+ try {
+ countRes = await Database.Query('SELECT COUNT (*) FROM lego_set;');
+ dbres = await Database.Query(`
SELECT
- lego_set.id, lego_set.name, price, new_price AS "discount", tag.name AS "tag"
- FROM lego_set
- LEFT JOIN lego_set_inventory as inv ON lego_set.id = inv.set_id
- LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
- LEFT JOIN tag AS tag ON tags.tag = tag.id
- ORDER BY id ASC
- LIMIT $1
- OFFSET $2;`,
- [resPerPage, page * resPerPage]);
- await Database.Query('END TRANSACTION;');
+ lego_set.id, lego_set.name, price, new_price AS "discount", tag.name AS "tag"
+ FROM lego_set
+ LEFT JOIN lego_set_inventory as inv ON lego_set.id = inv.set_id
+ LEFT JOIN lego_set_tag AS tags ON tags.set_id = lego_set.id
+ LEFT JOIN tag AS tag ON tags.tag = tag.id
+ ORDER BY id ASC
+ LIMIT $1
+ OFFSET $2;`,
+ [resPerPage, page * resPerPage]);
+ await Database.Query('COMMIT TRANSACTION;');
+ } catch {
+ await Database.Query('ROLLBACK TRANSACTION;');
+ Logger.Error('Database Error');
+ return {
+ error: 'Database error',
+ };
+ }
+ const total = parseInt(countRes.rows[0].count);
// validate database response
if (dbres.rows.length === 0) {
@@ -174,6 +211,7 @@ async function GetSets(page, resPerPage) {
set.tags = [];
}
+
// combine (joined) rows into a single array
sets = sets.reduce((arr, current) => {
if (!arr.some(item => item.id === current.id)) {
diff --git a/src/controllers/spellchecker.js b/src/controllers/spellchecker.js
new file mode 100644
index 0000000..f32c049
--- /dev/null
+++ b/src/controllers/spellchecker.js
@@ -0,0 +1,168 @@
+const axios = require('axios');
+
+let StaticDictionary = [];
+let MispellingDictionaryRAW = '';
+
+async function Init() {
+ // yes i know it could be unreliable to get them from external, untrusted sources
+ // this algorithm is purely for fun and is very much a "work in progress"
+ await axios.get('http://www.mieliestronk.com/corncob_lowercase.txt').then(response => {
+ StaticDictionary = response.data;
+ });
+
+ await axios.get('https://www.dcs.bbk.ac.uk/~roger/missp.dat').then(response => {
+ MispellingDictionaryRAW = response.data;
+ });
+}
+
+// probability of trigram/bigram
+const BigramCommonality = {
+ th: 1.52,
+ he: 1.28,
+ in: 0.94,
+ er: 0.94,
+ an: 0.82,
+ re: 0.68,
+ nd: 0.63,
+ at: 0.59,
+ on: 0.57,
+ nt: 0.56,
+ ha: 0.56,
+ es: 0.56,
+ st: 0.55,
+ en: 0.55,
+ ed: 0.53,
+ to: 0.52,
+ it: 0.50,
+ ou: 0.50,
+ ea: 0.47,
+ hi: 0.46,
+ is: 0.46,
+ or: 0.43,
+ ti: 0.34,
+ as: 0.33,
+ te: 0.27,
+ et: 0.19,
+ ng: 0.18,
+ of: 0.16,
+ al: 0.09,
+ de: 0.09,
+ se: 0.08,
+ le: 0.08,
+ sa: 0.06,
+ si: 0.05,
+ ar: 0.04,
+ ve: 0.04,
+ ra: 0.04,
+ ld: 0.02,
+ ur: 0.02,
+};
+
+const TrigramCommonality = {
+ the: 1.81,
+ and: 0.73,
+ tha: 0.33,
+ ent: 0.42,
+ ing: 0.72,
+ ion: 0.42,
+ tio: 0.31,
+ for: 0.34,
+ oft: 0.22,
+ sth: 0.21,
+};
+
+function MostProbableAlternateQueries(query) {
+ const words = query.split(' ');
+
+ const reconstruction = [];
+
+ for (let i = 0; i < words.length; i++) {
+ const mostLikely = MostProbableMissSpelling(words[i]);
+ reconstruction.push([...mostLikely]);
+ }
+
+ // go over suggested fixes and construct the permutations of the query
+ // for example if the query is 'brik 2x10X4', the reconstructions are:
+ // brick, [2x10x4, 2 x 10 x 4]
+ // therefore the permutations are:
+ // brick 2x10x4, brick 2 x 10 x 4
+
+ let totalLength = 1;
+ for (let i = 0; i < reconstruction.length; i++) {
+ const length = reconstruction[i].length;
+ totalLength *= length;
+ }
+
+ const permutations = [];
+ for (let i = 0; i < totalLength; i++) {
+ const permutation = [];
+ for (let j = 0; j < reconstruction.length; j++) {
+ const index = i % reconstruction[j].length;
+ permutation.push(reconstruction[j][index]);
+ }
+ permutations.push(permutation.join(' '));
+ }
+
+ // work out a bit of context to determine the most likely sentence
+ return permutations;
+}
+
+function MostProbableMissSpelling(word) {
+ // First work out if it's intended to be a word
+ if (word.match(/[0-9]/g)) {
+ // it's got a number so probably not a word
+ // if it's a number, it's either a year, id or dimension
+
+ // if it's a dimension, we should split by x X
+ if (word.match(/[xX]/g)) {
+ // it's a dimension split by x X
+ const split = word.split(/[xX]/g);
+ return [split.join(' x '), word];
+ }
+
+ return [word];
+ }
+
+ // if it's one letter, it's probably not a word
+ if (word.length === 1) {
+ return [word];
+ }
+
+ const trigrams = TriGrams(word);
+ const bigrams = BiGrams(word);
+
+ return [word];
+}
+
+function ConditionalTrigramProbability(token) {
+ // closeness of token to the trigram commonality
+
+
+}
+
+function ConditionalBigramProbability(token) {
+
+}
+
+// returns list of tokens
+function TriGrams(word) {
+ return NGrams(word, 3);
+}
+
+function BiGrams(word) {
+ return NGrams(word, 2);
+}
+
+function NGrams(word, n) {
+ const tokens = [];
+ for (let i = 0; i < word.length - n + 1; i++) {
+ tokens.push(word.substring(i, i + n));
+ }
+ return tokens;
+}
+
+module.exports = {
+ Init,
+ MostProbableAlternateQueries,
+ MostProbableMissSpelling,
+};
diff --git a/src/index.js b/src/index.js
index 1f5983f..b52d17f 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,7 +5,7 @@ const API = require('./routes/api.js');
const Database = require('./database/database.js');
-const ngrams = require('./controllers/n-grams.js');
+const ngrams = require('./controllers/spellchecker.js');
async function main() {
Config.Load();
@@ -20,15 +20,16 @@ async function main() {
Logger.Info('Pre-Init Complete');
await Database.Connect();
+ await ngrams.Init();
Server.Listen(process.env.PORT);
API.Init();
- await ngrams.Init();
- ngrams.MostProbableAlternateQueries('brick 2x10x4');
- ngrams.MostProbableAlternateQueries('lego star wars battlefront');
- ngrams.MostProbableAlternateQueries('lego stor was s');
+ ngrams.MostProbableAlternateQueries('brick 2x10X4 2 x 2');
+ // ngrams.MostProbableAlternateQueries('brick 2 x 10 x 4 2x10X4');
+ // ngrams.MostProbableAlternateQueries('lego star wars battlefront');
+ // ngrams.MostProbableAlternateQueries('lego stor was s');
}
main();
diff --git a/src/routes/helpers.js b/src/routes/helpers.js
index 9deb5ad..be239c6 100644
--- a/src/routes/helpers.js
+++ b/src/routes/helpers.js
@@ -30,10 +30,11 @@ async function CalculateBasketPrice(req, res) {
}
}
- const setSubtotal = await SetController.SumPrices(setList, setQuantities);
- const brickSubtotal = await BrickController.SumPrices(brickList, brickQuantities);
+ let setSubtotal = await SetController.SumPrices(setList, setQuantities);
+ let brickSubtotal = await BrickController.SumPrices(brickList, brickQuantities);
- console.log(setSubtotal, brickSubtotal);
+ if (setSubtotal.error) setSubtotal = 0;
+ if (brickSubtotal.error) brickSubtotal = 0;
res.send({
data: {
diff --git a/src/routes/query-router.js b/src/routes/query-router.js
index 2d4ed13..10c6977 100644
--- a/src/routes/query-router.js
+++ b/src/routes/query-router.js
@@ -1,6 +1,7 @@
const ControllerMaster = require('../controllers/controller-master.js');
const BrickController = require('../controllers/brick-controller.js');
const SetController = require('../controllers/set-controller.js');
+const SpellController = require('../controllers/spellchecker.js');
async function Search(req, res) {
const q = req.query.q;
@@ -15,14 +16,16 @@ async function Search(req, res) {
return;
}
+ const alternateQueries = SpellController.MostProbableAlternateQueries(sanatisedQuery);
+
const pageRequested = req.query.page || 1;
const perPage = req.query.per_page || 16;
// TODO: it is tricky to do a database offset / limit here
// due to the fact that we have to combine the results of
// the two queries, look into me (maybe merging the queries)
- const brickResults = await BrickController.Search(sanatisedQuery);
- const setResults = await SetController.Search(sanatisedQuery);
+ const brickResults = await BrickController.Search(alternateQueries);
+ const setResults = await SetController.Search(alternateQueries);
if (brickResults.error && setResults.error) {
return res.send(JSON.stringify({
@@ -32,8 +35,8 @@ async function Search(req, res) {
}
let count = 0;
- if (brickResults) count += brickResults.length;
- if (setResults) count += setResults.length;
+ if (!brickResults.error) count += brickResults.length;
+ if (!setResults.error) count += setResults.length;
if (brickResults.error) {
// remove after the requested page
@@ -72,8 +75,8 @@ async function Search(req, res) {
const bName = b.name.toLowerCase();
const aTag = a.tag.toLowerCase();
const bTag = b.tag.toLowerCase();
- const aFuzzy = q.toLowerCase();
- const bFuzzy = q.toLowerCase();
+ const aFuzzy = alternateQueries[0].toLowerCase();
+ const bFuzzy = alternateQueries[0].toLowerCase();
const aDist = ControllerMaster.LevenshteinDistance(aName, aFuzzy);
const bDist = ControllerMaster.LevenshteinDistance(bName, bFuzzy);
diff --git a/src/routes/sets-router.js b/src/routes/sets-router.js
index 4ba7015..3565f42 100644
--- a/src/routes/sets-router.js
+++ b/src/routes/sets-router.js
@@ -1,5 +1,4 @@
const Controller = require('../controllers/set-controller.js');
-const Database = require('../database/database.js');
async function Get(req, res) {
// get id from url
@@ -18,7 +17,7 @@ async function Get(req, res) {
async function Featured(req, res) {
// query all sets and return all of them
- const { sets } = await Controller.GetSets(0, 8);
+ const { sets } = await Controller.GetSets(0, 10);
if (sets.error) {
res.send(JSON.stringify(sets));