@platformatic/sql-mapper 3.52.2 → 3.53.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +12 -0
- package/lib/entity.js +16 -2
- package/lib/queries/pg.js +15 -4
- package/lib/vector.js +34 -0
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import * as queriesFactory from './lib/queries/index.js'
|
|
14
14
|
import { setupTelemetry } from './lib/telemetry.js'
|
|
15
15
|
import { areSchemasSupported } from './lib/utils.js'
|
|
16
|
+
import { parseVector } from './lib/vector.js'
|
|
16
17
|
|
|
17
18
|
// Ignore the function as it is only used only for MySQL and PostgreSQL
|
|
18
19
|
/* istanbul ignore next */
|
|
@@ -76,6 +77,16 @@ const defaultAutoTimestampFields = {
|
|
|
76
77
|
updatedAt: 'updated_at'
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
async function registerPostgreSQLExtensionTypes (db) {
|
|
81
|
+
try {
|
|
82
|
+
await db.registerTypeParser('vector', parseVector)
|
|
83
|
+
} catch {}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
await db.registerTypeParser('_vector', value => db.parseArray(value, parseVector))
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
|
|
79
90
|
export async function createConnectionPool ({
|
|
80
91
|
log,
|
|
81
92
|
connectionString,
|
|
@@ -102,6 +113,7 @@ export async function createConnectionPool ({
|
|
|
102
113
|
queueTimeoutMilliseconds,
|
|
103
114
|
acquireLockTimeoutMilliseconds
|
|
104
115
|
)
|
|
116
|
+
await registerPostgreSQLExtensionTypes(db)
|
|
105
117
|
sql = createConnectionPoolPg.sql
|
|
106
118
|
db.isPg = true
|
|
107
119
|
} else if (connectionString.indexOf('mysql') === 0) {
|
package/lib/entity.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from './errors.js'
|
|
15
15
|
import { wrapDB } from './telemetry.js'
|
|
16
16
|
import { sanitizeLimit, tableName, toLowerFirst, toSingular, toUpperFirst } from './utils.js'
|
|
17
|
+
import { isVectorType, parseVector, serializeVector } from './vector.js'
|
|
17
18
|
|
|
18
19
|
function createMapper (
|
|
19
20
|
defaultDb,
|
|
@@ -75,7 +76,7 @@ function createMapper (
|
|
|
75
76
|
function fixInput (input) {
|
|
76
77
|
const newInput = {}
|
|
77
78
|
for (const key of Object.keys(input)) {
|
|
78
|
-
|
|
79
|
+
let value = input[key]
|
|
79
80
|
let newKey = inputToFieldMap[key]
|
|
80
81
|
if (newKey === undefined) {
|
|
81
82
|
if (fields[key] !== undefined) {
|
|
@@ -84,6 +85,11 @@ function createMapper (
|
|
|
84
85
|
throw new UnknownFieldError(key)
|
|
85
86
|
}
|
|
86
87
|
}
|
|
88
|
+
|
|
89
|
+
if (isVectorType(fields[newKey].sqlType)) {
|
|
90
|
+
value = serializeVector(value)
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
newInput[newKey] = value
|
|
88
94
|
}
|
|
89
95
|
return newInput
|
|
@@ -100,6 +106,9 @@ function createMapper (
|
|
|
100
106
|
if (primaryKeys.has(key) && value !== null && value !== undefined) {
|
|
101
107
|
value = value.toString()
|
|
102
108
|
}
|
|
109
|
+
if (newKey && isVectorType(fields[key].sqlType)) {
|
|
110
|
+
value = parseVector(value)
|
|
111
|
+
}
|
|
103
112
|
newOutput[newKey] = value
|
|
104
113
|
}
|
|
105
114
|
return newOutput
|
|
@@ -327,6 +336,10 @@ function createMapper (
|
|
|
327
336
|
}
|
|
328
337
|
|
|
329
338
|
function computeCriteriaValue (fieldWrap, value) {
|
|
339
|
+
if (isVectorType(fieldWrap.sqlType)) {
|
|
340
|
+
return sql`${serializeVector(value)}`
|
|
341
|
+
}
|
|
342
|
+
|
|
330
343
|
if (Array.isArray(value)) {
|
|
331
344
|
return sql`(${sql.join(
|
|
332
345
|
value.map(v => computeCriteriaValue(fieldWrap, v)),
|
|
@@ -487,7 +500,8 @@ export function buildEntity (
|
|
|
487
500
|
acc[column.column_name] = {
|
|
488
501
|
sqlType: column.udt_name,
|
|
489
502
|
isNullable: column.is_nullable === 'YES',
|
|
490
|
-
isArray: column.isArray
|
|
503
|
+
isArray: column.isArray,
|
|
504
|
+
vectorDimensions: column.vectorDimensions
|
|
491
505
|
}
|
|
492
506
|
|
|
493
507
|
// To get enum values in mysql and mariadb
|
package/lib/queries/pg.js
CHANGED
|
@@ -46,10 +46,16 @@ export async function listColumns (db, sql, table, schema) {
|
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
48
|
const res = await db.query(sql`
|
|
49
|
-
SELECT column_name, udt_name, is_nullable, is_generated, data_type
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
SELECT c.column_name, c.udt_name, c.is_nullable, c.is_generated, c.data_type,
|
|
50
|
+
pg_catalog.format_type(a.atttypid, a.atttypmod) AS formatted_type
|
|
51
|
+
FROM information_schema.columns c
|
|
52
|
+
JOIN pg_catalog.pg_class cls ON cls.relname = c.table_name
|
|
53
|
+
JOIN pg_catalog.pg_namespace ns ON ns.oid = cls.relnamespace AND ns.nspname = c.table_schema
|
|
54
|
+
JOIN pg_catalog.pg_attribute a ON a.attrelid = cls.oid AND a.attname = c.column_name
|
|
55
|
+
WHERE c.table_name = ${table}
|
|
56
|
+
AND c.table_schema = ${schema}
|
|
57
|
+
AND a.attnum > 0
|
|
58
|
+
AND NOT a.attisdropped
|
|
53
59
|
`)
|
|
54
60
|
|
|
55
61
|
for (const col of res) {
|
|
@@ -59,6 +65,11 @@ export async function listColumns (db, sql, table, schema) {
|
|
|
59
65
|
} else {
|
|
60
66
|
col.isArray = false
|
|
61
67
|
}
|
|
68
|
+
|
|
69
|
+
const match = col.formatted_type?.match(/^vector\((\d+)\)$/)
|
|
70
|
+
if (match) {
|
|
71
|
+
col.vectorDimensions = Number(match[1])
|
|
72
|
+
}
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
return res
|
package/lib/vector.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function isVectorType (sqlType) {
|
|
2
|
+
return sqlType === 'vector'
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function serializeVector (value) {
|
|
6
|
+
if (Array.isArray(value)) {
|
|
7
|
+
return JSON.stringify(value)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (ArrayBuffer.isView(value)) {
|
|
11
|
+
return JSON.stringify(Array.from(value))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return value
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function parseVector (value) {
|
|
18
|
+
if (value === null || value === undefined || Array.isArray(value)) {
|
|
19
|
+
return value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof value !== 'string') {
|
|
23
|
+
return value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(value)
|
|
28
|
+
if (Array.isArray(parsed)) {
|
|
29
|
+
return parsed
|
|
30
|
+
}
|
|
31
|
+
} catch {}
|
|
32
|
+
|
|
33
|
+
return value
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/sql-mapper",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.53.0-alpha.0",
|
|
4
4
|
"description": "A data mapper utility for SQL databases",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"camelcase": "^6.3.0",
|
|
36
36
|
"fastify-plugin": "^5.0.0",
|
|
37
37
|
"inflected": "^2.1.0",
|
|
38
|
-
"@platformatic/foundation": "3.
|
|
39
|
-
"@platformatic/telemetry": "3.
|
|
38
|
+
"@platformatic/foundation": "3.53.0-alpha.0",
|
|
39
|
+
"@platformatic/telemetry": "3.53.0-alpha.0"
|
|
40
40
|
},
|
|
41
41
|
"tsd": {
|
|
42
42
|
"directory": "test/types"
|