@mastra/mssql 1.1.1 → 1.2.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/CHANGELOG.md +17 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/reference-storage-mssql.md +3 -3
- package/dist/index.cjs +85 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +86 -7
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +12 -0
- package/dist/storage/db/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +1 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @mastra/mssql
|
|
2
2
|
|
|
3
|
+
## 1.2.0-alpha.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added `requestContext` column to the spans table. Request context data from tracing is now persisted alongside other span data. ([#14020](https://github.com/mastra-ai/mastra/pull/14020))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Added resilient column handling to insert and update operations. Unknown columns in records are now silently dropped instead of causing SQL errors, ensuring forward compatibility when newer domain packages add fields that haven't been migrated yet. ([#14021](https://github.com/mastra-ai/mastra/pull/14021))
|
|
12
|
+
|
|
13
|
+
For example, calling `db.insert({ tableName, record: { id: '1', title: 'Hello', futureField: 'value' } })` will silently ignore `futureField` if it doesn't exist in the database table, rather than throwing. The same applies to `update` — unknown fields in the data payload are dropped before building the SQL statement.
|
|
14
|
+
|
|
15
|
+
- Improved semantic recall performance for large message histories. Semantic recall no longer loads entire threads when only the recalled messages are needed, eliminating delays that previously scaled with total message count. (Fixes #11702) ([#14022](https://github.com/mastra-ai/mastra/pull/14022))
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`4f71b43`](https://github.com/mastra-ai/mastra/commit/4f71b436a4a6b8839842d8da47b57b84509af56c), [`a070277`](https://github.com/mastra-ai/mastra/commit/a07027766ce195ba74d0783116d894cbab25d44c), [`b628b91`](https://github.com/mastra-ai/mastra/commit/b628b9128b372c0f54214d902b07279f03443900), [`332c014`](https://github.com/mastra-ai/mastra/commit/332c014e076b81edf7fe45b58205882726415e90), [`6b63153`](https://github.com/mastra-ai/mastra/commit/6b63153878ea841c0f4ce632ba66bb33e57e9c1b), [`4246e34`](https://github.com/mastra-ai/mastra/commit/4246e34cec9c26636d0965942268e6d07c346671), [`b8837ee`](https://github.com/mastra-ai/mastra/commit/b8837ee77e2e84197609762bfabd8b3da326d30c), [`5d950f7`](https://github.com/mastra-ai/mastra/commit/5d950f7bf426a215a1808f0abef7de5c8336ba1c), [`28c85b1`](https://github.com/mastra-ai/mastra/commit/28c85b184fc32b40f7f160483c982da6d388ecbd), [`e9a08fb`](https://github.com/mastra-ai/mastra/commit/e9a08fbef1ada7e50e961e2f54f55e8c10b4a45c), [`631ffd8`](https://github.com/mastra-ai/mastra/commit/631ffd82fed108648b448b28e6a90e38c5f53bf5), [`aae2295`](https://github.com/mastra-ai/mastra/commit/aae2295838a2d329ad6640829e87934790ffe5b8), [`aa61f29`](https://github.com/mastra-ai/mastra/commit/aa61f29ff8095ce46a4ae16e46c4d8c79b2b685b), [`7ff3714`](https://github.com/mastra-ai/mastra/commit/7ff37148515439bb3be009a60e02c3e363299760), [`41d79a1`](https://github.com/mastra-ai/mastra/commit/41d79a14bd8cb6de1e2565fd0a04786bae2f211b), [`e673376`](https://github.com/mastra-ai/mastra/commit/e6733763ad1321aa7e5ae15096b9c2104f93b1f3), [`b2204c9`](https://github.com/mastra-ai/mastra/commit/b2204c98a42848bbfb6f0440f005dc2b6354f1cd), [`a1bf1e3`](https://github.com/mastra-ai/mastra/commit/a1bf1e385ed4c0ef6f11b56c5887442970d127f2), [`b6f647a`](https://github.com/mastra-ai/mastra/commit/b6f647ae2388e091f366581595feb957e37d5b40), [`0c57b8b`](https://github.com/mastra-ai/mastra/commit/0c57b8b0a69a97b5a4ae3f79be6c610f29f3cf7b), [`b081f27`](https://github.com/mastra-ai/mastra/commit/b081f272cf411716e1d6bd72ceac4bcee2657b19), [`0c09eac`](https://github.com/mastra-ai/mastra/commit/0c09eacb1926f64cfdc9ae5c6d63385cf8c9f72c), [`6b9b93d`](https://github.com/mastra-ai/mastra/commit/6b9b93d6f459d1ba6e36f163abf62a085ddb3d64), [`31b6067`](https://github.com/mastra-ai/mastra/commit/31b6067d0cc3ab10e1b29c36147f3b5266bc714a), [`797ac42`](https://github.com/mastra-ai/mastra/commit/797ac4276de231ad2d694d9aeca75980f6cd0419), [`0bc289e`](https://github.com/mastra-ai/mastra/commit/0bc289e2d476bf46c5b91c21969e8d0c6864691c), [`9b75a06`](https://github.com/mastra-ai/mastra/commit/9b75a06e53ebb0b950ba7c1e83a0142047185f46), [`4c3a1b1`](https://github.com/mastra-ai/mastra/commit/4c3a1b122ea083e003d71092f30f3b31680b01c0), [`85cc3b3`](https://github.com/mastra-ai/mastra/commit/85cc3b3b6f32ae4b083c26498f50d5b250ba944b), [`97ea28c`](https://github.com/mastra-ai/mastra/commit/97ea28c746e9e4147d56047bbb1c4a92417a3fec), [`d567299`](https://github.com/mastra-ai/mastra/commit/d567299cf81e02bd9d5221d4bc05967d6c224161), [`716ffe6`](https://github.com/mastra-ai/mastra/commit/716ffe68bed81f7c2690bc8581b9e140f7bf1c3d), [`8296332`](https://github.com/mastra-ai/mastra/commit/8296332de21c16e3dfc3d0b2d615720a6dc88f2f), [`4df2116`](https://github.com/mastra-ai/mastra/commit/4df211619dd922c047d396ca41cd7027c8c4c8e7), [`2219c1a`](https://github.com/mastra-ai/mastra/commit/2219c1acbd21da116da877f0036ffb985a9dd5a3), [`17c4145`](https://github.com/mastra-ai/mastra/commit/17c4145166099354545582335b5252bdfdfd908b)]:
|
|
18
|
+
- @mastra/core@1.11.0-alpha.0
|
|
19
|
+
|
|
3
20
|
## 1.1.1
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -41,9 +41,9 @@ const storage = new MSSQLStore({
|
|
|
41
41
|
|
|
42
42
|
## Parameters
|
|
43
43
|
|
|
44
|
-
**connectionString
|
|
44
|
+
**connectionString** (`string`): MSSQL connection string (e.g., Server=localhost,1433;Database=mydb;User Id=sa;Password=password;Encrypt=true;TrustServerCertificate=true)
|
|
45
45
|
|
|
46
|
-
**schemaName
|
|
46
|
+
**schemaName** (`string`): The name of the schema you want the storage to use. Will use the default schema if not provided.
|
|
47
47
|
|
|
48
48
|
## Constructor Examples
|
|
49
49
|
|
|
@@ -138,7 +138,7 @@ const memoryStore = await storage.getStore('memory')
|
|
|
138
138
|
const thread = await memoryStore?.getThreadById({ threadId: '...' })
|
|
139
139
|
```
|
|
140
140
|
|
|
141
|
-
> **Warning:** If `init()`
|
|
141
|
+
> **Warning:** If `init()` isn't called, tables won't be created and storage operations will fail silently or throw errors.
|
|
142
142
|
|
|
143
143
|
### Direct Database and Pool Access
|
|
144
144
|
|
package/dist/index.cjs
CHANGED
|
@@ -58,6 +58,8 @@ var MssqlDB = class extends base.MastraBase {
|
|
|
58
58
|
skipDefaultIndexes;
|
|
59
59
|
setupSchemaPromise = null;
|
|
60
60
|
schemaSetupComplete = void 0;
|
|
61
|
+
/** Cache of actual table columns: tableName -> Set<columnName> */
|
|
62
|
+
tableColumnsCache = /* @__PURE__ */ new Map();
|
|
61
63
|
/**
|
|
62
64
|
* Columns that participate in composite indexes need smaller sizes (NVARCHAR(100)).
|
|
63
65
|
* MSSQL has a 900-byte index key limit, so composite indexes with NVARCHAR(400) columns fail.
|
|
@@ -142,6 +144,41 @@ var MssqlDB = class extends base.MastraBase {
|
|
|
142
144
|
this.schemaName = schemaName;
|
|
143
145
|
this.skipDefaultIndexes = skipDefaultIndexes;
|
|
144
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Gets the set of column names that actually exist in the database table.
|
|
149
|
+
* Results are cached; the cache is invalidated when alterTable() adds new columns.
|
|
150
|
+
*/
|
|
151
|
+
async getTableColumns(tableName) {
|
|
152
|
+
const cached = this.tableColumnsCache.get(tableName);
|
|
153
|
+
if (cached) return cached;
|
|
154
|
+
const schema = this.schemaName || "dbo";
|
|
155
|
+
const request = this.pool.request();
|
|
156
|
+
request.input("schema", schema);
|
|
157
|
+
request.input("tableName", tableName);
|
|
158
|
+
const result = await request.query(
|
|
159
|
+
`SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = @tableName`
|
|
160
|
+
);
|
|
161
|
+
const columns = new Set((result.recordset || []).map((r) => r.COLUMN_NAME));
|
|
162
|
+
if (columns.size > 0) {
|
|
163
|
+
this.tableColumnsCache.set(tableName, columns);
|
|
164
|
+
}
|
|
165
|
+
return columns;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Filters a record to only include columns that exist in the actual database table.
|
|
169
|
+
* Unknown columns are silently dropped to ensure forward compatibility.
|
|
170
|
+
*/
|
|
171
|
+
async filterRecordToKnownColumns(tableName, record) {
|
|
172
|
+
const knownColumns = await this.getTableColumns(tableName);
|
|
173
|
+
if (knownColumns.size === 0) return record;
|
|
174
|
+
const filtered = {};
|
|
175
|
+
for (const [key, value] of Object.entries(record)) {
|
|
176
|
+
if (knownColumns.has(key)) {
|
|
177
|
+
filtered[key] = value;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return filtered;
|
|
181
|
+
}
|
|
145
182
|
async hasColumn(table, column) {
|
|
146
183
|
const schema = this.schemaName || "dbo";
|
|
147
184
|
const request = this.pool.request();
|
|
@@ -197,13 +234,15 @@ var MssqlDB = class extends base.MastraBase {
|
|
|
197
234
|
transaction
|
|
198
235
|
}) {
|
|
199
236
|
try {
|
|
200
|
-
const
|
|
237
|
+
const filteredRecord = await this.filterRecordToKnownColumns(tableName, record);
|
|
238
|
+
const columns = Object.keys(filteredRecord);
|
|
239
|
+
if (columns.length === 0) return;
|
|
201
240
|
const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
202
241
|
const paramNames = columns.map((_, i) => `@param${i}`);
|
|
203
242
|
const insertSql = `INSERT INTO ${getTableName({ indexName: tableName, schemaName: getSchemaName(this.schemaName) })} (${parsedColumns.map((c) => `[${c}]`).join(", ")}) VALUES (${paramNames.join(", ")})`;
|
|
204
243
|
const request = transaction ? transaction.request() : this.pool.request();
|
|
205
244
|
columns.forEach((col, i) => {
|
|
206
|
-
const value =
|
|
245
|
+
const value = filteredRecord[col];
|
|
207
246
|
const preparedValue = this.prepareValue(value, col, tableName);
|
|
208
247
|
if (preparedValue instanceof Date) {
|
|
209
248
|
request.input(`param${i}`, sql__default.default.DateTime2, preparedValue);
|
|
@@ -394,6 +433,8 @@ Note: This migration may take some time for large tables.
|
|
|
394
433
|
},
|
|
395
434
|
error$1
|
|
396
435
|
);
|
|
436
|
+
} finally {
|
|
437
|
+
this.tableColumnsCache.delete(tableName);
|
|
397
438
|
}
|
|
398
439
|
}
|
|
399
440
|
/**
|
|
@@ -621,6 +662,8 @@ Note: This migration may take some time for large tables.
|
|
|
621
662
|
},
|
|
622
663
|
error$1
|
|
623
664
|
);
|
|
665
|
+
} finally {
|
|
666
|
+
this.tableColumnsCache.delete(tableName);
|
|
624
667
|
}
|
|
625
668
|
}
|
|
626
669
|
async load({ tableName, keys }) {
|
|
@@ -704,6 +747,8 @@ Note: This migration may take some time for large tables.
|
|
|
704
747
|
},
|
|
705
748
|
error$1
|
|
706
749
|
);
|
|
750
|
+
} finally {
|
|
751
|
+
this.tableColumnsCache.delete(tableName);
|
|
707
752
|
}
|
|
708
753
|
}
|
|
709
754
|
/**
|
|
@@ -795,10 +840,12 @@ Note: This migration may take some time for large tables.
|
|
|
795
840
|
text: "Cannot update without keys to identify records"
|
|
796
841
|
});
|
|
797
842
|
}
|
|
843
|
+
const filteredData = await this.filterRecordToKnownColumns(tableName, data);
|
|
844
|
+
if (Object.keys(filteredData).length === 0) return;
|
|
798
845
|
const setClauses = [];
|
|
799
846
|
const request = transaction ? transaction.request() : this.pool.request();
|
|
800
847
|
let paramIndex = 0;
|
|
801
|
-
Object.entries(
|
|
848
|
+
Object.entries(filteredData).forEach(([key, value]) => {
|
|
802
849
|
const parsedKey = utils.parseSqlIdentifier(key, "column name");
|
|
803
850
|
const paramName = `set${paramIndex++}`;
|
|
804
851
|
setClauses.push(`[${parsedKey}] = @${paramName}`);
|
|
@@ -1734,6 +1781,18 @@ var MemoryMSSQL = class _MemoryMSSQL extends storage.MemoryStorage {
|
|
|
1734
1781
|
);
|
|
1735
1782
|
}
|
|
1736
1783
|
}
|
|
1784
|
+
_sortMessages(messages, field, direction) {
|
|
1785
|
+
const mult = direction === "ASC" ? 1 : -1;
|
|
1786
|
+
return messages.sort((a, b) => {
|
|
1787
|
+
const aVal = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
1788
|
+
const bVal = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
1789
|
+
if (aVal == null || bVal == null) {
|
|
1790
|
+
return aVal == null && bVal == null ? a.id.localeCompare(b.id) : aVal == null ? 1 : -1;
|
|
1791
|
+
}
|
|
1792
|
+
const diff = (typeof aVal === "number" && typeof bVal === "number" ? aVal - bVal : String(aVal).localeCompare(String(bVal))) * mult;
|
|
1793
|
+
return diff !== 0 ? diff : a.id.localeCompare(b.id);
|
|
1794
|
+
});
|
|
1795
|
+
}
|
|
1737
1796
|
async _getIncludedMessages({ include }) {
|
|
1738
1797
|
if (!include || include.length === 0) return null;
|
|
1739
1798
|
const unionQueries = [];
|
|
@@ -1895,6 +1954,20 @@ var MemoryMSSQL = class _MemoryMSSQL extends storage.MemoryStorage {
|
|
|
1895
1954
|
const bindWhereParams = (req) => {
|
|
1896
1955
|
Object.entries(whereParams).forEach(([paramName, paramValue]) => req.input(paramName, paramValue));
|
|
1897
1956
|
};
|
|
1957
|
+
if (perPage === 0 && (!include || include.length === 0)) {
|
|
1958
|
+
return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
|
|
1959
|
+
}
|
|
1960
|
+
if (perPage === 0 && include && include.length > 0) {
|
|
1961
|
+
const includeMessages = await this._getIncludedMessages({ include });
|
|
1962
|
+
const messages2 = this._parseAndFormatMessages(includeMessages ?? [], "v2");
|
|
1963
|
+
return {
|
|
1964
|
+
messages: this._sortMessages(messages2, field, direction),
|
|
1965
|
+
total: 0,
|
|
1966
|
+
page,
|
|
1967
|
+
perPage: perPageForResponse,
|
|
1968
|
+
hasMore: false
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1898
1971
|
const countRequest = this.pool.request();
|
|
1899
1972
|
bindWhereParams(countRequest);
|
|
1900
1973
|
const countResult = await countRequest.query(`SELECT COUNT(*) as total FROM ${tableName}${actualWhereClause}`);
|
|
@@ -2360,6 +2433,11 @@ var ObservabilityMSSQL = class _ObservabilityMSSQL extends storage.Observability
|
|
|
2360
2433
|
this.needsConnect = false;
|
|
2361
2434
|
}
|
|
2362
2435
|
await this.db.createTable({ tableName: storage.TABLE_SPANS, schema: storage.SPAN_SCHEMA });
|
|
2436
|
+
await this.db.alterTable({
|
|
2437
|
+
tableName: storage.TABLE_SPANS,
|
|
2438
|
+
schema: storage.SPAN_SCHEMA,
|
|
2439
|
+
ifNotExists: ["requestContext"]
|
|
2440
|
+
});
|
|
2363
2441
|
await this.createDefaultIndexes();
|
|
2364
2442
|
await this.createCustomIndexes();
|
|
2365
2443
|
}
|
|
@@ -2672,7 +2750,8 @@ var ObservabilityMSSQL = class _ObservabilityMSSQL extends storage.Observability
|
|
|
2672
2750
|
}
|
|
2673
2751
|
async listTraces(args) {
|
|
2674
2752
|
const { filters, pagination, orderBy } = storage.listTracesArgsSchema.parse(args);
|
|
2675
|
-
const
|
|
2753
|
+
const page = pagination?.page ?? 0;
|
|
2754
|
+
const perPage = pagination?.perPage ?? 10;
|
|
2676
2755
|
const tableName = getTableName2({
|
|
2677
2756
|
indexName: storage.TABLE_SPANS,
|
|
2678
2757
|
schemaName: getSchemaName2(this.schema)
|
|
@@ -2837,8 +2916,8 @@ var ObservabilityMSSQL = class _ObservabilityMSSQL extends storage.Observability
|
|
|
2837
2916
|
}
|
|
2838
2917
|
}
|
|
2839
2918
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2840
|
-
const sortField = orderBy
|
|
2841
|
-
const sortDirection = orderBy
|
|
2919
|
+
const sortField = orderBy?.field ?? "startedAt";
|
|
2920
|
+
const sortDirection = orderBy?.direction ?? "DESC";
|
|
2842
2921
|
const countRequest = this.pool.request();
|
|
2843
2922
|
Object.entries(params).forEach(([key, value]) => {
|
|
2844
2923
|
countRequest.input(key, value);
|