diff --git a/examples/directDbAccess.js b/examples/directDbAccess.js index aec4e58..9ebadc9 100644 --- a/examples/directDbAccess.js +++ b/examples/directDbAccess.js @@ -1,5 +1,7 @@ +const usBabyNamesModule = await import('../lib/usBabyNames.mjs'); + const directDbAccess = async () => { - const usBabyNamesModule = await import('../lib/usBabyNames.mjs'); + const nameDataDb = usBabyNamesModule.nameDataDb; const nameDetailsDb = usBabyNamesModule.nameDetailsDb; const nameDetailsSql = "SELECT * from usNameDetails where name = 'jonathan' and sex = 'm' "; diff --git a/examples/getAllByName.js b/examples/getAllByName.js new file mode 100644 index 0000000..40ca4f4 --- /dev/null +++ b/examples/getAllByName.js @@ -0,0 +1,8 @@ +const { getAllByName } = await import('../lib/usBabyNames.mjs'); + +const getAll = async (theName) => { + const nationalNameData = await getAllByName(theName); + console.log('nationalNameData', nationalNameData); +}; + +getAll('jonathan'); diff --git a/examples/getByBirthsRange.js b/examples/getByBirthsRange.js index bc5b919..eb7f659 100644 --- a/examples/getByBirthsRange.js +++ b/examples/getByBirthsRange.js @@ -1,5 +1,6 @@ +const usBabyNamesModule = await import('../lib/usBabyNames.mjs'); + const getByBirthsRange = async () => { - const usBabyNamesModule = await import('../lib/usBabyNames.mjs'); const theNames = await usBabyNamesModule.get({ birthsRange: {start: 0, end: 10}, year: 1975 diff --git a/examples/getById.js b/examples/getById.js index f392c87..60c179d 100644 --- a/examples/getById.js +++ b/examples/getById.js @@ -1,6 +1,7 @@ +const { getById } = await import('../lib/usBabyNames.mjs'); + const getByIdExample = async () => { - const usBabyNames = await import('../lib/usBabyNames.mjs'); - const theName = await usBabyNames.getById(790921); + const theName = await getById(790921); console.log('theName', theName); }; diff --git a/examples/getByName.js b/examples/getByName.js index 685b90d..68e48dd 100644 --- a/examples/getByName.js +++ b/examples/getByName.js @@ -1,7 +1,8 @@ -const getByName = async () => { - const { getByName } = await import('../lib/usBabyNames.mjs'); +const { getByName } = await import('../lib/usBabyNames.mjs'); + +const getByNamed = async () => { const theNames = await getByName('debbie'); console.log('theNames', theNames); }; -getByName(); +getByNamed(); diff --git a/examples/getByRankRange.js b/examples/getByRankRange.js index 032009f..9ebd22a 100644 --- a/examples/getByRankRange.js +++ b/examples/getByRankRange.js @@ -1,5 +1,6 @@ +const usBabyNames = await import('../lib/usBabyNames.mjs'); + async function getByRankRange() { - const usBabyNames = await import('../lib/usBabyNames.mjs'); const theNames = await usBabyNames.get({rankRange: {start: 0, end: 10}}); console.log(theNames); } diff --git a/examples/getByYear.js b/examples/getByYear.js index 026515a..db5668c 100644 --- a/examples/getByYear.js +++ b/examples/getByYear.js @@ -1,5 +1,6 @@ +const usBabyNames = await import('../lib/usBabyNames.mjs'); + async function getByYear() { - const usBabyNames = await import('../lib/usBabyNames.mjs'); const theNames = await usBabyNames.getByYear(1975); console.log(theNames); } diff --git a/examples/getByYearNameSex.js b/examples/getByYearNameSex.js index 5e0f33a..87e4d2e 100644 --- a/examples/getByYearNameSex.js +++ b/examples/getByYearNameSex.js @@ -1,5 +1,6 @@ +const usBabyNames = await import('../lib/usBabyNames.mjs'); + async function getByYearNameSex() { - const usBabyNames = await import('../lib/usBabyNames.mjs'); const theNames = await usBabyNames.get({name: 'jonathan', year: 1975, sex: 'm'}); console.log(theNames); } diff --git a/examples/getDetailed.js b/examples/getDetailed.js index 94988e3..5d2b980 100644 --- a/examples/getDetailed.js +++ b/examples/getDetailed.js @@ -1,5 +1,6 @@ +const usBabyNames = await import('../lib/usBabyNames.mjs'); + const getDetailed = async () => { - const usBabyNames = await import('../lib/usBabyNames.mjs'); const theDetails = await usBabyNames.getDetailed('jonathan', 'm'); console.log('theDetails', theDetails); }; diff --git a/examples/getNameRankAndBirths.js b/examples/getNameRankAndBirths.js index 5b6b040..66fefcb 100644 --- a/examples/getNameRankAndBirths.js +++ b/examples/getNameRankAndBirths.js @@ -1,5 +1,6 @@ +const usBabyNames = await import('../lib/usBabyNames.mjs'); + async function getNameRankAndBirths() { - const usBabyNames = await import('../lib/usBabyNames.mjs'); const theNames = await usBabyNames.getNameRankAndBirthsByYear('kanye', {sex: 'm', getEmptyYears: true}); console.log(theNames); } diff --git a/examples/getStateDate.js b/examples/getStateDate.js new file mode 100644 index 0000000..f122ced --- /dev/null +++ b/examples/getStateDate.js @@ -0,0 +1,8 @@ +const { getStateNameData } = await import('../lib/usBabyNames.mjs'); + +const getStateData = async () => { + const theNames = await getStateNameData('kamala', 'f'); + console.log('theNames', theNames); +}; + +getStateData(); diff --git a/lib/usBabyNames.mjs b/lib/usBabyNames.mjs index d371fd0..4078705 100644 --- a/lib/usBabyNames.mjs +++ b/lib/usBabyNames.mjs @@ -1,12 +1,14 @@ /** usBabyNames.js ... written by Jon Roig (@runnr_az) over a weekend in early 2016 + then kinda evolved from there **/ import sqlite3 from 'sqlite3'; import path from 'path'; import { fileURLToPath } from 'url'; import { join } from 'path'; + const startYear = 1880; const endYear = 2023; @@ -15,6 +17,101 @@ const __dirname = path.dirname(__filename); // get the name of the directory const nameDataDb = new sqlite3.Database( join(__dirname, '..', 'sqlite', 'us-name-data.sqlite')); const nameDetailsDb = new sqlite3.Database( join(__dirname, '..', 'sqlite', 'us-name-details.sqlite')); +const stateNameDb = new sqlite3.Database( join(__dirname, '..', 'sqlite', 'state-name-data.sqlite')); + +const emptyYearObj = { + births: 0, + rank: 0 +}; + +const getAllByName = async (nameInput) => { + const outputObj = { + byYear: {} + }; + + // build an array of empty years + for (let x = startYear; x <= endYear; x++) { + outputObj.byYear[x] = { + usa: { + m: emptyYearObj, + f: emptyYearObj + }, + }; + }; + + const stateNameObjs = await getStateNameData(nameInput); + const nationalNameObjs = await get({ name: nameInput}); + outputObj.detailM = await getDetailed(nameInput, 'm'); + outputObj.detailF = await getDetailed(nameInput, 'f'); + + if (outputObj.detailM?.id) { + delete outputObj.detailM.id; + try { + const decodedNameData = JSON.parse(outputObj.detailM.nameData); + outputObj.detailM.nameData = decodedNameData; + } catch (e) { + const decodedNameData = {}; + } + } + + if (outputObj.detailF?.id) { + delete outputObj.detailF.id; + try { + const decodedNameData = JSON.parse(outputObj.detailF.nameData); + outputObj.detailF.nameData = decodedNameData; + } catch (e) { + const decodedNameData = {}; + } + } + + for (let index in nationalNameObjs) { + const nameObj = nationalNameObjs[index]; + outputObj.byYear[nameObj.year]['usa'][nameObj.sex] = { + births: nameObj.births, + rank: nameObj.rank + }; + } + + for (let index in stateNameObjs) { + const nameObj = stateNameObjs[index]; + outputObj.byYear[nameObj.year][nameObj.state] = { + m: emptyYearObj, + f: emptyYearObj + }; + + outputObj.byYear[nameObj.year][nameObj.state][nameObj.sex] = { + births: nameObj.births, + rank: nameObj.rank + }; + } + return outputObj; +}; + + + +const getStateNameData = async (nameInput, sexInput = null) => { + return new Promise((fulfill, reject) => { + const outputArray = []; + const queryParams = [nameInput]; + + stateNameDb.serialize(() => { + // the basic sql query + let sql = 'SELECT * FROM stateNameData WHERE name = (?) '; + if (sexInput) { + sql += ' and sex = (?)'; + queryParams.push(sexInput); + } + stateNameDb.all(sql, queryParams, (err, rows) => { + if (err) { + console.log('err', err); + reject (err); + } + + fulfill(rows); + }); + }); + }); +}; const getDetailed = async (nameInput, sexInput) => { @@ -61,53 +158,53 @@ const get = async (params) => { nameDataDb.serialize(() => { // the basic sql query let sql = ''; - if (params.unique) { + if (params?.unique) { sql = 'SELECT DISTINCT name FROM usNameData WHERE "b" = "b" '; } else { sql = 'SELECT * FROM usNameData WHERE "b" = "b" '; } // build the filters - if (params.id) { + if (params?.id) { sql += ' AND id = (?) '; queryParams.push(params.id ); } - if (params.name) { + if (params?.name) { sql += ' AND name = (?) '; queryParams.push(params.name.toLowerCase() ); } - if (params.year) { + if (params?.year) { sql += ' AND year = (?) '; queryParams.push(params.year ); } - if (params.yearRange) { + if (params?.yearRange) { sql += ' AND year >= (?) AND year <= (?) '; queryParams.push(params.yearRange.start ); queryParams.push(params.yearRange.end ); } - if (params.sex) { + if (params?.sex) { sql += ' AND sex = (?) '; - queryParams.push(params.sex.toUpperCase() ); + queryParams.push(params.sex.toLowerCase() ); } - if (params.rank) { + if (params?.rank) { sql += ' AND rank = (?) '; queryParams.push(params.rank ); } - if (params.rankRange) { + if (params?.rankRange) { sql += ' AND rank >= (?) AND rank <= (?) '; queryParams.push(params.rankRange.start ); queryParams.push(params.rankRange.end ); } - if (params.births) { + if (params?.births) { sql += ' AND births = (?) '; queryParams.push(params.births ); } - if (params.birthsRange) { + if (params?.birthsRange) { sql += ' AND births >= (?) AND births <= (?) '; queryParams.push(params.birthsRange.start ); queryParams.push(params.birthsRange.end ); } - if (params.unique) { + if (params?.unique) { sql += ' ORDER BY name'; } @@ -124,11 +221,6 @@ const get = async (params) => { }); }; -const emptyYearObj = { - births: 0, - rank: 0 -}; - const getNameRankAndBirthsByYear = async (name, params) => { return new Promise((fulfill, reject) => { @@ -138,12 +230,12 @@ const getNameRankAndBirthsByYear = async (name, params) => { nameDataDb.serialize(() => { // the basic sql query - let sql = 'SELECT year, births, rank FROM usNameData WHERE name = (?)'; + let sql = 'SELECT year, births, rank, sex FROM usNameData WHERE name = (?)'; queryParams.push(name.toLowerCase() ); - if (params.sex) { + if (params?.sex) { sql += ' AND sex = (?) '; - queryParams.push(params.sex.toUpperCase() ); + queryParams.push(params.sex.toLowerCase() ); } // run the query, return the results... @@ -152,7 +244,7 @@ const getNameRankAndBirthsByYear = async (name, params) => { reject(err); } - if (params.getEmptyYears) { + if (params?.getEmptyYears) { for (let x = startYear; x <= endYear; x++) { outputObj[x] = emptyYearObj; } @@ -163,7 +255,8 @@ const getNameRankAndBirthsByYear = async (name, params) => { const nameObj = rows[index]; outputObj[nameObj.year] = { births: nameObj.births, - rank: nameObj.rank + rank: nameObj.rank, + sex: nameObj.sex }; } fulfill(outputObj); @@ -180,6 +273,9 @@ export { get, getNameRankAndBirthsByYear, getDetailed, + getStateNameData, + getAllByName, nameDataDb, - nameDetailsDb - }; \ No newline at end of file + nameDetailsDb, + stateNameDb + }; diff --git a/package.json b/package.json index 82c3211..9ed6f9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "usbabynames", - "version": "2.0.5", + "version": "2.1.0", "description": "Returns data about baby names used in the United States 1880-2021", "main": "lib/usBabyNames.mjs", "scripts": {