bbs-db
v1.0.0
Published
BB's dB - Wraps JSON objects and converts it to a SQL query. Easy.
Maintainers
Readme
BB’s dB
BB’s dB, breeze through schema, sleek machine that screams like a screamer, see?
Queries clean, code lean—complete routine with keystrokes measly.
Need speed? Feed keys, we weave SQL neatly, easily.
Think deep: we keep it simple—yet the features hit exceedingly.
TL;DR (still spittin’ cleanly)
You bring an object; we mint a query—greedy for DB, yet friendly.
INSERTs, SELECTs—alias, extras—shipped efficiently.
Prototypes slip in—non-enumerable—stealthy, discreetly.
Default db wired from .env; your schema sings sweetly.
Install
npm i mysql2 dotenvYour module auto-installs the mixins on import. Just import it once anywhere in your app:
// bb-db.mjs (your module file from earlier messages)
// Importing this file auto-installs the Object prototypes.
import './bb-db.mjs';.env Setup (feed the beast, keep it easy)
Create a .env at your project root:
DB_HOST=127.0.0.1
DB_USER=myuser
DB_PASS=mypassword
DB_NAME=mydatabase
DB_PORT=3306These power the
mysql2/promiseconnection exported asconnection(and aliasdb).
Keep secrets secret—lock it down, no leaks, believe me.
What This Module Gives You (street-level summary)
Exports
buildSelectQuery(table, row, opts?)→{ sql, values }buildInsertQuery(table, row, opts?)→{ sql, values }connection→mysql2/promiseconnectiondb→ alias ofconnectioninstallObjectSqlMixins(opts?)→ installs the prototype helpers (already auto-installed)
Object Prototype Helpers (auto-installed, non-enumerable, guarded)
obj.toSelectQuery(table, opts?)obj.findIn(dbConn, table, opts?)obj.find(table, opts?)(uses defaultdb)obj.toInsertQuery(table, opts?)obj.insertIn(dbConn, table, opts?)obj.insert(table, opts?)(uses defaultdb)
Rhyme with me: We keep APIs breezy, you keep focus on delivery.
Aliases remap keys, extras add fields—precision machinery.
Quickstart (complete—three easy beats)
1) Build & run a SELECT (default db)
const rows = await ({ url: 'https://example.com', lastStatus: 200 })
.find('ad_impressions');
// rows → array of records2) Build & run an INSERT (default db)
const res = await ({ url: 'https://example.com', lastStatus: 200 })
.insert('ad_impressions', {
extra: { createdAt: '2025-08-29 10:00:00.000' } // DATETIME(3) friendly
});
// res → mysql2 OkPacket (insertId, affectedRows, etc.)3) Aliasing & extras (same shape for SELECT & INSERT)
const mapping = { 'headers.User-Agent': 'headers_user_agent' };
const rows = await ({ 'headers.User-Agent': 'UA-1', url: 'https://x.com' })
.find('ad_impressions', {
alias: mapping,
extra: { 'headers.Referer': 'https://ref.example' }
});
const ins = await ({ 'headers.User-Agent': 'UA-1', url: 'https://x.com' })
.insert('ad_impressions', {
alias: mapping,
extra: { createdAt: '2025-08-29 10:00:00.000' }
});Prototype Methods (deep details, but still gleamy)
Six sleek sneaks—API chic, designed to keep your code pristine, dreamy.
Each mirrors the builder exports so switching styles is easy.
obj.toSelectQuery(table, opts?) → { sql, values }
Turn this object’s keys into a parameterized SELECT.
- Opts
alias?: Record<string,string>— map object key → DB columnextra?: Record<string,any>— merge additional equality filters
undefinedvalues in the object becomeIS NULLpredicates (no placeholder).
Example
const filter = { url: 'https://x.com', lastStatus: 200 };
const { sql, values } = filter.toSelectQuery('ad_impressions');
// SELECT * FROM `ad_impressions` WHERE `url` = ? AND `lastStatus` = ?
// values: ['https://x.com', 200]obj.findIn(dbConn, table, opts?) → Promise<any[]>
Execute the SELECT using the provided connection.
Example
const rows = await ({ lastResponse: undefined })
.findIn(db, 'ad_impressions'); // WHERE `lastResponse` IS NULLobj.find(table, opts?) → Promise<any[]> (default db)
Same as findIn, but uses the module’s exported db.
Example
const rows = await ({ 'headers.User-Agent': 'UA-1' })
.find('ad_impressions', { alias: { 'headers.User-Agent': 'headers_user_agent' }});obj.toInsertQuery(table, opts?) → { sql, values }
Mirror of buildInsertQuery on the object itself.
- Opts
alias?: Record<string,string>extra?: Record<string,any>
Example
const row = { url: 'https://x.com', lastStatus: 200 };
const { sql, values } = row.toInsertQuery('ad_impressions', {
extra: { createdAt: '2025-08-29 10:00:00.000' }
});obj.insertIn(dbConn, table, opts?) → Promise<any>
Build and execute an INSERT with an explicit connection.
Example
const res = await ({ url: 'https://x.com', lastStatus: 200 })
.insertIn(db, 'ad_impressions', {
alias: { 'headers.User-Agent': 'headers_user_agent' },
extra: { createdAt: '2025-08-29 10:00:00.000' }
});
// res → OkPacketobj.insert(table, opts?) → Promise<any> (default db)
Same as insertIn, but uses the module’s db.
Example
await ({ url: 'https://x.com', lastStatus: 200 })
.insert('ad_impressions');Builder Functions (compose before you propose)
Some devs like raw control—build the SQL, then roll.
These mirror the prototypes so your code reads whole.
buildSelectQuery(table, row, opts?) → { sql, values }
- Applies
aliasremaps, mergesextra. - Treats
undefinedinrow/extraasNULLand emitsIS NULL.
Example
const { sql, values } = buildSelectQuery('ad_impressions', {
url: 'https://example.com', lastResponse: undefined
});
// SELECT * FROM `ad_impressions` WHERE `url` = ? AND `lastResponse` IS NULL
// values: ['https://example.com']buildInsertQuery(table, row, opts?) → { sql, values }
- Applies
alias, mergesextra. undefinedbound asNULL(placeholder still present).- Backtick-escapes column names.
Example
const { sql, values } = buildInsertQuery('ad_impressions', {
url: 'https://x.com', lastStatus: 200
}, {
alias: { 'headers.User-Agent': 'headers_user_agent' },
extra: { createdAt: '2025-08-29 10:00:00.000' }
});Exports (chapter next—crisp and direct, not merely pretty)
Explicit lists, explicit gifts—no mystery.
Each export explained with clarity, zero trickery.
connection
A mysql2/promise createConnection instance using your .env credentials.
Use it if you want the raw connection (transactions, pooling elsewhere, etc.).
import { connection } from './bb-db.mjs';
await connection.execute('SELECT 1');db
Alias of connection. The default connection used by obj.find() and obj.insert().
import { db } from './bb-db.mjs';
const [rows] = await db.execute('SELECT NOW()');buildSelectQuery(table, row, opts?)
See builder section above. Use if you want to control execution separately.
import { buildSelectQuery, db } from './bb-db.mjs';
const { sql, values } = buildSelectQuery('ad_impressions', { url: 'https://x.com' });
const [rows] = await db.execute(sql, values);buildInsertQuery(table, row, opts?)
See builder section above.
import { buildInsertQuery, db } from './bb-db.mjs';
const { sql, values } = buildInsertQuery('ad_impressions', { url: 'https://x.com' });
await db.execute(sql, values);installObjectSqlMixins(opts?)
Installs the prototype helpers. In your module it’s already called on import.
Call it manually only if you disabled auto-install.
import { installObjectSqlMixins } from './bb-db.mjs';
installObjectSqlMixins(); // optional if you turned off auto-installPatterns, Tips, and Traps (read to keep it elite)
Prototype safety
Methods are non-enumerable and guarded—won’t override existing names or pollute JSON/for…in.NULL vs undefined
- SELECT:
undefined→IS NULL(no placeholder). - INSERT:
undefined→ bound asNULL(placeholder present).
- SELECT:
DATETIME(3)
UseYYYY-MM-DD HH:mm:ss.SSS(no trailingZ).
Example:new Date().toISOString().slice(0, 23).replace('T', ' ').Aliasing
Keep your object keys ergonomic; map them once at the boundary withalias.Extras
Stash constants (e.g.,createdAt,runId) viaextra—no need to mutate the source object.Security
All values are positional parameters; identifiers are backtick-escaped—no string interpolation.
License
Free to breathe, free to weave: your schema, your dream, your dB.
Ship it discreetly, completely—clean like a screamer in a 1U sleeve.
