@memberjunction/sqlserver-dataprovider 2.43.0 → 2.45.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/README.md +261 -79
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -17,6 +17,10 @@ The `@memberjunction/sqlserver-dataprovider` package implements MemberJunction's
|
|
|
17
17
|
- **Entity Relationships**: Handle complex entity relationships automatically
|
|
18
18
|
- **User/Role Management**: Integrated with MemberJunction's security model
|
|
19
19
|
- **Type-Safe Operations**: Fully TypeScript compatible
|
|
20
|
+
- **AI Integration**: Support for AI-powered features through entity actions
|
|
21
|
+
- **Duplicate Detection**: Built-in support for duplicate record detection
|
|
22
|
+
- **Audit Logging**: Comprehensive audit trail capabilities
|
|
23
|
+
- **Row-Level Security**: Enforce data access controls at the database level
|
|
20
24
|
|
|
21
25
|
## Installation
|
|
22
26
|
|
|
@@ -30,8 +34,13 @@ This package relies on the following key dependencies:
|
|
|
30
34
|
- `@memberjunction/core`: Core MemberJunction functionality
|
|
31
35
|
- `@memberjunction/core-entities`: Entity definitions
|
|
32
36
|
- `@memberjunction/global`: Shared utilities and constants
|
|
33
|
-
-
|
|
34
|
-
-
|
|
37
|
+
- `@memberjunction/actions`: Action execution framework
|
|
38
|
+
- `@memberjunction/ai`: AI integration capabilities
|
|
39
|
+
- `@memberjunction/ai-vector-dupe`: Duplicate detection using AI vectors
|
|
40
|
+
- `@memberjunction/aiengine`: AI engine integration
|
|
41
|
+
- `@memberjunction/queue`: Queue management for async operations
|
|
42
|
+
- `mssql`: SQL Server client for Node.js (v11+)
|
|
43
|
+
- `typeorm`: ORM for database operations (v0.3+)
|
|
35
44
|
|
|
36
45
|
## Usage
|
|
37
46
|
|
|
@@ -74,44 +83,50 @@ await dataProvider.initialize();
|
|
|
74
83
|
|
|
75
84
|
```typescript
|
|
76
85
|
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
77
|
-
import {
|
|
86
|
+
import { Metadata, CompositeKey, UserInfo } from '@memberjunction/core';
|
|
87
|
+
import { UserEntity } from '@memberjunction/core-entities';
|
|
78
88
|
|
|
79
89
|
// Setup data provider
|
|
80
90
|
const dataProvider = new SQLServerDataProvider(/* config */);
|
|
81
91
|
await dataProvider.initialize();
|
|
82
92
|
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
// Get entity metadata
|
|
94
|
+
const md = new Metadata();
|
|
95
|
+
const userEntity = md.EntityByName('User');
|
|
96
|
+
|
|
97
|
+
// Load an entity by ID
|
|
98
|
+
const userKey = new CompositeKey([{ FieldName: 'ID', Value: 1 }]);
|
|
99
|
+
const userResult = await dataProvider.Get(userEntity, userKey);
|
|
100
|
+
|
|
101
|
+
if (userResult.Success) {
|
|
102
|
+
const user = userResult.Entity;
|
|
87
103
|
console.log(`Loaded user: ${user.FirstName} ${user.LastName}`);
|
|
88
104
|
|
|
89
105
|
// Update the entity
|
|
90
106
|
user.Email = 'new.email@example.com';
|
|
91
|
-
const saveResult = await dataProvider.
|
|
107
|
+
const saveResult = await dataProvider.Save(user, contextUser);
|
|
92
108
|
|
|
93
|
-
if (saveResult.
|
|
94
|
-
console.log(`User updated successfully, ID: ${saveResult.
|
|
109
|
+
if (saveResult.Success) {
|
|
110
|
+
console.log(`User updated successfully, ID: ${saveResult.Entity.ID}`);
|
|
95
111
|
}
|
|
96
112
|
}
|
|
97
113
|
|
|
98
114
|
// Create a new entity
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (createResult.success) {
|
|
109
|
-
console.log(`New user created with ID: ${createResult.entity.ID}`);
|
|
115
|
+
const newUserEntity = await md.GetEntityObject<UserEntity>('User');
|
|
116
|
+
newUserEntity.FirstName = 'John';
|
|
117
|
+
newUserEntity.LastName = 'Doe';
|
|
118
|
+
newUserEntity.Email = 'john.doe@example.com';
|
|
119
|
+
// set other required fields...
|
|
120
|
+
|
|
121
|
+
const createResult = await dataProvider.Save(newUserEntity, contextUser);
|
|
122
|
+
if (createResult.Success) {
|
|
123
|
+
console.log(`New user created with ID: ${createResult.Entity.ID}`);
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
// Delete an entity
|
|
113
|
-
const
|
|
114
|
-
|
|
127
|
+
const deleteKey = new CompositeKey([{ FieldName: 'ID', Value: 5 }]);
|
|
128
|
+
const deleteResult = await dataProvider.Delete(userEntity, deleteKey, contextUser);
|
|
129
|
+
if (deleteResult.Success) {
|
|
115
130
|
console.log('User deleted successfully');
|
|
116
131
|
}
|
|
117
132
|
```
|
|
@@ -120,54 +135,59 @@ if (deleteResult.success) {
|
|
|
120
135
|
|
|
121
136
|
```typescript
|
|
122
137
|
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
123
|
-
import {
|
|
138
|
+
import { SQLServerTransactionGroup } from '@memberjunction/sqlserver-dataprovider';
|
|
139
|
+
import { Metadata } from '@memberjunction/core';
|
|
124
140
|
|
|
125
141
|
// Setup data provider
|
|
126
142
|
const dataProvider = new SQLServerDataProvider(/* config */);
|
|
127
143
|
await dataProvider.initialize();
|
|
128
144
|
|
|
129
145
|
// Create a transaction group
|
|
130
|
-
|
|
131
|
-
constructor() {
|
|
132
|
-
super('CreateOrderWithItems');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
146
|
+
const transaction = new SQLServerTransactionGroup('CreateOrderWithItems');
|
|
135
147
|
|
|
136
|
-
|
|
148
|
+
// Get entity objects
|
|
149
|
+
const md = new Metadata();
|
|
150
|
+
const orderEntity = await md.GetEntityObject('Order');
|
|
151
|
+
const orderItemEntity1 = await md.GetEntityObject('Order Item');
|
|
152
|
+
const orderItemEntity2 = await md.GetEntityObject('Order Item');
|
|
137
153
|
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
OrderDate: new Date(),
|
|
143
|
-
Status: 'New'
|
|
144
|
-
});
|
|
154
|
+
// Set up the order
|
|
155
|
+
orderEntity.CustomerID = 123;
|
|
156
|
+
orderEntity.OrderDate = new Date();
|
|
157
|
+
orderEntity.Status = 'New';
|
|
145
158
|
|
|
146
|
-
//
|
|
147
|
-
transaction.
|
|
148
|
-
ID: 0,
|
|
149
|
-
OrderID: '@Order.1', // Reference to the first Order in this transaction
|
|
150
|
-
ProductID: 456,
|
|
151
|
-
Quantity: 2,
|
|
152
|
-
Price: 29.99
|
|
153
|
-
});
|
|
159
|
+
// Add to transaction - this will get ID after save
|
|
160
|
+
await transaction.AddTransaction(orderEntity);
|
|
154
161
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
+
// Set up order items with references to the order
|
|
163
|
+
orderItemEntity1.OrderID = '@Order.1'; // Reference to the first Order in this transaction
|
|
164
|
+
orderItemEntity1.ProductID = 456;
|
|
165
|
+
orderItemEntity1.Quantity = 2;
|
|
166
|
+
orderItemEntity1.Price = 29.99;
|
|
167
|
+
|
|
168
|
+
orderItemEntity2.OrderID = '@Order.1'; // Same order reference
|
|
169
|
+
orderItemEntity2.ProductID = 789;
|
|
170
|
+
orderItemEntity2.Quantity = 1;
|
|
171
|
+
orderItemEntity2.Price = 49.99;
|
|
172
|
+
|
|
173
|
+
// Add items to transaction
|
|
174
|
+
await transaction.AddTransaction(orderItemEntity1);
|
|
175
|
+
await transaction.AddTransaction(orderItemEntity2);
|
|
162
176
|
|
|
163
177
|
// Execute the transaction group
|
|
164
|
-
const
|
|
178
|
+
const results = await transaction.Submit();
|
|
165
179
|
|
|
166
|
-
|
|
180
|
+
// Check results
|
|
181
|
+
const success = results.every(r => r.Success);
|
|
182
|
+
if (success) {
|
|
167
183
|
console.log('Transaction completed successfully');
|
|
168
|
-
|
|
184
|
+
const orderResult = results.find(r => r.Entity.EntityInfo.Name === 'Order');
|
|
185
|
+
console.log('Order ID:', orderResult?.Entity.ID);
|
|
169
186
|
} else {
|
|
170
|
-
console.error('Transaction failed
|
|
187
|
+
console.error('Transaction failed');
|
|
188
|
+
results.filter(r => !r.Success).forEach(r => {
|
|
189
|
+
console.error(`Failed: ${r.Entity.EntityInfo.Name}`, r.Message);
|
|
190
|
+
});
|
|
171
191
|
}
|
|
172
192
|
```
|
|
173
193
|
|
|
@@ -175,14 +195,14 @@ if (result.success) {
|
|
|
175
195
|
|
|
176
196
|
```typescript
|
|
177
197
|
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
178
|
-
import {
|
|
198
|
+
import { RunViewParams, RunReportParams } from '@memberjunction/core';
|
|
179
199
|
|
|
180
200
|
// Setup data provider
|
|
181
201
|
const dataProvider = new SQLServerDataProvider(/* config */);
|
|
182
202
|
await dataProvider.initialize();
|
|
183
203
|
|
|
184
204
|
// Run a view with filtering and pagination
|
|
185
|
-
const viewOptions:
|
|
205
|
+
const viewOptions: RunViewParams = {
|
|
186
206
|
EntityName: 'vwActiveUsers',
|
|
187
207
|
ExtraFilter: "Role = 'Administrator'",
|
|
188
208
|
OrderBy: 'LastName, FirstName',
|
|
@@ -190,7 +210,7 @@ const viewOptions: RunViewOptions = {
|
|
|
190
210
|
PageNumber: 1
|
|
191
211
|
};
|
|
192
212
|
|
|
193
|
-
const viewResult = await dataProvider.
|
|
213
|
+
const viewResult = await dataProvider.RunView(viewOptions);
|
|
194
214
|
|
|
195
215
|
if (viewResult.success) {
|
|
196
216
|
console.log(`Found ${viewResult.Results.length} users`);
|
|
@@ -202,14 +222,17 @@ if (viewResult.success) {
|
|
|
202
222
|
}
|
|
203
223
|
|
|
204
224
|
// Run a report
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
225
|
+
const reportParams: RunReportParams = {
|
|
226
|
+
ReportID: 'report-id-here',
|
|
227
|
+
// Other parameters as needed
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
const reportResult = await dataProvider.RunReport(reportParams);
|
|
210
231
|
|
|
211
|
-
if (reportResult.
|
|
212
|
-
console.log('Report data:', reportResult.
|
|
232
|
+
if (reportResult.Success) {
|
|
233
|
+
console.log('Report data:', reportResult.Results);
|
|
234
|
+
console.log('Row count:', reportResult.RowCount);
|
|
235
|
+
console.log('Execution time:', reportResult.ExecutionTime, 'ms');
|
|
213
236
|
}
|
|
214
237
|
```
|
|
215
238
|
|
|
@@ -217,13 +240,14 @@ if (reportResult.success) {
|
|
|
217
240
|
|
|
218
241
|
```typescript
|
|
219
242
|
import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
243
|
+
import { RunQueryParams } from '@memberjunction/core';
|
|
220
244
|
|
|
221
245
|
// Setup data provider
|
|
222
246
|
const dataProvider = new SQLServerDataProvider(/* config */);
|
|
223
247
|
await dataProvider.initialize();
|
|
224
248
|
|
|
225
|
-
// Execute
|
|
226
|
-
const
|
|
249
|
+
// Execute raw SQL with parameters
|
|
250
|
+
const sqlResult = await dataProvider.ExecuteSQL(
|
|
227
251
|
'SELECT * FROM Users WHERE Department = @dept AND HireDate > @date',
|
|
228
252
|
{
|
|
229
253
|
dept: 'Engineering',
|
|
@@ -231,23 +255,33 @@ const queryResult = await dataProvider.executeQuery(
|
|
|
231
255
|
}
|
|
232
256
|
);
|
|
233
257
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
});
|
|
239
|
-
}
|
|
258
|
+
console.log(`Query returned ${sqlResult.length} rows`);
|
|
259
|
+
sqlResult.forEach(row => {
|
|
260
|
+
console.log(row);
|
|
261
|
+
});
|
|
240
262
|
|
|
241
263
|
// Execute a stored procedure
|
|
242
|
-
const spResult = await dataProvider.
|
|
264
|
+
const spResult = await dataProvider.ExecuteSQL(
|
|
243
265
|
'EXEC sp_GetUserPermissions @UserID',
|
|
244
266
|
{
|
|
245
267
|
UserID: 123
|
|
246
268
|
}
|
|
247
269
|
);
|
|
248
270
|
|
|
249
|
-
|
|
250
|
-
|
|
271
|
+
console.log('User permissions:', spResult);
|
|
272
|
+
|
|
273
|
+
// Using RunQuery for pre-defined queries
|
|
274
|
+
const queryParams: RunQueryParams = {
|
|
275
|
+
QueryID: 'query-id-here', // or use QueryName
|
|
276
|
+
// CategoryID: 'optional-category-id',
|
|
277
|
+
// CategoryName: 'optional-category-name'
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const queryResult = await dataProvider.RunQuery(queryParams);
|
|
281
|
+
|
|
282
|
+
if (queryResult.Success) {
|
|
283
|
+
console.log('Query results:', queryResult.Results);
|
|
284
|
+
console.log('Execution time:', queryResult.ExecutionTime, 'ms');
|
|
251
285
|
}
|
|
252
286
|
```
|
|
253
287
|
|
|
@@ -301,22 +335,170 @@ import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
|
|
|
301
335
|
|
|
302
336
|
class CustomSQLProvider extends SQLServerDataProvider {
|
|
303
337
|
// Override to add custom logging or modifications
|
|
304
|
-
async
|
|
338
|
+
async ExecuteSQL(sql: string, params?: any, maxRows?: number): Promise<any> {
|
|
305
339
|
console.log(`Executing SQL: ${sql}`);
|
|
306
340
|
console.log('Parameters:', params);
|
|
307
341
|
|
|
308
342
|
// Add timing
|
|
309
343
|
const startTime = Date.now();
|
|
310
|
-
const result = await super.
|
|
344
|
+
const result = await super.ExecuteSQL(sql, params, maxRows);
|
|
311
345
|
const duration = Date.now() - startTime;
|
|
312
346
|
|
|
313
347
|
console.log(`Query executed in ${duration}ms`);
|
|
348
|
+
console.log(`Rows returned: ${result?.length || 0}`);
|
|
314
349
|
|
|
315
350
|
return result;
|
|
316
351
|
}
|
|
352
|
+
|
|
353
|
+
// Custom error handling
|
|
354
|
+
protected async HandleExecuteSQLError(error: any, sql: string): Promise<void> {
|
|
355
|
+
console.error('SQL Error:', error);
|
|
356
|
+
console.error('Failed SQL:', sql);
|
|
357
|
+
// Add custom error handling logic here
|
|
358
|
+
await super.HandleExecuteSQLError(error, sql);
|
|
359
|
+
}
|
|
317
360
|
}
|
|
318
361
|
```
|
|
319
362
|
|
|
363
|
+
### Error Handling
|
|
364
|
+
|
|
365
|
+
The SQL Server Data Provider includes comprehensive error handling:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
try {
|
|
369
|
+
const result = await dataProvider.Save(entity, user);
|
|
370
|
+
if (!result.Success) {
|
|
371
|
+
console.error('Save failed:', result.ErrorMessage);
|
|
372
|
+
// Handle validation or business logic errors
|
|
373
|
+
}
|
|
374
|
+
} catch (error) {
|
|
375
|
+
console.error('Unexpected error:', error);
|
|
376
|
+
// Handle system-level errors
|
|
377
|
+
}
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Build & Development
|
|
381
|
+
|
|
382
|
+
### Building the Package
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
# From the package directory
|
|
386
|
+
npm run build
|
|
387
|
+
|
|
388
|
+
# Or from the repository root
|
|
389
|
+
turbo build --filter="@memberjunction/sqlserver-dataprovider"
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Development Scripts
|
|
393
|
+
|
|
394
|
+
- `npm run build` - Compile TypeScript to JavaScript
|
|
395
|
+
- `npm run start` - Run the package with ts-node-dev for development
|
|
396
|
+
|
|
397
|
+
### TypeScript Configuration
|
|
398
|
+
|
|
399
|
+
This package is configured with TypeScript strict mode enabled. The compiled output is placed in the `dist/` directory with declaration files for type support.
|
|
400
|
+
|
|
401
|
+
## API Reference
|
|
402
|
+
|
|
403
|
+
### SQLServerDataProvider
|
|
404
|
+
|
|
405
|
+
The main class that implements IEntityDataProvider, IMetadataProvider, IRunViewProvider, IRunReportProvider, and IRunQueryProvider interfaces.
|
|
406
|
+
|
|
407
|
+
#### Key Methods
|
|
408
|
+
|
|
409
|
+
- `Config(configData: SQLServerProviderConfigData): Promise<boolean>` - Configure the provider with connection details
|
|
410
|
+
- `Get(entity: EntityInfo, CompositeKey: CompositeKey, user?: UserInfo): Promise<BaseEntityResult>` - Load an entity by primary key
|
|
411
|
+
- `Save(entity: BaseEntity, user: UserInfo, options?: EntitySaveOptions): Promise<BaseEntityResult>` - Save (create/update) an entity
|
|
412
|
+
- `Delete(entity: EntityInfo, CompositeKey: CompositeKey, user?: UserInfo, options?: EntityDeleteOptions): Promise<BaseEntityResult>` - Delete an entity
|
|
413
|
+
- `RunView(params: RunViewParams, contextUser?: UserInfo): Promise<RunViewResult>` - Execute a database view
|
|
414
|
+
- `RunReport(params: RunReportParams, contextUser?: UserInfo): Promise<RunReportResult>` - Execute a report
|
|
415
|
+
- `RunQuery(params: RunQueryParams, contextUser?: UserInfo): Promise<RunQueryResult>` - Execute a query
|
|
416
|
+
- `ExecuteSQL(sql: string, params?: any, maxRows?: number): Promise<any[]>` - Execute raw SQL
|
|
417
|
+
|
|
418
|
+
### SQLServerProviderConfigData
|
|
419
|
+
|
|
420
|
+
Configuration class for the SQL Server provider.
|
|
421
|
+
|
|
422
|
+
#### Properties
|
|
423
|
+
|
|
424
|
+
- `DataSource: DataSource` - TypeORM DataSource instance
|
|
425
|
+
- `CurrentUserEmail: string` - Email of the current user
|
|
426
|
+
- `CheckRefreshIntervalSeconds: number` - Interval for checking metadata refresh (0 to disable)
|
|
427
|
+
- `MJCoreSchemaName: string` - Schema name for MJ core tables (default: '__mj')
|
|
428
|
+
- `IncludeSchemas?: string[]` - List of schemas to include
|
|
429
|
+
- `ExcludeSchemas?: string[]` - List of schemas to exclude
|
|
430
|
+
|
|
431
|
+
### SQLServerTransactionGroup
|
|
432
|
+
|
|
433
|
+
SQL Server implementation of TransactionGroupBase for managing database transactions.
|
|
434
|
+
|
|
435
|
+
#### Methods
|
|
436
|
+
|
|
437
|
+
- `HandleSubmit(): Promise<TransactionResult[]>` - Execute all pending transactions in the group
|
|
438
|
+
|
|
439
|
+
### UserCache
|
|
440
|
+
|
|
441
|
+
Server-side cache for user and role information.
|
|
442
|
+
|
|
443
|
+
#### Static Methods
|
|
444
|
+
|
|
445
|
+
- `Instance: UserCache` - Get singleton instance
|
|
446
|
+
- `Users: UserInfo[]` - Get all cached users
|
|
447
|
+
|
|
448
|
+
#### Instance Methods
|
|
449
|
+
|
|
450
|
+
- `Refresh(dataSource: DataSource, autoRefreshIntervalMS?: number): Promise<void>` - Refresh user cache
|
|
451
|
+
- `UserByName(name: string, caseSensitive?: boolean): UserInfo | undefined` - Find user by name
|
|
452
|
+
|
|
453
|
+
### setupSQLServerClient
|
|
454
|
+
|
|
455
|
+
Helper function to initialize and configure the SQL Server data provider.
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
setupSQLServerClient(config: SQLServerProviderConfigData): Promise<SQLServerDataProvider>
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Troubleshooting
|
|
462
|
+
|
|
463
|
+
### Common Issues
|
|
464
|
+
|
|
465
|
+
1. **Connection Timeout Errors**
|
|
466
|
+
- Increase `connectionTimeout` and `requestTimeout` in configuration
|
|
467
|
+
- Verify network connectivity to SQL Server
|
|
468
|
+
- Check SQL Server firewall rules
|
|
469
|
+
|
|
470
|
+
2. **Authentication Failures**
|
|
471
|
+
- Ensure correct username/password or Windows authentication
|
|
472
|
+
- Verify user has appropriate database permissions
|
|
473
|
+
- Check if encryption settings match server requirements
|
|
474
|
+
|
|
475
|
+
3. **Schema Not Found**
|
|
476
|
+
- Verify `MJCoreSchemaName` matches your database schema (default: `__mj`)
|
|
477
|
+
- Ensure user has access to the schema
|
|
478
|
+
- Check if MemberJunction tables are properly installed
|
|
479
|
+
|
|
480
|
+
4. **Transaction Rollback Issues**
|
|
481
|
+
- Check for constraint violations in related entities
|
|
482
|
+
- Verify all required fields are populated
|
|
483
|
+
- Review transaction logs for specific error details
|
|
484
|
+
|
|
485
|
+
5. **Performance Issues**
|
|
486
|
+
- Adjust connection pool settings (`pool.max`, `pool.min`)
|
|
487
|
+
- Enable query logging to identify slow queries
|
|
488
|
+
- Consider adding database indexes for frequently queried fields
|
|
489
|
+
|
|
490
|
+
### Debug Logging
|
|
491
|
+
|
|
492
|
+
Enable detailed logging by setting environment variables:
|
|
493
|
+
|
|
494
|
+
```bash
|
|
495
|
+
# Enable SQL query logging
|
|
496
|
+
export MJ_LOG_SQL=true
|
|
497
|
+
|
|
498
|
+
# Enable detailed error logging
|
|
499
|
+
export MJ_LOG_LEVEL=debug
|
|
500
|
+
```
|
|
501
|
+
|
|
320
502
|
## License
|
|
321
503
|
|
|
322
504
|
ISC
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/sqlserver-dataprovider",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.45.0",
|
|
4
4
|
"description": "MemberJunction: SQL Server Client Data Provider",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"typescript": "^5.4.5"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@memberjunction/actions": "2.
|
|
23
|
-
"@memberjunction/ai": "2.
|
|
24
|
-
"@memberjunction/ai-vector-dupe": "2.
|
|
25
|
-
"@memberjunction/aiengine": "2.
|
|
26
|
-
"@memberjunction/core": "2.
|
|
27
|
-
"@memberjunction/core-entities": "2.
|
|
28
|
-
"@memberjunction/global": "2.
|
|
29
|
-
"@memberjunction/queue": "2.
|
|
22
|
+
"@memberjunction/actions": "2.45.0",
|
|
23
|
+
"@memberjunction/ai": "2.45.0",
|
|
24
|
+
"@memberjunction/ai-vector-dupe": "2.45.0",
|
|
25
|
+
"@memberjunction/aiengine": "2.45.0",
|
|
26
|
+
"@memberjunction/core": "2.45.0",
|
|
27
|
+
"@memberjunction/core-entities": "2.45.0",
|
|
28
|
+
"@memberjunction/global": "2.45.0",
|
|
29
|
+
"@memberjunction/queue": "2.45.0",
|
|
30
30
|
"mssql": "^11.0.1",
|
|
31
31
|
"typeorm": "^0.3.20"
|
|
32
32
|
}
|