activeitem 0.0.15 → 0.0.16
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.
- checksums.yaml +4 -4
- data/lib/active_item/relation.rb +57 -6
- data/lib/active_item/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6460db8a74ca7bcb5d28c0bfdb7c4a6c1eba5c5d68318245612dad78d1d1d282
|
|
4
|
+
data.tar.gz: 9fe2d9707efa0a41b74fa1c07c5c24453605baa5d24e3f1880c248c92c5a03b0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61ad96dc3dd1a28bda5a9af288bd17e1eef4f11b450f08efae26c1ea8f8060819727dde8d855d562e0fbbf2e6012096e159952d44c0d22255abc2384d85d80a9
|
|
7
|
+
data.tar.gz: 741d0e3a257199f62373c16960bea2d90fe26e37e9f4dcb8516cfb049170caac8a237c90ef1ba17dde88b356218b12f7e5e7d5f4a9d96abee7f64225639762f8
|
data/lib/active_item/relation.rb
CHANGED
|
@@ -547,7 +547,8 @@ module ActiveItem
|
|
|
547
547
|
if effective_index && normalized_conditions.any? && normalized_conditions.values.first.is_a?(Array)
|
|
548
548
|
index_config = resolved_model.indexes[effective_index] || {}
|
|
549
549
|
ruby_partition_key = normalized_conditions.keys.first.to_s
|
|
550
|
-
|
|
550
|
+
raw_pk = index_config[:partition_key]&.to_s || ruby_partition_key
|
|
551
|
+
dynamo_partition_key = resolved_model.to_dynamo_key(raw_pk)
|
|
551
552
|
return fanout_paginated_query(effective_index, normalized_conditions, index_config, dynamo_partition_key,
|
|
552
553
|
normalized_conditions.values.first, cursor, per_page)
|
|
553
554
|
end
|
|
@@ -559,6 +560,12 @@ module ActiveItem
|
|
|
559
560
|
else
|
|
560
561
|
paginated_scan_with_conditions(normalized_conditions, exclusive_start_key, per_page)
|
|
561
562
|
end
|
|
563
|
+
rescue Aws::DynamoDB::Errors::ValidationException => e
|
|
564
|
+
raise unless e.message.include?('specified index')
|
|
565
|
+
|
|
566
|
+
warn "[ActiveItem] WARNING: Index not found on table '#{resolved_model.table_name}'. " \
|
|
567
|
+
'Falling back to table scan. Create the index: belt setup tables && belt deploy'
|
|
568
|
+
paginated_scan_with_conditions(normalized_conditions, exclusive_start_key, per_page)
|
|
562
569
|
rescue Aws::DynamoDB::Errors::AccessDeniedException => e
|
|
563
570
|
raise ActiveItem::AccessDeniedError.new(model_name: resolved_model.name, table: resolved_model.table_name,
|
|
564
571
|
operation: 'PaginatedQuery', original_error: e)
|
|
@@ -606,7 +613,8 @@ module ActiveItem
|
|
|
606
613
|
partition_value = normalized_conditions.values.first
|
|
607
614
|
|
|
608
615
|
index_config = resolved_model.indexes[idx_name] || {}
|
|
609
|
-
|
|
616
|
+
raw_pk = index_config[:partition_key]&.to_s || ruby_partition_key
|
|
617
|
+
dynamo_partition_key = resolved_model.to_dynamo_key(raw_pk)
|
|
610
618
|
|
|
611
619
|
params = {
|
|
612
620
|
table_name: resolved_model.table_name,
|
|
@@ -788,7 +796,7 @@ module ActiveItem
|
|
|
788
796
|
effective_index = index_name || resolved_model.send(:detect_index_for_conditions, normalized_conditions)
|
|
789
797
|
|
|
790
798
|
if effective_index && normalized_conditions.any?
|
|
791
|
-
|
|
799
|
+
query_with_index_or_fallback(effective_index, normalized_conditions)
|
|
792
800
|
else
|
|
793
801
|
scan_with_conditions_normalized(normalized_conditions)
|
|
794
802
|
end
|
|
@@ -838,6 +846,13 @@ module ActiveItem
|
|
|
838
846
|
end
|
|
839
847
|
|
|
840
848
|
limit_value ? [total, limit_value].min : total
|
|
849
|
+
rescue Aws::DynamoDB::Errors::ValidationException => e
|
|
850
|
+
raise unless e.message.include?('specified index')
|
|
851
|
+
|
|
852
|
+
warn "[ActiveItem] WARNING: Index not found on table '#{resolved_model.table_name}'. " \
|
|
853
|
+
'Falling back to table scan for count. Create the index: belt setup tables && belt deploy'
|
|
854
|
+
# Retry without the index
|
|
855
|
+
count_via_scan(normalized_conditions)
|
|
841
856
|
rescue Aws::DynamoDB::Errors::AccessDeniedException => e
|
|
842
857
|
raise ActiveItem::AccessDeniedError.new(model_name: resolved_model.name, table: resolved_model.table_name,
|
|
843
858
|
operation: 'Count', original_error: e)
|
|
@@ -848,7 +863,8 @@ module ActiveItem
|
|
|
848
863
|
partition_value = normalized_conditions.values.first
|
|
849
864
|
|
|
850
865
|
index_config = resolved_model.indexes[idx_name] || {}
|
|
851
|
-
|
|
866
|
+
raw_partition_key = index_config[:partition_key]&.to_s || ruby_partition_key
|
|
867
|
+
dynamo_partition_key = resolved_model.to_dynamo_key(raw_partition_key)
|
|
852
868
|
|
|
853
869
|
params = {
|
|
854
870
|
table_name: resolved_model.table_name,
|
|
@@ -911,6 +927,26 @@ module ActiveItem
|
|
|
911
927
|
params
|
|
912
928
|
end
|
|
913
929
|
|
|
930
|
+
# Fallback count via scan when an index is missing
|
|
931
|
+
def count_via_scan(normalized_conditions)
|
|
932
|
+
total = 0
|
|
933
|
+
exclusive_start_key = nil
|
|
934
|
+
|
|
935
|
+
loop do
|
|
936
|
+
params = build_count_scan_params(normalized_conditions)
|
|
937
|
+
params[:exclusive_start_key] = exclusive_start_key if exclusive_start_key
|
|
938
|
+
params[:limit] = limit_value if limit_value
|
|
939
|
+
|
|
940
|
+
response = resolved_model.dynamodb.scan(params)
|
|
941
|
+
total += response.count
|
|
942
|
+
exclusive_start_key = response.last_evaluated_key
|
|
943
|
+
break unless exclusive_start_key
|
|
944
|
+
break if limit_value && total >= limit_value
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
limit_value ? [total, limit_value].min : total
|
|
948
|
+
end
|
|
949
|
+
|
|
914
950
|
# Build scan params for a count-only scan
|
|
915
951
|
def build_count_scan_params(normalized_conditions)
|
|
916
952
|
filter_parts = []
|
|
@@ -944,7 +980,8 @@ module ActiveItem
|
|
|
944
980
|
partition_value = normalized_conditions.values.first
|
|
945
981
|
|
|
946
982
|
index_config = resolved_model.indexes[idx_name] || {}
|
|
947
|
-
|
|
983
|
+
raw_pk = index_config[:partition_key]&.to_s || ruby_partition_key
|
|
984
|
+
dynamo_partition_key = resolved_model.to_dynamo_key(raw_pk)
|
|
948
985
|
|
|
949
986
|
params = {
|
|
950
987
|
table_name: resolved_model.table_name,
|
|
@@ -1082,6 +1119,18 @@ module ActiveItem
|
|
|
1082
1119
|
foreign_key.to_s == attr_name ? nil : foreign_key.to_s
|
|
1083
1120
|
end
|
|
1084
1121
|
|
|
1122
|
+
# Attempt a GSI query, falling back to a filtered scan if the index doesn't exist.
|
|
1123
|
+
# Logs a warning when falling back so the developer knows to create the index.
|
|
1124
|
+
def query_with_index_or_fallback(idx_name, normalized_conditions)
|
|
1125
|
+
query_with_index_normalized(idx_name, normalized_conditions)
|
|
1126
|
+
rescue Aws::DynamoDB::Errors::ValidationException => e
|
|
1127
|
+
raise unless e.message.include?('specified index')
|
|
1128
|
+
|
|
1129
|
+
warn "[ActiveItem] WARNING: Index '#{idx_name}' not found on table '#{resolved_model.table_name}'. " \
|
|
1130
|
+
'Falling back to table scan. Create the index for better performance: belt setup tables && belt deploy'
|
|
1131
|
+
scan_with_conditions_normalized(normalized_conditions)
|
|
1132
|
+
end
|
|
1133
|
+
|
|
1085
1134
|
def query_with_index_normalized(idx_name, normalized_conditions)
|
|
1086
1135
|
# Get the partition key from conditions (Ruby snake_case)
|
|
1087
1136
|
ruby_partition_key = normalized_conditions.keys.first.to_s
|
|
@@ -1090,7 +1139,9 @@ module ActiveItem
|
|
|
1090
1139
|
# Get the actual DynamoDB partition key name from the index definition
|
|
1091
1140
|
# The index definition stores the DynamoDB key name (which may be camelCase)
|
|
1092
1141
|
index_config = resolved_model.indexes[idx_name] || {}
|
|
1093
|
-
|
|
1142
|
+
raw_partition_key = index_config[:partition_key]&.to_s || ruby_partition_key
|
|
1143
|
+
# Always convert to DynamoDB key format (camelCase) for the expression
|
|
1144
|
+
dynamo_partition_key = resolved_model.to_dynamo_key(raw_partition_key)
|
|
1094
1145
|
|
|
1095
1146
|
return fanout_query(idx_name, normalized_conditions, index_config, dynamo_partition_key, partition_value) if partition_value.is_a?(Array)
|
|
1096
1147
|
|
data/lib/active_item/version.rb
CHANGED