velocity-python 0.0.134__py3-none-any.whl → 0.0.135__py3-none-any.whl

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.

Potentially problematic release.


This version of velocity-python might be problematic. Click here for more details.

@@ -0,0 +1,644 @@
1
+ import unittest
2
+ import threading
3
+ import time
4
+ from concurrent.futures import ThreadPoolExecutor, as_completed
5
+ from velocity.db.exceptions import (
6
+ DbObjectExistsError, DbTableMissingError, DbColumnMissingError,
7
+ DbSchemaLockedError, DuplicateError
8
+ )
9
+ from velocity.db.core.row import Row
10
+ from velocity.db.core.result import Result
11
+ from .common import CommonPostgresTest, engine, test_db
12
+
13
+
14
+ @engine.transaction
15
+ class TestTableComprehensive(CommonPostgresTest):
16
+ """Comprehensive tests for Table class including edge cases, race conditions, and error recovery."""
17
+
18
+ @classmethod
19
+ def create_test_tables(cls, tx):
20
+ """Create comprehensive test tables for Table testing."""
21
+ # Basic table for general operations
22
+ tx.table("table_test_basic").create(
23
+ columns={
24
+ "name": str,
25
+ "age": int,
26
+ "email": str,
27
+ "active": bool,
28
+ "score": float,
29
+ "data": str,
30
+ }
31
+ )
32
+
33
+ # Table with constraints and indexes
34
+ tx.table("table_test_constraints").create(
35
+ columns={
36
+ "username": str,
37
+ "email": str,
38
+ "created_at": str,
39
+ "status": str,
40
+ }
41
+ )
42
+
43
+ # Create unique indexes for constraint testing
44
+ try:
45
+ tx.table("table_test_constraints").create_index("username", unique=True)
46
+ tx.table("table_test_constraints").create_index("email", unique=True)
47
+ except:
48
+ pass # Index might already exist
49
+
50
+ # Parent table for foreign key testing
51
+ tx.table("table_test_parent").create(
52
+ columns={
53
+ "parent_name": str,
54
+ "category": str,
55
+ "priority": int,
56
+ }
57
+ )
58
+
59
+ # Child table with foreign key
60
+ tx.table("table_test_child").create(
61
+ columns={
62
+ "parent_id": int,
63
+ "child_name": str,
64
+ "value": float,
65
+ "notes": str,
66
+ }
67
+ )
68
+
69
+ # Create foreign key
70
+ tx.table("table_test_child").create_foreign_key("parent_id", "table_test_parent", "sys_id")
71
+
72
+ # Large table for performance testing
73
+ tx.table("table_test_large").create(
74
+ columns={
75
+ "batch_id": int,
76
+ "sequence": int,
77
+ "data_payload": str,
78
+ "processed": bool,
79
+ "timestamp": str,
80
+ }
81
+ )
82
+
83
+ # Table for concurrent access testing
84
+ tx.table("table_test_concurrent").create(
85
+ columns={
86
+ "counter": int,
87
+ "worker_id": str,
88
+ "operation": str,
89
+ "timestamp": str,
90
+ }
91
+ )
92
+
93
+ # Insert initial test data
94
+ cls.insert_test_data(tx)
95
+
96
+ @classmethod
97
+ def insert_test_data(cls, tx):
98
+ """Insert comprehensive test data."""
99
+ # Basic table data
100
+ basic_data = [
101
+ {"name": "Alice Johnson", "age": 30, "email": "alice@test.com", "active": True, "score": 95.5, "data": "user_data_1"},
102
+ {"name": "Bob Smith", "age": 25, "email": "bob@test.com", "active": False, "score": 87.2, "data": "user_data_2"},
103
+ {"name": "Charlie Brown", "age": 35, "email": "charlie@test.com", "active": True, "score": 92.8, "data": "user_data_3"},
104
+ {"name": "Diana Prince", "age": 28, "email": "diana@test.com", "active": True, "score": 88.9, "data": "user_data_4"},
105
+ {"name": "Eve Adams", "age": 32, "email": "eve@test.com", "active": False, "score": 91.1, "data": "user_data_5"},
106
+ ]
107
+
108
+ for data in basic_data:
109
+ tx.table("table_test_basic").insert(data)
110
+
111
+ # Constraints table data
112
+ constraint_data = [
113
+ {"username": "admin", "email": "admin@test.com", "created_at": "2023-01-01", "status": "active"},
114
+ {"username": "user1", "email": "user1@test.com", "created_at": "2023-01-02", "status": "pending"},
115
+ {"username": "user2", "email": "user2@test.com", "created_at": "2023-01-03", "status": "active"},
116
+ ]
117
+
118
+ for data in constraint_data:
119
+ tx.table("table_test_constraints").insert(data)
120
+
121
+ # Parent-child data
122
+ parent_data = [
123
+ {"parent_name": "Project Alpha", "category": "development", "priority": 1},
124
+ {"parent_name": "Project Beta", "category": "testing", "priority": 2},
125
+ {"parent_name": "Project Gamma", "category": "deployment", "priority": 3},
126
+ ]
127
+
128
+ parent_ids = []
129
+ for data in parent_data:
130
+ row = tx.table("table_test_parent").insert(data)
131
+ parent_ids.append(row["sys_id"])
132
+
133
+ child_data = [
134
+ {"parent_id": parent_ids[0], "child_name": "Task A1", "value": 10.5, "notes": "Important task"},
135
+ {"parent_id": parent_ids[0], "child_name": "Task A2", "value": 20.3, "notes": "Secondary task"},
136
+ {"parent_id": parent_ids[1], "child_name": "Task B1", "value": 15.7, "notes": "Testing task"},
137
+ {"parent_id": parent_ids[2], "child_name": "Task C1", "value": 30.9, "notes": "Deployment task"},
138
+ ]
139
+
140
+ for data in child_data:
141
+ tx.table("table_test_child").insert(data)
142
+
143
+ # Large table data (batch insert)
144
+ large_data = []
145
+ for batch in range(10):
146
+ for seq in range(50):
147
+ large_data.append({
148
+ "batch_id": batch,
149
+ "sequence": seq,
150
+ "data_payload": f"batch_{batch}_seq_{seq}_data",
151
+ "processed": seq % 2 == 0,
152
+ "timestamp": f"2023-01-{(seq % 28) + 1:02d}",
153
+ })
154
+
155
+ for data in large_data:
156
+ tx.table("table_test_large").insert(data)
157
+
158
+ def test_table_creation_and_existence(self, tx):
159
+ """Test table creation and existence checking."""
160
+ # Test table exists
161
+ table = tx.table("table_test_basic")
162
+ self.assertTrue(table.exists())
163
+
164
+ # Test non-existent table
165
+ non_existent = tx.table("non_existent_table")
166
+ self.assertFalse(non_existent.exists())
167
+
168
+ # Test creating new table
169
+ new_table = tx.table("table_test_new")
170
+ self.assertFalse(new_table.exists())
171
+ new_table.create(columns={"test_col": str, "test_num": int})
172
+ self.assertTrue(new_table.exists())
173
+
174
+ def test_table_string_representation(self, tx):
175
+ """Test table string representation."""
176
+ table = tx.table("table_test_basic")
177
+ str_repr = str(table)
178
+
179
+ self.assertIn("Table: table_test_basic", str_repr)
180
+ self.assertIn("(table exists) True", str_repr)
181
+ self.assertIn("Columns:", str_repr)
182
+ self.assertIn("Rows:", str_repr)
183
+
184
+ def test_table_column_operations(self, tx):
185
+ """Test table column operations."""
186
+ table = tx.table("table_test_basic")
187
+
188
+ # Test getting columns
189
+ columns = table.columns()
190
+ self.assertIn("name", columns)
191
+ self.assertIn("age", columns)
192
+ self.assertIn("email", columns)
193
+
194
+ # Test system columns
195
+ sys_columns = table.sys_columns()
196
+ self.assertIn("sys_id", sys_columns)
197
+ self.assertIn("sys_created_by", sys_columns)
198
+ self.assertIn("sys_created_on", sys_columns)
199
+
200
+ # Test column filtering (non-sys columns)
201
+ filtered_columns = table.columns()
202
+ sys_column_count = len([col for col in filtered_columns if col.startswith("sys_")])
203
+ self.assertEqual(sys_column_count, 0)
204
+
205
+ def test_table_row_count(self, tx):
206
+ """Test table row counting."""
207
+ table = tx.table("table_test_basic")
208
+
209
+ # Test len() method
210
+ count = len(table)
211
+ self.assertEqual(count, 5) # We inserted 5 rows
212
+
213
+ # Test count() method
214
+ count_method = table.count()
215
+ self.assertEqual(count_method, 5)
216
+
217
+ # Test count with condition
218
+ count_active = table.count({"active": True})
219
+ self.assertEqual(count_active, 3) # 3 active users
220
+
221
+ def test_table_iteration(self, tx):
222
+ """Test table iteration."""
223
+ table = tx.table("table_test_basic")
224
+
225
+ # Test basic iteration
226
+ rows = list(table)
227
+ self.assertEqual(len(rows), 5)
228
+
229
+ # Test that rows are Row objects
230
+ for row in rows:
231
+ self.assertIsInstance(row, Row)
232
+
233
+ # Test iteration with callable syntax
234
+ active_rows = list(table(where={"active": True}))
235
+ self.assertEqual(len(active_rows), 3)
236
+
237
+ def test_table_insert_operations(self, tx):
238
+ """Test table insert operations including edge cases."""
239
+ table = tx.table("table_test_basic")
240
+
241
+ # Test basic insert
242
+ data = {"name": "Test User", "age": 40, "email": "test@test.com", "active": True, "score": 85.0}
243
+ row = table.insert(data)
244
+ self.assertIsInstance(row, Row)
245
+ self.assertEqual(row["name"], "Test User")
246
+
247
+ # Test insert with None values
248
+ data_with_none = {"name": "User With None", "age": None, "email": "none@test.com"}
249
+ row_none = table.insert(data_with_none)
250
+ self.assertIsNone(row_none["age"])
251
+
252
+ # Test insert with missing columns (should work with auto-creation)
253
+ data_partial = {"name": "Partial User", "age": 25}
254
+ row_partial = table.insert(data_partial)
255
+ self.assertEqual(row_partial["name"], "Partial User")
256
+
257
+ # Test insert with extra columns (should auto-create)
258
+ data_extra = {"name": "Extra User", "age": 25, "new_column": "new_value"}
259
+ row_extra = table.insert(data_extra)
260
+ self.assertEqual(row_extra["new_column"], "new_value")
261
+
262
+ def test_table_update_operations(self, tx):
263
+ """Test table update operations."""
264
+ table = tx.table("table_test_basic")
265
+
266
+ # Get a row to update
267
+ row = table.select().first()
268
+ original_name = row["name"]
269
+ row_id = row["sys_id"]
270
+
271
+ # Test basic update
272
+ table.update({"name": "Updated Name"}, {"sys_id": row_id})
273
+ updated_row = table.find(row_id)
274
+ self.assertEqual(updated_row["name"], "Updated Name")
275
+
276
+ # Test bulk update
277
+ affected = table.update({"active": False}, {"active": True})
278
+ self.assertGreaterEqual(affected, 0)
279
+
280
+ # Test update with complex where clause
281
+ table.update({"score": 100.0}, {"age__gte": 30, "active": False})
282
+
283
+ def test_table_delete_operations(self, tx):
284
+ """Test table delete operations."""
285
+ table = tx.table("table_test_basic")
286
+
287
+ initial_count = table.count()
288
+
289
+ # Test delete with specific condition
290
+ deleted = table.delete({"name": "Updated Name"})
291
+ self.assertGreaterEqual(deleted, 0)
292
+
293
+ # Test bulk delete
294
+ deleted_bulk = table.delete({"active": False})
295
+ self.assertGreaterEqual(deleted_bulk, 0)
296
+
297
+ # Verify count changed
298
+ final_count = table.count()
299
+ self.assertLess(final_count, initial_count)
300
+
301
+ def test_table_select_operations(self, tx):
302
+ """Test table select operations with various conditions."""
303
+ table = tx.table("table_test_basic")
304
+
305
+ # Test select all
306
+ result = table.select()
307
+ self.assertIsInstance(result, Result)
308
+
309
+ # Test select with where clause
310
+ result_where = table.select(where={"active": True})
311
+ active_count = len(list(result_where))
312
+ self.assertGreaterEqual(active_count, 0)
313
+
314
+ # Test select with order by
315
+ result_ordered = table.select(orderby="name")
316
+ ordered_list = list(result_ordered)
317
+ self.assertGreaterEqual(len(ordered_list), 0)
318
+
319
+ # Test select with limit
320
+ result_limited = table.select(limit=2)
321
+ limited_list = list(result_limited)
322
+ self.assertLessEqual(len(limited_list), 2)
323
+
324
+ # Test select with complex conditions
325
+ result_complex = table.select(where={"age__gte": 25, "active": True}, orderby="-score", limit=3)
326
+ complex_list = list(result_complex)
327
+ self.assertLessEqual(len(complex_list), 3)
328
+
329
+ def test_table_upsert_operations(self, tx):
330
+ """Test table upsert operations."""
331
+ table = tx.table("table_test_basic")
332
+
333
+ # Test upsert (insert new)
334
+ new_data = {"name": "Upsert User", "age": 45, "email": "upsert@test.com"}
335
+ row = table.upsert(new_data)
336
+ self.assertEqual(row["name"], "Upsert User")
337
+
338
+ # Test upsert (update existing)
339
+ existing_data = {"name": "Upsert User Updated", "age": 46}
340
+ where_clause = {"email": "upsert@test.com"}
341
+ row_updated = table.upsert(existing_data, where_clause)
342
+ self.assertEqual(row_updated["name"], "Upsert User Updated")
343
+ self.assertEqual(row_updated["age"], 46)
344
+
345
+ def test_table_find_operations(self, tx):
346
+ """Test table find operations."""
347
+ table = tx.table("table_test_basic")
348
+
349
+ # Test find by sys_id
350
+ first_row = table.select().first()
351
+ found_row = table.find(first_row["sys_id"])
352
+ self.assertEqual(found_row["sys_id"], first_row["sys_id"])
353
+
354
+ # Test find with dictionary conditions
355
+ found_by_name = table.find({"name": first_row["name"]})
356
+ self.assertEqual(found_by_name["name"], first_row["name"])
357
+
358
+ # Test find non-existent
359
+ non_existent = table.find(99999999)
360
+ self.assertIsNone(non_existent)
361
+
362
+ def test_table_get_value_operations(self, tx):
363
+ """Test table get_value operations."""
364
+ table = tx.table("table_test_basic")
365
+
366
+ # Get a known row
367
+ row = table.select().first()
368
+ row_id = row["sys_id"]
369
+
370
+ # Test get_value
371
+ name_value = table.get_value("name", {"sys_id": row_id})
372
+ self.assertEqual(name_value, row["name"])
373
+
374
+ # Test get_value with non-existent column
375
+ with self.assertRaises((DbColumnMissingError, Exception)):
376
+ table.get_value("non_existent_column", {"sys_id": row_id})
377
+
378
+ def test_table_constraint_violations(self, tx):
379
+ """Test handling of constraint violations."""
380
+ table = tx.table("table_test_constraints")
381
+
382
+ # Test unique constraint violation
383
+ try:
384
+ # Try to insert duplicate username
385
+ table.insert({"username": "admin", "email": "admin2@test.com"})
386
+ except (DuplicateError, Exception):
387
+ pass # Expected to fail
388
+
389
+ # Test foreign key constraint
390
+ child_table = tx.table("table_test_child")
391
+ try:
392
+ # Try to insert with non-existent parent_id
393
+ child_table.insert({"parent_id": 99999, "child_name": "Orphan Task"})
394
+ except Exception:
395
+ pass # Expected to fail
396
+
397
+ def test_table_transaction_rollback(self, tx):
398
+ """Test table operations with transaction rollback."""
399
+ table = tx.table("table_test_basic")
400
+
401
+ initial_count = table.count()
402
+
403
+ # Insert some data
404
+ table.insert({"name": "Rollback Test", "age": 99})
405
+
406
+ # Verify the insert
407
+ after_insert_count = table.count()
408
+ self.assertEqual(after_insert_count, initial_count + 1)
409
+
410
+ # Rollback (this will happen automatically at end of test due to transaction decorator)
411
+ # The rollback behavior is tested by the framework itself
412
+
413
+ def test_table_concurrent_access(self, tx):
414
+ """Test table operations under concurrent access."""
415
+ table = tx.table("table_test_concurrent")
416
+
417
+ # Clear any existing data
418
+ table.delete({})
419
+
420
+ def worker(worker_id, operations=10):
421
+ """Worker function for concurrent testing."""
422
+ results = []
423
+ for i in range(operations):
424
+ try:
425
+ # Insert operation
426
+ row = table.insert({
427
+ "counter": i,
428
+ "worker_id": f"worker_{worker_id}",
429
+ "operation": "insert",
430
+ "timestamp": f"2023-01-01T{i:02d}:00:00"
431
+ })
432
+ results.append(("insert", row["sys_id"]))
433
+
434
+ # Update operation
435
+ table.update(
436
+ {"operation": "updated"},
437
+ {"sys_id": row["sys_id"]}
438
+ )
439
+ results.append(("update", row["sys_id"]))
440
+
441
+ time.sleep(0.001) # Small delay to encourage race conditions
442
+
443
+ except Exception as e:
444
+ results.append(("error", str(e)))
445
+
446
+ return results
447
+
448
+ # Run concurrent workers
449
+ with ThreadPoolExecutor(max_workers=3) as executor:
450
+ futures = [executor.submit(worker, i, 5) for i in range(3)]
451
+ all_results = []
452
+ for future in as_completed(futures):
453
+ all_results.extend(future.result())
454
+
455
+ # Verify operations completed
456
+ self.assertGreater(len(all_results), 0)
457
+
458
+ # Check final state
459
+ final_count = table.count()
460
+ self.assertGreaterEqual(final_count, 0)
461
+
462
+ def test_table_large_dataset_performance(self, tx):
463
+ """Test table operations with large datasets."""
464
+ table = tx.table("table_test_large")
465
+
466
+ # Test count on large table
467
+ count = table.count()
468
+ self.assertEqual(count, 500) # 10 batches * 50 sequences
469
+
470
+ # Test filtered queries on large table
471
+ batch_0_count = table.count({"batch_id": 0})
472
+ self.assertEqual(batch_0_count, 50)
473
+
474
+ # Test complex query
475
+ complex_result = table.select(
476
+ where={"batch_id__gte": 5, "processed": True},
477
+ orderby="sequence",
478
+ limit=10
479
+ )
480
+ complex_list = list(complex_result)
481
+ self.assertLessEqual(len(complex_list), 10)
482
+
483
+ # Test bulk operations
484
+ affected = table.update(
485
+ {"processed": True},
486
+ {"batch_id__in": [1, 2, 3]}
487
+ )
488
+ self.assertGreaterEqual(affected, 0)
489
+
490
+ def test_table_edge_cases_empty_operations(self, tx):
491
+ """Test edge cases with empty operations."""
492
+ table = tx.table("table_test_basic")
493
+
494
+ # Test select with empty where clause
495
+ result = table.select(where={})
496
+ self.assertIsInstance(result, Result)
497
+
498
+ # Test update with empty data (should be handled gracefully)
499
+ try:
500
+ table.update({}, {"sys_id": 1})
501
+ except Exception:
502
+ pass # May legitimately fail
503
+
504
+ # Test delete with empty where (dangerous but should work)
505
+ # Don't actually run this as it would delete all data
506
+ # table.delete({})
507
+
508
+ def test_table_edge_cases_null_and_unicode(self, tx):
509
+ """Test edge cases with NULL and Unicode data."""
510
+ table = tx.table("table_test_basic")
511
+
512
+ # Test with Unicode data
513
+ unicode_data = {
514
+ "name": "José María 🚀",
515
+ "email": "josé@español.com",
516
+ "data": "Unicode test: αβγδε"
517
+ }
518
+ row = table.insert(unicode_data)
519
+ self.assertEqual(row["name"], "José María 🚀")
520
+
521
+ # Test with NULL values
522
+ null_data = {
523
+ "name": "NULL Test User",
524
+ "age": None,
525
+ "email": None,
526
+ "active": None,
527
+ "score": None
528
+ }
529
+ row_null = table.insert(null_data)
530
+ self.assertEqual(row_null["name"], "NULL Test User")
531
+ self.assertIsNone(row_null["age"])
532
+
533
+ def test_table_data_type_edge_cases(self, tx):
534
+ """Test edge cases with different data types."""
535
+ table = tx.table("table_test_basic")
536
+
537
+ # Test with extreme values
538
+ extreme_data = {
539
+ "name": "Extreme User",
540
+ "age": 999999999, # Very large integer
541
+ "score": 999999.999999, # Large float
542
+ "active": True,
543
+ "data": "x" * 1000 # Long string
544
+ }
545
+ row = table.insert(extreme_data)
546
+ self.assertEqual(row["name"], "Extreme User")
547
+
548
+ # Test with minimum values
549
+ min_data = {
550
+ "name": "", # Empty string
551
+ "age": 0,
552
+ "score": 0.0,
553
+ "active": False
554
+ }
555
+ row_min = table.insert(min_data)
556
+ self.assertEqual(row_min["age"], 0)
557
+
558
+ def test_table_error_recovery(self, tx):
559
+ """Test table error recovery scenarios."""
560
+ table = tx.table("table_test_basic")
561
+
562
+ # Test recovery from constraint violation
563
+ try:
564
+ # Insert with very long email that might exceed column limit
565
+ table.insert({
566
+ "name": "Long Email User",
567
+ "email": "very" + "long" * 100 + "@example.com"
568
+ })
569
+ except Exception:
570
+ # Should be able to continue after error
571
+ row = table.insert({
572
+ "name": "Recovery User",
573
+ "email": "recovery@test.com"
574
+ })
575
+ self.assertEqual(row["name"], "Recovery User")
576
+
577
+ # Test recovery from invalid column reference
578
+ try:
579
+ table.select(where={"invalid_column": "value"})
580
+ except Exception:
581
+ # Should be able to continue
582
+ result = table.select(where={"name": "Recovery User"})
583
+ self.assertIsInstance(result, Result)
584
+
585
+ def test_table_context_manager(self, tx):
586
+ """Test table as context manager."""
587
+ # Test with context manager
588
+ with tx.table("table_test_basic") as table:
589
+ count = table.count()
590
+ self.assertGreaterEqual(count, 0)
591
+
592
+ # Table should be properly closed after context
593
+
594
+ def test_table_drop_and_recreate(self, tx):
595
+ """Test dropping and recreating tables."""
596
+ # Create temporary table
597
+ temp_table = tx.table("table_test_temp")
598
+ temp_table.create(columns={"temp_col": str})
599
+ self.assertTrue(temp_table.exists())
600
+
601
+ # Drop table
602
+ temp_table.drop()
603
+ self.assertFalse(temp_table.exists())
604
+
605
+ # Recreate with different schema
606
+ temp_table.create(columns={"temp_col": str, "new_col": int})
607
+ self.assertTrue(temp_table.exists())
608
+
609
+ # Verify new schema
610
+ columns = temp_table.columns()
611
+ self.assertIn("temp_col", columns)
612
+ self.assertIn("new_col", columns)
613
+
614
+ def test_table_index_operations(self, tx):
615
+ """Test table index operations."""
616
+ table = tx.table("table_test_basic")
617
+
618
+ # Create index
619
+ try:
620
+ table.create_index("name")
621
+ table.create_index("email", unique=True)
622
+ except Exception:
623
+ pass # Index might already exist
624
+
625
+ # Test that operations still work with indexes
626
+ result = table.select(where={"name": "Alice Johnson"})
627
+ self.assertIsInstance(result, Result)
628
+
629
+ def test_table_query_builder(self, tx):
630
+ """Test table query builder functionality."""
631
+ table = tx.table("table_test_basic")
632
+
633
+ # Test that query building doesn't execute immediately
634
+ query = table.select(where={"active": True}, orderby="name")
635
+ self.assertIsInstance(query, Result)
636
+
637
+ # Test chaining operations
638
+ result = table.select(where={"age__gte": 25}).orderby("score").limit(3)
639
+ result_list = list(result)
640
+ self.assertLessEqual(len(result_list), 3)
641
+
642
+
643
+ if __name__ == "__main__":
644
+ unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.0.134
3
+ Version: 0.0.135
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -1,4 +1,4 @@
1
- velocity/__init__.py,sha256=PHstfJh2GLHPBIbDIMy3wUshp4rvBakQ_JP037OoLb8,147
1
+ velocity/__init__.py,sha256=TaShBCBTfQsN28lDWrO3qye4k4Dg4XpwqKR7yDNnH6A,147
2
2
  velocity/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  velocity/app/invoices.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  velocity/app/orders.py,sha256=fr1oTBjSFfyeMBUXRG06LV4jgwrlwYNL5mbEBleFwf0,6328
@@ -89,10 +89,13 @@ velocity/db/tests/postgres/test_general_usage.py,sha256=dCoCv8gJJafh9kN1-hK8mw47
89
89
  velocity/db/tests/postgres/test_imports.py,sha256=1_Er9T96N3KcUtu_yPdlwU7ywImrHCGvXzgHNgMkBfE,199
90
90
  velocity/db/tests/postgres/test_result.py,sha256=zxQjy16fFhfBl5YK8XnReviqUM4Rmr2AWXptAc4QdlA,464
91
91
  velocity/db/tests/postgres/test_row.py,sha256=F5UfxOuI9fzu2fxp3UnBYqeg2GHYYTNc5fv-G13bFrA,4521
92
+ velocity/db/tests/postgres/test_row_comprehensive.py,sha256=KdTbD6BYwwxe9-Os9cWzQG_ECZ-RDdU288Olbr80_L4,24421
92
93
  velocity/db/tests/postgres/test_schema_locking.py,sha256=_wH9XIX8GBhdIFLNiAKmZD2ArLTU_j0XIjN8erif55k,12697
93
94
  velocity/db/tests/postgres/test_schema_locking_unit.py,sha256=5Ifa7BEiR1zJwttuuV4Xue65VQJ-c3ueALw5REfqGls,3850
94
95
  velocity/db/tests/postgres/test_sequence.py,sha256=UoI4x2z8RvucuvZk4Tf1Ue_obtRHt0QCX0ae87iQ7mY,672
96
+ velocity/db/tests/postgres/test_sql_comprehensive.py,sha256=hRBaP7skRxxxjFJnMr0YAiyzNalD8HTGwDgUGntRsJw,18921
95
97
  velocity/db/tests/postgres/test_table.py,sha256=D55TpJl0fh8b9Q-ijS3Cj6BeXrS_XQs8qfJFu3G2WL8,2306
98
+ velocity/db/tests/postgres/test_table_comprehensive.py,sha256=Mqa_YDcPb4VYkAAMiu15rfgvZZVkPL9MK8wu1IHqhp4,24064
96
99
  velocity/db/tests/postgres/test_transaction.py,sha256=Hek8rXmz7Cuz1-Fmmgq7eyhMG9GYKkCKpUUMx5prnjc,2406
97
100
  velocity/db/tests/sql/__init__.py,sha256=evafiIjAB0jyhqZ8HfiPgRujXJkRpQ7a34Bjac4qyv8,12
98
101
  velocity/db/tests/sql/common.py,sha256=bXRob_RcZoonjCcwY712muraqGiW6HRMSpz5OOtixUM,5811
@@ -118,8 +121,8 @@ velocity/misc/tests/test_merge.py,sha256=Vm5_jY5cVczw0hZF-3TYzmxFw81heJOJB-dvhCg
118
121
  velocity/misc/tests/test_oconv.py,sha256=fy4DwWGn_v486r2d_3ACpuBD-K1oOngNq1HJCGH7X-M,4694
119
122
  velocity/misc/tests/test_original_error.py,sha256=iWSd18tckOA54LoPQOGV5j9LAz2W-3_ZOwmyZ8-4YQc,1742
120
123
  velocity/misc/tests/test_timer.py,sha256=l9nrF84kHaFofvQYKInJmfoqC01wBhsUB18lVBgXCoo,2758
121
- velocity_python-0.0.134.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
122
- velocity_python-0.0.134.dist-info/METADATA,sha256=P7Im0GNay1U7Vsbh9j91LKTWFKe7709t8lTbSp6vBH4,34262
123
- velocity_python-0.0.134.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
- velocity_python-0.0.134.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
125
- velocity_python-0.0.134.dist-info/RECORD,,
124
+ velocity_python-0.0.135.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
125
+ velocity_python-0.0.135.dist-info/METADATA,sha256=8a1y-3K5G_40sWs3SMMy8zl3XBlqpfSvYnMd4ok4ltY,34262
126
+ velocity_python-0.0.135.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
127
+ velocity_python-0.0.135.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
128
+ velocity_python-0.0.135.dist-info/RECORD,,