@starbemtech/star-db-query-builder 1.1.0 → 1.2.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 (88) hide show
  1. package/.github/workflows/publish.yml +118 -0
  2. package/ARCHITECTURE.md +313 -0
  3. package/CHANGELOG.md +65 -0
  4. package/README.md +1275 -210
  5. package/coverage/base.css +224 -0
  6. package/coverage/block-navigation.js +87 -0
  7. package/coverage/favicon.png +0 -0
  8. package/coverage/index.html +131 -0
  9. package/coverage/lcov-report/base.css +224 -0
  10. package/coverage/lcov-report/block-navigation.js +87 -0
  11. package/coverage/lcov-report/favicon.png +0 -0
  12. package/coverage/lcov-report/index.html +131 -0
  13. package/coverage/lcov-report/mysqlClient.ts.html +685 -0
  14. package/coverage/lcov-report/pgClient.ts.html +823 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +210 -0
  19. package/coverage/lcov.info +533 -0
  20. package/coverage/mysqlClient.ts.html +685 -0
  21. package/coverage/pgClient.ts.html +823 -0
  22. package/coverage/prettify.css +1 -0
  23. package/coverage/prettify.js +2 -0
  24. package/coverage/sort-arrow-sprite.png +0 -0
  25. package/coverage/sorter.js +210 -0
  26. package/dist/index.d.ts +5 -4
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/src/core/repository.d.ts +374 -0
  30. package/dist/src/core/repository.js +677 -0
  31. package/dist/src/core/repository.js.map +1 -0
  32. package/dist/src/{default → core}/types.d.ts +9 -1
  33. package/dist/src/{default → core}/types.js.map +1 -1
  34. package/dist/src/core/utils.d.ts +133 -0
  35. package/dist/src/{default → core}/utils.js +167 -0
  36. package/dist/src/core/utils.js.map +1 -0
  37. package/dist/src/db/IDatabaseClient.d.ts +10 -1
  38. package/dist/src/db/initDb.d.ts +120 -1
  39. package/dist/src/db/initDb.js +119 -0
  40. package/dist/src/db/initDb.js.map +1 -1
  41. package/dist/src/db/mysqlClient.d.ts +23 -1
  42. package/dist/src/db/mysqlClient.js +115 -0
  43. package/dist/src/db/mysqlClient.js.map +1 -1
  44. package/dist/src/db/pgClient.d.ts +22 -1
  45. package/dist/src/db/pgClient.js +127 -0
  46. package/dist/src/db/pgClient.js.map +1 -1
  47. package/dist/src/monitor/monitor.d.ts +6 -1
  48. package/dist/src/monitor/monitor.js +5 -0
  49. package/dist/src/monitor/monitor.js.map +1 -1
  50. package/dist/src/setupTests.d.ts +26 -0
  51. package/dist/src/setupTests.js +43 -0
  52. package/dist/src/setupTests.js.map +1 -0
  53. package/docs/INDEX.md +145 -0
  54. package/docs/methods/findFirst.md +394 -0
  55. package/docs/methods/findMany.md +587 -0
  56. package/docs/methods/insert.md +536 -0
  57. package/docs/methods/insertMany.md +627 -0
  58. package/docs/methods/joins.md +781 -0
  59. package/docs/methods/rawQuery.md +284 -0
  60. package/docs/methods/transactions.md +737 -0
  61. package/eslint.config.mjs +77 -0
  62. package/index.ts +5 -4
  63. package/jest.config.ts +23 -28
  64. package/package.json +52 -29
  65. package/scripts/release.sh +123 -0
  66. package/src/core/repository.ts +865 -0
  67. package/src/{default → core}/types.ts +11 -2
  68. package/src/{default → core}/utils.ts +168 -0
  69. package/src/db/IDatabaseClient.ts +11 -1
  70. package/src/db/__tests__/mysqlClient.test.ts +262 -0
  71. package/src/db/__tests__/pgClient.test.ts +260 -0
  72. package/src/db/initDb.ts +120 -1
  73. package/src/db/mysqlClient.ts +119 -3
  74. package/src/db/pgClient.ts +131 -3
  75. package/src/monitor/monitor.ts +5 -0
  76. package/src/setupTests.ts +45 -0
  77. package/tsconfig.test.json +21 -0
  78. package/.eslintignore +0 -4
  79. package/.eslintrc.json +0 -32
  80. package/dist/.eslintrc.json +0 -32
  81. package/dist/src/default/genericRepository.d.ts +0 -28
  82. package/dist/src/default/genericRepository.js +0 -284
  83. package/dist/src/default/genericRepository.js.map +0 -1
  84. package/dist/src/default/utils.d.ts +0 -9
  85. package/dist/src/default/utils.js.map +0 -1
  86. package/index.d.ts +0 -60
  87. package/src/default/genericRepository.ts +0 -461
  88. /package/dist/src/{default → core}/types.js +0 -0
@@ -0,0 +1,284 @@
1
+ # Raw Query - Usage Examples
2
+
3
+ The `rawQuery` method allows you to execute pure SQL queries directly on the database, offering maximum flexibility for complex cases that cannot be resolved with the standard generic repository methods.
4
+
5
+ ## Import
6
+
7
+ ```typescript
8
+ import { rawQuery } from 'star-db-query-builder'
9
+ ```
10
+
11
+ ## Method Signature
12
+
13
+ ```typescript
14
+ rawQuery<T = any>({
15
+ dbClient: IDatabaseClient,
16
+ sql: string,
17
+ params?: any[]
18
+ }): Promise<T>
19
+ ```
20
+
21
+ ## Usage Examples
22
+
23
+ ### 1. Simple Query without Parameters
24
+
25
+ ```typescript
26
+ // Find all active users
27
+ const activeUsers = await rawQuery({
28
+ dbClient,
29
+ sql: 'SELECT * FROM users WHERE active = true',
30
+ })
31
+ ```
32
+
33
+ ### 2. Query with Parameters
34
+
35
+ ```typescript
36
+ // Find specific user
37
+ const user = await rawQuery({
38
+ dbClient,
39
+ sql: 'SELECT * FROM users WHERE id = ? AND email = ?',
40
+ params: ['user-123', 'user@example.com'],
41
+ })
42
+ ```
43
+
44
+ ### 3. Aggregation Queries
45
+
46
+ ```typescript
47
+ // User statistics
48
+ const stats = await rawQuery({
49
+ dbClient,
50
+ sql: `
51
+ SELECT
52
+ COUNT(*) as total_users,
53
+ AVG(age) as avg_age,
54
+ MIN(created_at) as first_user,
55
+ MAX(created_at) as last_user
56
+ FROM users
57
+ WHERE created_at >= ?
58
+ `,
59
+ params: [new Date('2023-01-01')],
60
+ })
61
+ ```
62
+
63
+ ### 4. Queries with Complex JOINs
64
+
65
+ ```typescript
66
+ // Complex report with multiple JOINs
67
+ const report = await rawQuery({
68
+ dbClient,
69
+ sql: `
70
+ SELECT
71
+ u.name,
72
+ u.email,
73
+ COUNT(o.id) as total_orders,
74
+ SUM(o.total) as total_spent,
75
+ p.name as plan_name
76
+ FROM users u
77
+ LEFT JOIN orders o ON u.id = o.user_id
78
+ LEFT JOIN user_plans up ON u.id = up.user_id
79
+ LEFT JOIN plans p ON up.plan_id = p.id
80
+ WHERE u.created_at >= ?
81
+ GROUP BY u.id, u.name, u.email, p.name
82
+ HAVING COUNT(o.id) > ?
83
+ ORDER BY total_spent DESC
84
+ `,
85
+ params: [new Date('2023-01-01'), 5],
86
+ })
87
+ ```
88
+
89
+ ### 5. Queries with Subqueries
90
+
91
+ ```typescript
92
+ // Users with more orders than average
93
+ const topUsers = await rawQuery({
94
+ dbClient,
95
+ sql: `
96
+ SELECT
97
+ u.*,
98
+ COUNT(o.id) as order_count
99
+ FROM users u
100
+ INNER JOIN orders o ON u.id = o.user_id
101
+ GROUP BY u.id
102
+ HAVING COUNT(o.id) > (
103
+ SELECT AVG(order_count)
104
+ FROM (
105
+ SELECT COUNT(*) as order_count
106
+ FROM orders
107
+ GROUP BY user_id
108
+ ) as avg_orders
109
+ )
110
+ `,
111
+ })
112
+ ```
113
+
114
+ ### 6. Queries with Window Functions
115
+
116
+ ```typescript
117
+ // User ranking by spending
118
+ const userRanking = await rawQuery({
119
+ dbClient,
120
+ sql: `
121
+ SELECT
122
+ u.name,
123
+ u.email,
124
+ SUM(o.total) as total_spent,
125
+ ROW_NUMBER() OVER (ORDER BY SUM(o.total) DESC) as rank,
126
+ PERCENT_RANK() OVER (ORDER BY SUM(o.total) DESC) as percentile
127
+ FROM users u
128
+ INNER JOIN orders o ON u.id = o.user_id
129
+ WHERE o.created_at >= ?
130
+ GROUP BY u.id, u.name, u.email
131
+ ORDER BY total_spent DESC
132
+ `,
133
+ params: [new Date('2023-01-01')],
134
+ })
135
+ ```
136
+
137
+ ### 7. Queries with CTEs (Common Table Expressions)
138
+
139
+ ```typescript
140
+ // Monthly growth analysis
141
+ const monthlyGrowth = await rawQuery({
142
+ dbClient,
143
+ sql: `
144
+ WITH monthly_stats AS (
145
+ SELECT
146
+ DATE_TRUNC('month', created_at) as month,
147
+ COUNT(*) as new_users,
148
+ SUM(total) as revenue
149
+ FROM users u
150
+ LEFT JOIN orders o ON u.id = o.user_id
151
+ WHERE u.created_at >= ?
152
+ GROUP BY DATE_TRUNC('month', created_at)
153
+ ),
154
+ growth_calc AS (
155
+ SELECT
156
+ month,
157
+ new_users,
158
+ revenue,
159
+ LAG(new_users) OVER (ORDER BY month) as prev_users,
160
+ LAG(revenue) OVER (ORDER BY month) as prev_revenue
161
+ FROM monthly_stats
162
+ )
163
+ SELECT
164
+ month,
165
+ new_users,
166
+ revenue,
167
+ CASE
168
+ WHEN prev_users > 0
169
+ THEN ROUND(((new_users - prev_users)::float / prev_users) * 100, 2)
170
+ ELSE 0
171
+ END as user_growth_percent,
172
+ CASE
173
+ WHEN prev_revenue > 0
174
+ THEN ROUND(((revenue - prev_revenue)::float / prev_revenue) * 100, 2)
175
+ ELSE 0
176
+ END as revenue_growth_percent
177
+ FROM growth_calc
178
+ ORDER BY month
179
+ `,
180
+ params: [new Date('2023-01-01')],
181
+ })
182
+ ```
183
+
184
+ ### 8. Batch Update Queries
185
+
186
+ ```typescript
187
+ // Update status of multiple records
188
+ const updateResult = await rawQuery({
189
+ dbClient,
190
+ sql: `
191
+ UPDATE users
192
+ SET
193
+ last_login = ?,
194
+ login_count = login_count + 1,
195
+ updated_at = ?
196
+ WHERE id IN (${userIds.map(() => '?').join(',')})
197
+ `,
198
+ params: [new Date(), new Date(), ...userIds],
199
+ })
200
+ ```
201
+
202
+ ### 9. Queries with TypeScript Typing
203
+
204
+ ```typescript
205
+ // Define interface for the result
206
+ interface UserStats {
207
+ total_users: number
208
+ active_users: number
209
+ avg_age: number
210
+ last_created: Date
211
+ }
212
+
213
+ // Typed query
214
+ const stats: UserStats = await rawQuery<UserStats>({
215
+ dbClient,
216
+ sql: `
217
+ SELECT
218
+ COUNT(*) as total_users,
219
+ COUNT(CASE WHEN active = true THEN 1 END) as active_users,
220
+ AVG(age) as avg_age,
221
+ MAX(created_at) as last_created
222
+ FROM users
223
+ `,
224
+ })
225
+ ```
226
+
227
+ ### 10. Error Handling
228
+
229
+ ```typescript
230
+ try {
231
+ const result = await rawQuery({
232
+ dbClient,
233
+ sql: 'SELECT * FROM non_existent_table',
234
+ })
235
+ } catch (error) {
236
+ console.error('Query error:', error.message)
237
+ // The error will be: "Raw query execution failed: [database message]"
238
+ }
239
+ ```
240
+
241
+ ## Important Considerations
242
+
243
+ ### Security
244
+
245
+ - **ALWAYS** use prepared parameters to avoid SQL injection
246
+ - Validate and sanitize data before using in queries
247
+ - Avoid concatenating strings directly in SQL
248
+
249
+ ### Performance
250
+
251
+ - Use `rawQuery` only when necessary
252
+ - Consider using appropriate indexes for complex queries
253
+ - Monitor the performance of raw queries
254
+
255
+ ### Compatibility
256
+
257
+ - The method works with PostgreSQL and MySQL
258
+ - Database-specific syntax (like `DATE_TRUNC` in PostgreSQL) may not work in other DBMS
259
+ - Test queries in different environments
260
+
261
+ ### Limitations
262
+
263
+ - No automatic type validation
264
+ - No automatic query caching
265
+ - No automatic retry on failure
266
+ - No automatic query logging
267
+
268
+ ## Recommended Use Cases
269
+
270
+ ✅ **Use `rawQuery` when:**
271
+
272
+ - You need very complex queries with multiple JOINs
273
+ - You want to use database-specific functions (window functions, CTEs, etc.)
274
+ - You need maximum performance for critical queries
275
+ - You want to do complex aggregation queries
276
+ - You need queries that don't fit the CRUD pattern
277
+
278
+ ❌ **Avoid `rawQuery` when:**
279
+
280
+ - You can use the standard repository methods
281
+ - The query is simple (basic SELECT, INSERT, UPDATE, DELETE)
282
+ - You need automatic type validation
283
+ - You want to take advantage of automatic caching
284
+ - The query can be reused across different DBMS