@bhushanpawar/sqldb 1.0.0 → 1.0.1

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.
Files changed (65) hide show
  1. package/README.md +695 -4
  2. package/dist/cache/cache-manager.d.ts.map +1 -1
  3. package/dist/cache/cache-manager.js +2 -1
  4. package/dist/cache/cache-manager.js.map +1 -1
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +225 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/schema-generator.d.ts +28 -0
  10. package/dist/cli/schema-generator.d.ts.map +1 -0
  11. package/dist/cli/schema-generator.js +159 -0
  12. package/dist/cli/schema-generator.js.map +1 -0
  13. package/dist/client.d.ts +32 -0
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/client.js +56 -14
  16. package/dist/client.js.map +1 -1
  17. package/dist/connection/mariadb.d.ts +21 -0
  18. package/dist/connection/mariadb.d.ts.map +1 -1
  19. package/dist/connection/mariadb.js +121 -3
  20. package/dist/connection/mariadb.js.map +1 -1
  21. package/dist/db-schema.d.ts +413 -0
  22. package/dist/db-schema.d.ts.map +1 -0
  23. package/dist/db-schema.js +1149 -0
  24. package/dist/db-schema.js.map +1 -0
  25. package/dist/discovery/dependency-graph.d.ts +3 -0
  26. package/dist/discovery/dependency-graph.d.ts.map +1 -1
  27. package/dist/discovery/dependency-graph.js +11 -0
  28. package/dist/discovery/dependency-graph.js.map +1 -1
  29. package/dist/discovery/schema-reader.d.ts +1 -1
  30. package/dist/discovery/schema-reader.d.ts.map +1 -1
  31. package/dist/discovery/schema-reader.js +48 -19
  32. package/dist/discovery/schema-reader.js.map +1 -1
  33. package/dist/index.d.ts +9 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +63 -3
  36. package/dist/index.js.map +1 -1
  37. package/dist/query/operations.d.ts +7 -0
  38. package/dist/query/operations.d.ts.map +1 -1
  39. package/dist/query/operations.js +204 -22
  40. package/dist/query/operations.js.map +1 -1
  41. package/dist/types/client.d.ts +32 -0
  42. package/dist/types/client.d.ts.map +1 -0
  43. package/dist/types/client.js +3 -0
  44. package/dist/types/client.js.map +1 -0
  45. package/dist/types/config.d.ts +3 -0
  46. package/dist/types/config.d.ts.map +1 -1
  47. package/dist/types/config.js +14 -1
  48. package/dist/types/config.js.map +1 -1
  49. package/dist/types/query.d.ts +12 -0
  50. package/dist/types/query.d.ts.map +1 -1
  51. package/dist/types/schema.d.ts +6 -0
  52. package/dist/types/schema.d.ts.map +1 -1
  53. package/dist/types/warming.d.ts +47 -0
  54. package/dist/types/warming.d.ts.map +1 -0
  55. package/dist/types/warming.js +3 -0
  56. package/dist/types/warming.js.map +1 -0
  57. package/dist/warming/auto-warming-manager.d.ts +65 -0
  58. package/dist/warming/auto-warming-manager.d.ts.map +1 -0
  59. package/dist/warming/auto-warming-manager.js +256 -0
  60. package/dist/warming/auto-warming-manager.js.map +1 -0
  61. package/dist/warming/query-stats-tracker.d.ts +53 -0
  62. package/dist/warming/query-stats-tracker.d.ts.map +1 -0
  63. package/dist/warming/query-stats-tracker.js +273 -0
  64. package/dist/warming/query-stats-tracker.js.map +1 -0
  65. package/package.json +4 -1
package/README.md CHANGED
@@ -80,6 +80,57 @@ await users.deleteById(1);
80
80
  await db.close();
81
81
  ```
82
82
 
83
+ ### Singleton Pattern (Recommended)
84
+
85
+ For production applications, use singleton mode to share a single connection pool:
86
+
87
+ ```typescript
88
+ import { createSmartDB, getSmartDB } from '@bhushanpawar/sqldb';
89
+
90
+ // Initialize once at app startup
91
+ const db = await createSmartDB({
92
+ mariadb: { /* config */ },
93
+ redis: { /* config */ },
94
+ cache: { enabled: true },
95
+ }, { singleton: true }); // Enable singleton mode
96
+
97
+ // Access anywhere in your app
98
+ import { getSmartDB } from '@bhushanpawar/sqldb';
99
+
100
+ const db = getSmartDB(); // Returns the same instance
101
+ const users = db.getTableOperations('users');
102
+ ```
103
+
104
+ See [SINGLETON_PATTERN.md](./docs/SINGLETON_PATTERN.md) for detailed usage.
105
+
106
+ ### Dynamic Table Access (TypeScript-Friendly)
107
+
108
+ Access tables directly as properties with full type safety:
109
+
110
+ ```typescript
111
+ import { createSmartDB, SmartDBWithTables } from '@bhushanpawar/sqldb';
112
+
113
+ // Define your schema
114
+ interface MySchema {
115
+ users: { id: number; name: string; email: string };
116
+ orders: { id: number; user_id: number; total: number };
117
+ }
118
+
119
+ type MyDB = SmartDBWithTables<MySchema>;
120
+
121
+ const db = await createSmartDB(config) as MyDB;
122
+
123
+ // Clean, typed access
124
+ const users = await db.users.findMany(); // Type: MySchema['users'][]
125
+ const order = await db.orders.findById(123); // Type: MySchema['orders'] | null
126
+ await db.users.updateById(1, { name: 'Jane' }); // Fully type-checked
127
+
128
+ // Still works the old way too
129
+ const usersTable = db.getTableOperations('users');
130
+ ```
131
+
132
+ See [DYNAMIC_TABLE_ACCESS.md](./docs/DYNAMIC_TABLE_ACCESS.md) for detailed usage.
133
+
83
134
  ### Raw Query Caching
84
135
 
85
136
  The `raw` method supports caching custom SQL queries with a configurable TTL (default: 1 minute):
@@ -432,6 +483,48 @@ await users.warmCache({ status: 'active' });
432
483
  const active = await users.findMany({ status: 'active' });
433
484
  ```
434
485
 
486
+ ### Cache Warming with Relations
487
+
488
+ Pre-warm cache for a table and all its related tables based on the dependency graph:
489
+
490
+ ```typescript
491
+ const provider = db.getTableOperations('provider');
492
+
493
+ // Warm cache for provider and all related tables
494
+ await provider.warmCacheWithRelations({}, {
495
+ correlationId: 'startup-warming',
496
+ depth: 1, // How deep to traverse relationships
497
+ warmDependents: true, // Warm tables that reference this table
498
+ warmDependencies: true, // Warm tables this table references
499
+ });
500
+
501
+ // Now provider and all related tables are cached:
502
+ // - provider (main table)
503
+ // - user (table that provider depends on)
504
+ // - orders, services, bank_details, etc. (tables that depend on provider)
505
+ ```
506
+
507
+ **Use Cases:**
508
+ - **Application startup**: Pre-warm frequently accessed tables and their relations
509
+ - **API endpoints**: Warm cache before handling requests for better response times
510
+ - **Batch operations**: Pre-load related data before processing
511
+
512
+ **Example - Warm on Startup:**
513
+ ```typescript
514
+ async function warmCacheOnStartup(db: SmartDBClient) {
515
+ // Warm most frequently accessed tables with their relations
516
+ const provider = db.getTableOperations('provider');
517
+ const orders = db.getTableOperations('orders');
518
+
519
+ await Promise.all([
520
+ provider.warmCacheWithRelations({}, { depth: 1, warmDependents: true }),
521
+ orders.warmCacheWithRelations({}, { depth: 1, warmDependencies: true }),
522
+ ]);
523
+
524
+ console.log('Cache warmed successfully!');
525
+ }
526
+ ```
527
+
435
528
  ## Query Tracking
436
529
 
437
530
  Track queries with correlation IDs for debugging and performance monitoring:
@@ -769,15 +862,613 @@ Based on real-world testing:
769
862
  - **Throughput**: 10,000+ queries/second with Redis cache
770
863
  - **Memory**: ~1KB per cached query
771
864
 
772
- See [PERFORMANCE_RESULTS.md](./PERFORMANCE_RESULTS.md) for detailed benchmarks.
865
+ See [PERFORMANCE_RESULTS.md](./docs/PERFORMANCE_RESULTS.md) for detailed benchmarks.
773
866
 
774
867
  ## Examples
775
868
 
776
- See the [examples](./examples) directory for complete examples:
869
+ This section provides examples from simple to complex, helping you get started quickly and gradually explore advanced features.
870
+
871
+ ### 1. Hello World - Minimal Setup
872
+
873
+ The simplest way to get started with SmartDB:
874
+
875
+ ```typescript
876
+ import { createSmartDB } from '@bhushanpawar/sqldb';
877
+
878
+ // Initialize with minimal config
879
+ const db = await createSmartDB({
880
+ mariadb: {
881
+ host: 'localhost',
882
+ user: 'root',
883
+ password: 'password',
884
+ database: 'mydb',
885
+ },
886
+ redis: {
887
+ host: 'localhost',
888
+ },
889
+ });
890
+
891
+ // Query users - automatically cached!
892
+ const users = await (db as any).users.findMany();
893
+ console.log('Found users:', users.length);
894
+
895
+ await db.close();
896
+ ```
897
+
898
+ **What this does:**
899
+ - Connects to MariaDB and Redis
900
+ - Auto-discovers all tables in your database
901
+ - Enables caching with smart defaults (60s TTL)
902
+ - Provides simple CRUD operations
903
+
904
+ ---
905
+
906
+ ### 2. Basic CRUD Operations
907
+
908
+ Learn all the basic operations with caching:
909
+
910
+ ```typescript
911
+ import { createSmartDB } from '@bhushanpawar/sqldb';
912
+
913
+ const db = await createSmartDB({
914
+ mariadb: { host: 'localhost', user: 'root', password: 'password', database: 'mydb' },
915
+ redis: { host: 'localhost' },
916
+ cache: {
917
+ enabled: true,
918
+ defaultTTL: 60,
919
+ invalidateOnWrite: true, // Auto-clear cache on INSERT/UPDATE/DELETE
920
+ },
921
+ });
922
+
923
+ // READ operations (cached automatically)
924
+ const allUsers = await (db as any).users.findMany();
925
+ const activeUsers = await (db as any).users.findMany({ status: 'active' });
926
+ const user = await (db as any).users.findById(1);
927
+ const count = await (db as any).users.count({ status: 'active' });
928
+
929
+ // CREATE operations (invalidates cache)
930
+ const newUser = await (db as any).users.insertOne({
931
+ name: 'John Doe',
932
+ email: 'john@example.com',
933
+ });
934
+
935
+ // UPDATE operations (invalidates cache)
936
+ await (db as any).users.updateById(1, { status: 'verified' });
937
+ await (db as any).users.updateMany({ status: 'pending' }, { status: 'active' });
938
+
939
+ // DELETE operations (invalidates cache)
940
+ await (db as any).users.deleteById(1);
941
+ await (db as any).users.deleteMany({ status: 'inactive' });
942
+
943
+ // Check cache performance
944
+ const stats = db.getCacheManager().getStats();
945
+ console.log('Cache hit rate:', stats.hitRate);
946
+
947
+ await db.close();
948
+ ```
949
+
950
+ **New concepts:**
951
+ - Automatic cache invalidation on writes
952
+ - Multiple find/update/delete methods
953
+ - Cache statistics monitoring
954
+
955
+ **See:** [basic-usage.ts](./examples/basic-usage.ts)
956
+
957
+ ---
958
+
959
+ ### 3. Type-Safe Queries with TypeScript
960
+
961
+ Add full type safety to your queries:
962
+
963
+ ```typescript
964
+ import { createSmartDB, SmartDBWithTables } from '@bhushanpawar/sqldb';
965
+
966
+ // Define your schema
967
+ interface User {
968
+ id: number;
969
+ name: string;
970
+ email: string;
971
+ status: 'active' | 'inactive' | 'verified';
972
+ created_at: Date;
973
+ }
974
+
975
+ interface Order {
976
+ id: number;
977
+ user_id: number;
978
+ total: number;
979
+ status: string;
980
+ }
981
+
982
+ interface MySchema {
983
+ users: User;
984
+ orders: Order;
985
+ }
986
+
987
+ // Create typed DB instance
988
+ type MyDB = SmartDBWithTables<MySchema>;
989
+ const db = await createSmartDB(config) as MyDB;
990
+
991
+ // Full type safety!
992
+ const users = await db.users.findMany(); // Type: User[]
993
+ const user = await db.users.findById(1); // Type: User | null
994
+ await db.users.updateById(1, { status: 'verified' }); // Type-checked!
995
+
996
+ // TypeScript will catch errors
997
+ // await db.users.updateById(1, { invalid: 'field' }); // ❌ Error!
998
+ ```
999
+
1000
+ **New concepts:**
1001
+ - TypeScript interfaces for your schema
1002
+ - Compile-time type checking
1003
+ - Auto-completion in your IDE
1004
+
1005
+ **See:** [typed-tables-example.ts](./examples/typed-tables-example.ts), [DYNAMIC_TABLE_ACCESS.md](./docs/DYNAMIC_TABLE_ACCESS.md)
1006
+
1007
+ ---
1008
+
1009
+ ### 4. Query Tracking & Performance Monitoring
1010
+
1011
+ Track query performance with correlation IDs:
1012
+
1013
+ ```typescript
1014
+ import { createSmartDB, generateQueryId } from '@bhushanpawar/sqldb';
1015
+
1016
+ const db = await createSmartDB({
1017
+ mariadb: { /* config */ },
1018
+ redis: { /* config */ },
1019
+ logging: { level: 'info' },
1020
+ });
1021
+
1022
+ // Generate a correlation ID (e.g., per HTTP request)
1023
+ const correlationId = generateQueryId();
1024
+
1025
+ // All queries with same correlationId are tracked together
1026
+ const users = await (db as any).users.findMany(
1027
+ { status: 'active' },
1028
+ { correlationId }
1029
+ );
1030
+
1031
+ const count = await (db as any).users.count(
1032
+ { status: 'active' },
1033
+ correlationId
1034
+ );
1035
+
1036
+ // Analyze performance
1037
+ const queries = db.getQueries(correlationId);
1038
+ queries.forEach(q => {
1039
+ console.log({
1040
+ table: q.sql.match(/FROM (\w+)/)?.[1],
1041
+ executionTime: q.executionTimeMs + 'ms',
1042
+ cached: q.resultCount,
1043
+ });
1044
+ });
1045
+
1046
+ // Calculate total time
1047
+ const totalTime = queries.reduce((sum, q) => sum + (q.executionTimeMs || 0), 0);
1048
+ console.log(`Total query time: ${totalTime}ms`);
1049
+
1050
+ // Clean up
1051
+ db.clearQueries(correlationId);
1052
+ ```
1053
+
1054
+ **New concepts:**
1055
+ - Correlation IDs for request tracking
1056
+ - Query performance analysis
1057
+ - Debugging slow requests
1058
+
1059
+ **Use cases:**
1060
+ - HTTP request tracking
1061
+ - Performance monitoring
1062
+ - Identifying slow queries
1063
+
1064
+ **See:** [query-tracking.ts](./examples/query-tracking.ts), [QUERY_TRACKING.md](./docs/QUERY_TRACKING.md)
1065
+
1066
+ ---
1067
+
1068
+ ### 5. Enhanced Query Logging
1069
+
1070
+ Monitor all database queries with detailed logging:
1071
+
1072
+ ```typescript
1073
+ import { createSmartDB } from '@bhushanpawar/sqldb';
1074
+
1075
+ const db = await createSmartDB({
1076
+ mariadb: {
1077
+ host: 'localhost',
1078
+ user: 'root',
1079
+ password: 'password',
1080
+ database: 'mydb',
1081
+ logging: true, // Enable query logging
1082
+ },
1083
+ redis: { host: 'localhost' },
1084
+ logging: { level: 'info' },
1085
+ });
1086
+
1087
+ // Run queries - they'll be logged automatically
1088
+ const users = await (db as any).users.findMany({ status: 'active' });
1089
+ const count = await (db as any).users.count({});
1090
+
1091
+ // Console output shows:
1092
+ // ✅ SELECT on users - 45ms - 10 rows
1093
+ // 🚀 SELECT on users - 12ms - 1 rows
1094
+ // ⚠️ SELECT on orders - 250ms - 100 rows (shows SQL for slow queries)
1095
+ ```
1096
+
1097
+ **Logging features:**
1098
+ - Query type (SELECT, INSERT, UPDATE, DELETE)
1099
+ - Table name extraction
1100
+ - Execution time with performance emojis
1101
+ - Automatic SQL display for slow queries (>200ms)
1102
+
1103
+ **Performance emojis:**
1104
+ - ⚡ Very fast (<10ms)
1105
+ - 🚀 Fast (<50ms)
1106
+ - ✅ Good (<200ms)
1107
+ - ⚠️ Slow (<500ms)
1108
+ - 🐌 Very slow (≥500ms)
1109
+
1110
+ **See:** [query-logging-example.ts](./examples/query-logging-example.ts), [QUERY_LOGGING.md](./docs/QUERY_LOGGING.md)
1111
+
1112
+ ---
1113
+
1114
+ ### 6. Smart Cache Invalidation with Relations
1115
+
1116
+ Automatic cascade invalidation based on foreign keys:
1117
+
1118
+ ```typescript
1119
+ // Database schema:
1120
+ // users (id, name)
1121
+ // posts (id, user_id, title) ← FK to users
1122
+ // comments (id, post_id, content) ← FK to posts
1123
+
1124
+ const db = await createSmartDB({
1125
+ mariadb: { /* config */ },
1126
+ redis: { /* config */ },
1127
+ cache: {
1128
+ enabled: true,
1129
+ invalidateOnWrite: true,
1130
+ cascadeInvalidation: true, // Enable cascade invalidation
1131
+ },
1132
+ discovery: {
1133
+ autoDiscover: true, // Auto-discover relationships
1134
+ },
1135
+ });
1136
+
1137
+ // When you update a user...
1138
+ await (db as any).users.updateById(1, { name: 'Updated Name' });
1139
+
1140
+ // SmartDB automatically invalidates:
1141
+ // 1. users:* (direct table)
1142
+ // 2. posts:* (depends on users via user_id)
1143
+ // 3. comments:* (depends on posts via post_id)
1144
+
1145
+ // View the dependency graph
1146
+ const graph = db.getDependencyGraph();
1147
+ const dependencies = graph.getDependencies('users');
1148
+ console.log('Tables that depend on users:', dependencies); // ['posts', 'comments']
1149
+
1150
+ // Manual invalidation with cascade
1151
+ const invalidationManager = db.getInvalidationManager();
1152
+ await invalidationManager.invalidateTable('users', { cascade: true });
1153
+ ```
1154
+
1155
+ **New concepts:**
1156
+ - Automatic relationship discovery
1157
+ - Cascade cache invalidation
1158
+ - Dependency graph visualization
1159
+
1160
+ **See:** [relationships-example.ts](./examples/relationships-example.ts)
1161
+
1162
+ ---
1163
+
1164
+ ### 7. Singleton Pattern for Production
1165
+
1166
+ Share a single SmartDB instance across your entire application:
1167
+
1168
+ ```typescript
1169
+ // db.ts - Initialize once at app startup
1170
+ import { createSmartDB } from '@bhushanpawar/sqldb';
1171
+
1172
+ export const initializeDB = async () => {
1173
+ const db = await createSmartDB({
1174
+ mariadb: { /* config */ },
1175
+ redis: { /* config */ },
1176
+ cache: { enabled: true },
1177
+ }, { singleton: true }); // Enable singleton mode
1178
+
1179
+ return db;
1180
+ };
1181
+
1182
+ // server.ts - Initialize at startup
1183
+ import { initializeDB } from './db';
1184
+
1185
+ const db = await initializeDB();
1186
+ console.log('Database initialized');
1187
+
1188
+ // userController.ts - Access anywhere
1189
+ import { getSmartDB } from '@bhushanpawar/sqldb';
1190
+
1191
+ export const getUsers = async () => {
1192
+ const db = getSmartDB(); // Returns the same instance
1193
+ return await (db as any).users.findMany();
1194
+ };
1195
+
1196
+ // orderController.ts - Access anywhere
1197
+ import { getSmartDB } from '@bhushanpawar/sqldb';
1198
+
1199
+ export const getOrders = async (userId: number) => {
1200
+ const db = getSmartDB(); // Same instance
1201
+ return await (db as any).orders.findMany({ user_id: userId });
1202
+ };
1203
+ ```
1204
+
1205
+ **Benefits:**
1206
+ - Single connection pool shared across app
1207
+ - No need to pass `db` around
1208
+ - Prevents multiple connections
1209
+ - Clean architecture
1210
+
1211
+ **See:** [singleton-example.ts](./examples/singleton-example.ts), [SINGLETON_PATTERN.md](./docs/SINGLETON_PATTERN.md)
1212
+
1213
+ ---
1214
+
1215
+ ### 8. Cache Warming for Better Performance
1216
+
1217
+ Pre-warm cache on startup for frequently accessed queries:
1218
+
1219
+ ```typescript
1220
+ import { createSmartDB } from '@bhushanpawar/sqldb';
1221
+
1222
+ const db = await createSmartDB({
1223
+ mariadb: { /* config */ },
1224
+ redis: { /* config */ },
1225
+ cache: { enabled: true },
1226
+ });
1227
+
1228
+ // Warm cache for specific queries
1229
+ await (db as any).users.warmCache({ status: 'active' });
1230
+ await (db as any).products.warmCache({ featured: true });
1231
+
1232
+ // Warm cache with related tables (follows foreign keys)
1233
+ await (db as any).orders.warmCacheWithRelations(
1234
+ { status: 'pending' },
1235
+ {
1236
+ depth: 1, // How deep to traverse relationships
1237
+ warmDependents: true, // Warm tables that reference this table
1238
+ warmDependencies: true, // Warm tables this table references
1239
+ correlationId: 'startup-warming',
1240
+ }
1241
+ );
1242
+
1243
+ // This warms:
1244
+ // - orders (main table)
1245
+ // - users (orders.user_id → users.id)
1246
+ // - order_items (order_items.order_id → orders.id)
1247
+ // - products (order_items.product_id → products.id)
1248
+
1249
+ // Now these queries are instant (served from cache)
1250
+ const orders = await (db as any).orders.findMany({ status: 'pending' });
1251
+ const user = await (db as any).users.findById(orders[0].user_id);
1252
+ ```
1253
+
1254
+ **Use cases:**
1255
+ - Application startup optimization
1256
+ - Pre-loading frequently accessed data
1257
+ - Improving first request performance
1258
+
1259
+ **See:** Cache warming section above
1260
+
1261
+ ---
1262
+
1263
+ ### 9. Auto-Warming - Intelligent Background Cache Warming
1264
+
1265
+ Automatically warm cache for your hottest queries:
1266
+
1267
+ ```typescript
1268
+ import { createSmartDB } from '@bhushanpawar/sqldb';
1269
+
1270
+ const db = await createSmartDB({
1271
+ mariadb: { /* config */ },
1272
+ redis: { /* config */ },
1273
+ cache: { enabled: true },
1274
+ warming: {
1275
+ enabled: true, // Enable auto-warming
1276
+ intervalMs: 60000, // Warm every 60 seconds
1277
+ topQueriesPerTable: 10, // Warm top 10 queries per table
1278
+ minAccessCount: 3, // Must be accessed at least 3 times
1279
+ maxStatsAge: 3600000, // Consider queries from last hour
1280
+ useSeperatePool: true, // Use separate connection pool
1281
+ warmingPoolSize: 2, // 2 connections for warming
1282
+ trackInDatabase: true, // Persist stats in database
1283
+ statsTableName: '__sqldb_query_stats',
1284
+
1285
+ // Callbacks
1286
+ onWarmingComplete: (stats) => {
1287
+ console.log('Warming complete:', {
1288
+ queriesWarmed: stats.queriesWarmed,
1289
+ cacheHitRateBefore: (stats.cacheHitRateBefore * 100).toFixed(1) + '%',
1290
+ cacheHitRateAfter: (stats.cacheHitRateAfter * 100).toFixed(1) + '%',
1291
+ });
1292
+ },
1293
+ onWarmingError: (error) => {
1294
+ console.error('Warming error:', error.message);
1295
+ },
1296
+ },
1297
+ });
1298
+
1299
+ // Use your app normally - auto-warming tracks which queries are hot
1300
+ for (let i = 0; i < 10; i++) {
1301
+ const users = await (db as any).users.findMany({ status: 'active' });
1302
+ const orders = await (db as any).orders.findMany({ status: 'pending' });
1303
+ await new Promise(r => setTimeout(r, 1000));
1304
+ }
1305
+
1306
+ // After 60 seconds, auto-warming will:
1307
+ // 1. Identify the most frequently accessed queries
1308
+ // 2. Pre-warm them in the background
1309
+ // 3. Improve cache hit rate automatically
1310
+
1311
+ // Check warming stats
1312
+ const warmingStats = db.getWarmingStats();
1313
+ console.log('Latest warming:', {
1314
+ queriesWarmed: warmingStats.queriesWarmed,
1315
+ totalTime: warmingStats.totalTimeMs + 'ms',
1316
+ perTable: warmingStats.tables,
1317
+ });
1318
+
1319
+ // Manually trigger warming
1320
+ const manualStats = await db.warmCache();
1321
+ console.log('Manual warming:', manualStats.queriesWarmed, 'queries');
1322
+ ```
1323
+
1324
+ **How it works:**
1325
+ 1. Tracks query frequency per table in `__sqldb_query_stats` table
1326
+ 2. Every X seconds, identifies the hottest queries
1327
+ 3. Pre-warms them using a separate connection pool (no impact on app)
1328
+ 4. Persists stats across restarts
1329
+
1330
+ **Benefits:**
1331
+ - Automatic - no manual configuration
1332
+ - Intelligent - only warms frequently used queries
1333
+ - Non-blocking - uses separate connection pool
1334
+ - Persistent - stats survive app restarts
1335
+ - Observable - callbacks for monitoring
1336
+
1337
+ **See:** [auto-warming-example.ts](./examples/auto-warming-example.ts), [AUTO_WARMING.md](./docs/AUTO_WARMING.md)
1338
+
1339
+ ---
1340
+
1341
+ ### 10. Complete Production Example
1342
+
1343
+ A real-world production setup with all features:
1344
+
1345
+ ```typescript
1346
+ import { createSmartDB, generateQueryId } from '@bhushanpawar/sqldb';
1347
+
1348
+ // Production configuration
1349
+ const db = await createSmartDB({
1350
+ mariadb: {
1351
+ host: process.env.DB_HOST,
1352
+ port: parseInt(process.env.DB_PORT || '3306'),
1353
+ user: process.env.DB_USER,
1354
+ password: process.env.DB_PASSWORD,
1355
+ database: process.env.DB_NAME,
1356
+ connectionLimit: 20,
1357
+ acquireTimeout: 10000,
1358
+ connectTimeout: 10000,
1359
+ logging: process.env.NODE_ENV === 'development',
1360
+ },
1361
+ redis: {
1362
+ host: process.env.REDIS_HOST,
1363
+ port: parseInt(process.env.REDIS_PORT || '6379'),
1364
+ password: process.env.REDIS_PASSWORD,
1365
+ keyPrefix: 'myapp:',
1366
+ },
1367
+ cache: {
1368
+ enabled: true,
1369
+ defaultTTL: 300, // 5 minutes
1370
+ maxKeys: 10000,
1371
+ invalidateOnWrite: true,
1372
+ cascadeInvalidation: true,
1373
+ },
1374
+ discovery: {
1375
+ autoDiscover: true,
1376
+ excludedTables: ['migrations', 'temp_*'],
1377
+ maxGraphDepth: 3,
1378
+ refreshInterval: 3600000, // Refresh schema every hour
1379
+ },
1380
+ warming: {
1381
+ enabled: process.env.NODE_ENV === 'production',
1382
+ intervalMs: 300000, // Warm every 5 minutes
1383
+ topQueriesPerTable: 20,
1384
+ minAccessCount: 5,
1385
+ useSeperatePool: true,
1386
+ trackInDatabase: true,
1387
+ onWarmingComplete: (stats) => {
1388
+ logger.info('Cache warming complete', {
1389
+ queriesWarmed: stats.queriesWarmed,
1390
+ hitRateImprovement:
1391
+ ((stats.cacheHitRateAfter - stats.cacheHitRateBefore) * 100).toFixed(2) + '%',
1392
+ });
1393
+ },
1394
+ },
1395
+ logging: {
1396
+ level: process.env.LOG_LEVEL || 'info',
1397
+ logger: (level, message, meta) => {
1398
+ // Use your preferred logger (Winston, Pino, etc.)
1399
+ logger[level](message, meta);
1400
+ },
1401
+ },
1402
+ }, { singleton: true });
1403
+
1404
+ // Express middleware for request tracking
1405
+ app.use((req, res, next) => {
1406
+ req.correlationId = generateQueryId();
1407
+ res.on('finish', () => {
1408
+ const queries = db.getQueries(req.correlationId);
1409
+ const totalTime = queries.reduce((sum, q) => sum + (q.executionTimeMs || 0), 0);
1410
+
1411
+ // Log slow requests
1412
+ if (totalTime > 1000) {
1413
+ logger.warn('Slow request', {
1414
+ path: req.path,
1415
+ method: req.method,
1416
+ totalTime,
1417
+ queryCount: queries.length,
1418
+ correlationId: req.correlationId,
1419
+ });
1420
+ }
1421
+
1422
+ db.clearQueries(req.correlationId);
1423
+ });
1424
+ next();
1425
+ });
1426
+
1427
+ // Health check endpoint
1428
+ app.get('/health', async (req, res) => {
1429
+ const health = await db.healthCheck();
1430
+ const stats = db.getCacheManager().getStats();
1431
+
1432
+ res.json({
1433
+ status: health.mariadb && health.redis ? 'healthy' : 'unhealthy',
1434
+ ...health,
1435
+ cache: stats,
1436
+ timestamp: new Date().toISOString(),
1437
+ });
1438
+ });
1439
+
1440
+ // Graceful shutdown
1441
+ process.on('SIGTERM', async () => {
1442
+ logger.info('SIGTERM received, closing connections...');
1443
+ await db.close();
1444
+ process.exit(0);
1445
+ });
1446
+ ```
1447
+
1448
+ **Production best practices:**
1449
+ - Environment-based configuration
1450
+ - Connection pooling optimization
1451
+ - Schema refresh scheduling
1452
+ - Auto-warming in production only
1453
+ - Request tracking middleware
1454
+ - Performance monitoring
1455
+ - Health checks
1456
+ - Graceful shutdown
1457
+
1458
+ ---
1459
+
1460
+ ### More Examples
1461
+
1462
+ For complete working examples, see the [examples](./examples) directory:
777
1463
 
778
- - [usage.ts](./examples/usage.ts) - Basic CRUD operations
1464
+ - [basic-usage.ts](./examples/basic-usage.ts) - Basic CRUD operations
1465
+ - [typed-tables-example.ts](./examples/typed-tables-example.ts) - TypeScript type safety
779
1466
  - [query-tracking.ts](./examples/query-tracking.ts) - Query tracking with correlation IDs
780
- - [simple-query-tracking.ts](./examples/simple-query-tracking.ts) - Simple tracking example
1467
+ - [query-logging-example.ts](./examples/query-logging-example.ts) - Enhanced query logging
1468
+ - [relationships-example.ts](./examples/relationships-example.ts) - Smart cache invalidation
1469
+ - [singleton-example.ts](./examples/singleton-example.ts) - Singleton pattern
1470
+ - [auto-warming-example.ts](./examples/auto-warming-example.ts) - Auto-warming system
1471
+ - [hooks-example.ts](./examples/hooks-example.ts) - Custom hooks and extensibility
781
1472
 
782
1473
  ## Documentation
783
1474