New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@platformatic/sql-mapper

Package Overview
Dependencies
Maintainers
6
Versions
332
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@platformatic/sql-mapper - npm Package Compare versions

Comparing version 0.22.0 to 0.23.0

29

lib/entity.js

@@ -17,3 +17,3 @@ 'use strict'

function createMapper (defaultDb, sql, log, table, fields, primaryKeys, relations, queries, autoTimestamp, schema, useSchemaInName, limitConfig) {
function createMapper (defaultDb, sql, log, table, fields, primaryKeys, relations, queries, autoTimestamp, schema, useSchemaInName, limitConfig, columns, constraintsList) {
/* istanbul ignore next */ // Ignoring because this won't be fully covered by DB not supporting schemas (SQLite)

@@ -343,5 +343,5 @@ const entityName = useSchemaInName ? toUpperFirst(`${schema}${toSingular(table)}`) : toSingular(table)

async function buildEntity (db, sql, log, table, queries, autoTimestamp, schema, useSchemaInName, ignore, limitConfig, schemaList) {
function buildEntity (db, sql, log, table, queries, autoTimestamp, schema, useSchemaInName, ignore, limitConfig, schemaList, columns, constraintsList) {
// Compute the columns
const columns = (await queries.listColumns(db, sql, table, schema)).filter((c) => !ignore[c.column_name])
columns = columns.filter((c) => !ignore[c.column_name])
const fields = columns.reduce((acc, column) => {

@@ -373,20 +373,13 @@ acc[column.column_name] = {

// To get enum values in pg
/* istanbul ignore next */
if (column.enum) {
acc[column.column_name].enum = column.enum
}
return acc
}, {})
// To get enum values in pg
/* istanbul ignore next */
if (db.isPg) {
const enums = await queries.listEnumValues(db, sql, table, schema)
for (const enumValue of enums) {
if (!fields[enumValue.column_name].enum) {
fields[enumValue.column_name].enum = [enumValue.enumlabel]
} else {
fields[enumValue.column_name].enum.push(enumValue.enumlabel)
}
}
}
const currentRelations = []
const constraintsList = await queries.listConstraints(db, sql, table, schema)
const primaryKeys = new Set()

@@ -397,6 +390,6 @@

if (db.isSQLite) {
const validTypes = ['integer', 'uuid', 'serial']
const validTypes = ['varchar', 'integer', 'uuid', 'serial']
const pkType = fields[constraint.column_name].sqlType.toLowerCase()
if (!validTypes.includes(pkType)) {
throw new Error(`Invalid Primary Key type. Expected "integer", found "${pkType}"`)
throw new Error(`Invalid Primary Key type: "${pkType}". We support the following: ${validTypes.join(', ')}.`)
}

@@ -403,0 +396,0 @@ }

@@ -49,3 +49,3 @@ 'use strict'

async function connect ({ connectionString, log, onDatabaseLoad, poolSize = 10, ignore = {}, autoTimestamp = true, hooks = {}, schema, limit = {} }) {
async function connect ({ connectionString, log, onDatabaseLoad, poolSize = 10, ignore = {}, autoTimestamp = true, hooks = {}, schema, limit = {}, dbschema }) {
if (typeof autoTimestamp === 'boolean' && autoTimestamp === true) {

@@ -114,5 +114,29 @@ autoTimestamp = defaultAutoTimestampFields

const tablesWithSchema = await queries.listTables(db, sql, schemaList)
if (!dbschema) {
dbschema = await queries.listTables(db, sql, schemaList)
for (const { table, schema } of tablesWithSchema) {
// TODO make this parallel or a single query
for (const wrap of dbschema) {
const { table, schema } = wrap
const columns = await queries.listColumns(db, sql, table, schema)
wrap.constraints = await queries.listConstraints(db, sql, table, schema)
wrap.columns = columns
// To get enum values in pg
/* istanbul ignore next */
if (db.isPg) {
const enums = await queries.listEnumValues(db, sql, table, schema)
for (const enumValue of enums) {
const column = columns.find(column => column.column_name === enumValue.column_name)
if (!column.enum) {
column.enum = [enumValue.enumlabel]
} else {
column.enum.push(enumValue.enumlabel)
}
}
}
}
}
for (const { table, schema, columns, constraints } of dbschema) {
// The following line is a safety net when developing this module,

@@ -127,3 +151,3 @@ // it should never happen.

}
const entity = await buildEntity(db, sql, log, table, queries, autoTimestamp, schema, useSchema, ignore[table] || {}, limit, schemaList)
const entity = buildEntity(db, sql, log, table, queries, autoTimestamp, schema, useSchema, ignore[table] || {}, limit, schemaList, columns, constraints)
// Check for primary key of all entities

@@ -143,2 +167,10 @@ if (entity.primaryKeys.size === 0) {

}
return {
db,
sql,
entities,
addEntityHooks,
dbschema
}
} catch (err) /* istanbul ignore next */ {

@@ -149,9 +181,2 @@ db.dispose()

return {
db,
sql,
entities,
addEntityHooks
}
function addEntityHooks (entityName, hooks) {

@@ -158,0 +183,0 @@ const entity = entities[entityName]

{
"name": "@platformatic/sql-mapper",
"version": "0.22.0",
"version": "0.23.0",
"description": "A data mapper utility for SQL databases",

@@ -5,0 +5,0 @@ "main": "mapper.js",

@@ -349,23 +349,28 @@ 'use strict'

test('[SQLite] throws if PK is not INTEGER', { skip: !isSQLite }, async ({ fail, equal, teardown, rejects }) => {
test('[SQLite] allows to have VARCHAR PK', { skip: !isSQLite }, async ({ same, teardown }) => {
async function onDatabaseLoad (db, sql) {
await clear(db, sql)
teardown(() => db.dispose())
await db.query(sql`CREATE TABLE pages (
id int PRIMARY KEY,
title varchar(255) NOT NULL,
content text NOT NULL
id varchar(255) PRIMARY KEY,
title varchar(255) NOT NULL
);`)
}
try {
await connect({
connectionString: connInfo.connectionString,
log: fakeLogger,
onDatabaseLoad,
ignore: {},
hooks: {}
})
fail()
} catch (err) {
equal(err.message, 'Invalid Primary Key type. Expected "integer", found "int"')
}
const mapper = await connect({
connectionString: connInfo.connectionString,
log: fakeLogger,
onDatabaseLoad,
ignore: {},
hooks: {}
})
const pageEntity = mapper.entities.page
const [newPage] = await pageEntity.insert({
fields: ['id', 'title'],
inputs: [{ id: 'varchar_id', title: '13th page with explicit id equal to 13' }]
})
same(newPage, {
id: 'varchar_id',
title: '13th page with explicit id equal to 13'
})
})

@@ -372,0 +377,0 @@

@@ -5,3 +5,3 @@ 'use strict'

const { clear, connInfo, isMysql8 } = require('./helper')
const { clear, connInfo, isMysql8, isSQLite } = require('./helper')
const { connect } = require('..')

@@ -40,3 +40,3 @@ const fakeLogger = {

equal(pageEntity.pluralName, 'pages')
if (isMysql8) {
if (isMysql8 || isSQLite) {
same(pageEntity.primaryKeys, new Set(['name']))

@@ -43,0 +43,0 @@ equal(pageEntity.camelCasedFields.name.primaryKey, true)

@@ -64,3 +64,3 @@ const { test } = require('tap')

test('find enums correctly using schemas', { skip: isSQLite }, async ({ pass, teardown, equal }) => {
test('find enums correctly using schemas', { skip: isSQLite }, async ({ pass, teardown, equal, match }) => {
async function onDatabaseLoad (db, sql) {

@@ -106,2 +106,27 @@ await clear(db, sql)

equal(pageEntity.pluralName, 'test1Pages')
match(mapper.dbschema, [
{
schema: 'test1',
table: 'pages',
constraints: [
{
constraint_type: isMysql8 ? 'UNIQUE' : 'PRIMARY KEY'
}
],
columns: [
{
column_name: 'id',
is_nullable: 'NO'
},
{
column_name: 'title',
is_nullable: 'NO'
},
{
column_name: 'type',
is_nullable: 'YES'
}
]
}
])
pass()

@@ -384,1 +409,69 @@ })

})
test('recreate mapper from schema', async ({ pass, teardown, equal, match, fail }) => {
async function onDatabaseLoad (db, sql) {
await clear(db, sql)
teardown(() => db.dispose())
if (isMysql || isMysql8) {
await db.query(sql`
CREATE TABLE IF NOT EXISTS \`pages\` (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL
);`)
} else if (isPg) {
await db.query(sql`
CREATE TABLE IF NOT EXISTS "pages" (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL
);`)
} else if (isSQLite) {
await db.query(sql`
CREATE TABLE IF NOT EXISTS "pages" (
id INTEGER PRIMARY KEY,
title VARCHAR(255) NOT NULL
);`)
} else {
await db.query(sql`CREATE TABLE IF NOT EXISTS "pages" (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
);`)
}
}
const mapper = await connect({
connectionString: connInfo.connectionString,
log: fakeLogger,
onDatabaseLoad,
ignore: {},
hooks: {}
})
const dbschema = mapper.dbschema
const knownQueries = [
'SELECT VERSION()'
]
const mapper2 = await connect({
connectionString: connInfo.connectionString,
log: {
trace (msg) {
if (knownQueries.indexOf(msg.query?.text) < 0) {
console.log(msg)
fail('no trace')
}
},
error (...msg) {
console.log(...msg)
fail('no error')
}
},
dbschema,
ignore: {},
hooks: {}
})
teardown(() => mapper2.db.dispose())
const pageEntity = mapper2.entities.page
equal(pageEntity.name, 'Page')
equal(pageEntity.singularName, 'page')
equal(pageEntity.pluralName, 'pages')
pass()
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc