Skip to content

Commit 7768021

Browse files
fixed indexed ordering issue
1 parent 3cc8ba2 commit 7768021

File tree

2 files changed

+38
-40
lines changed

2 files changed

+38
-40
lines changed

Magic.IndexedDb/wwwroot/magicLinqToIndexedDb.js

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -179,35 +179,47 @@ function runIndexedQuery(table, indexedConditions, queryAdditions = []) {
179179
debugLog("Executing runIndexedQuery", { indexedConditions, queryAdditions });
180180

181181
let query;
182-
let firstCondition = indexedConditions[0];
182+
const firstCondition = indexedConditions[0];
183183

184-
// **Handle Compound Index Query**
185-
if (Array.isArray(firstCondition.properties)) {
186-
debugLog("Detected Compound Index Query!", { properties: firstCondition.properties });
184+
const isUniversalFilter = (
185+
firstCondition &&
186+
firstCondition.operation === QUERY_OPERATIONS.GREATER_THAN_OR_EQUAL &&
187+
(firstCondition.value === -Infinity || firstCondition.value === Number.NEGATIVE_INFINITY)
188+
);
189+
190+
const orderAddition = queryAdditions.find(q =>
191+
q.additionFunction === QUERY_ADDITIONS.ORDER_BY ||
192+
q.additionFunction === QUERY_ADDITIONS.ORDER_BY_DESCENDING
193+
);
194+
195+
// === Handle Universal Filter Shortcut (full table scan with orderBy) ===
196+
if (isUniversalFilter && orderAddition?.property) {
197+
debugLog("Detected universal filter with orderBy!", { orderBy: orderAddition.property });
198+
199+
query = table.orderBy(orderAddition.property);
200+
if (orderAddition.additionFunction === QUERY_ADDITIONS.ORDER_BY_DESCENDING) {
201+
query = query.reverse();
202+
}
203+
}
187204

188-
// **Extract values in the correct order**
189-
const valuesInCorrectOrder = firstCondition.properties.map((_, index) => firstCondition.value[index]);
205+
// === Handle Compound Index Query ===
206+
else if (Array.isArray(firstCondition.properties)) {
207+
debugLog("Detected Compound Index Query!", { properties: firstCondition.properties });
190208

191-
debugLog("Compound Index Query - Ordered Properties & Values", {
192-
properties: firstCondition.properties,
193-
values: valuesInCorrectOrder
194-
});
209+
const valuesInCorrectOrder = firstCondition.properties.map((_, i) => firstCondition.value[i]);
195210

196211
query = table.where(firstCondition.properties);
197212

198213
if (firstCondition.operation === QUERY_OPERATIONS.EQUAL) {
199214
query = query.equals(valuesInCorrectOrder);
200-
}
201-
else if (firstCondition.operation === QUERY_OPERATIONS.IN) {
215+
} else if (firstCondition.operation === QUERY_OPERATIONS.IN) {
202216
query = query.anyOf(firstCondition.value);
203-
}
204-
else {
217+
} else {
205218
throw new Error(`Unsupported operation for compound indexes: ${firstCondition.operation}`);
206219
}
207220
}
208221

209-
210-
// **Handle Single Indexed Query**
222+
// === Handle Single Indexed Query ===
211223
else if (firstCondition.property) {
212224
debugLog("Detected Single-Index Query!", { property: firstCondition.property });
213225

@@ -233,45 +245,30 @@ function runIndexedQuery(table, indexedConditions, queryAdditions = []) {
233245
case QUERY_OPERATIONS.STARTS_WITH:
234246
query = table.where(firstCondition.property).startsWith(firstCondition.value);
235247
break;
236-
237248
case "between":
238249
if (Array.isArray(firstCondition.value) && firstCondition.value.length === 2) {
239250
const [lower, upper] = firstCondition.value;
240-
const includeLower = firstCondition.includeLower !== false; // default to true
241-
const includeUpper = firstCondition.includeUpper !== false; // default to true
242-
251+
const includeLower = firstCondition.includeLower !== false;
252+
const includeUpper = firstCondition.includeUpper !== false;
243253
query = table.where(firstCondition.property).between(lower, upper, includeLower, includeUpper);
244254
} else {
245255
throw new Error("Invalid 'between' value format. Expected [min, max]");
246256
}
247257
break;
248-
249-
250258
default:
251259
throw new Error(`Unsupported indexed query operation: ${firstCondition.operation}`);
252260
}
253-
}
254-
else {
261+
} else {
255262
throw new Error("Invalid indexed condition—missing `properties` or `property`.");
256263
}
257264

258-
/*
259-
LINQ to IndexedDB sacrifices ordering of the return for performance.
260-
Therefore skip entirely even appending an order if that's all that's on there.
261-
As that means the order doesn't have anything to do with the end desired results.
262-
*/
265+
// === Apply Query Additions (take, skip, first, etc.) ===
263266
if (requiresQueryAdditions(queryAdditions)) {
264267
for (const addition of queryAdditions) {
265268
switch (addition.additionFunction) {
266269
case QUERY_ADDITIONS.ORDER_BY:
267-
if (addition.property) {
268-
query = query.orderBy(addition.property);
269-
}
270-
break;
271270
case QUERY_ADDITIONS.ORDER_BY_DESCENDING:
272-
if (addition.property) {
273-
query = query.orderBy(addition.property).reverse();
274-
}
271+
// Already handled above (only valid without .where())
275272
break;
276273
case QUERY_ADDITIONS.SKIP:
277274
query = query.offset(addition.intValue);
@@ -295,6 +292,7 @@ function runIndexedQuery(table, indexedConditions, queryAdditions = []) {
295292
return query;
296293
}
297294

295+
298296
function requiresQueryAdditions(queryAdditions = []) {
299297
if (!queryAdditions || queryAdditions.length === 0) {
300298
return false; // No query additions at all, skip processing

TestServer/TestServer/Components/Pages/CarTests.razor

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,17 +138,17 @@
138138
await carQuery.ClearTable();
139139

140140
List<Car> cars = [];
141-
cars.Add(new Car{ Brand = "Audi"});
142-
cars.Add(new Car{ Brand = "Toyota"});
143-
cars.Add(new Car{ Brand = "Ferrari"});
141+
cars.Add(new Car { Brand = "Audi", Created = DateTime.UtcNow.AddDays(1) });
142+
cars.Add(new Car { Brand = "Toyota", Created = DateTime.UtcNow.AddDays(2) });
143+
cars.Add(new Car { Brand = "Ferrari", Created = DateTime.UtcNow.AddDays(3) });
144144

145145
await carQuery.AddRangeAsync(cars);
146146

147147
allCars = await carQuery.ToListAsync();
148148

149149
RunTest("Order date (index) with skip 1",
150150
await carQuery.OrderBy(car => car.Created).Skip(1).ToListAsync(),
151-
allCars.OrderBy(car => car.Created).ToList());
151+
allCars.OrderBy(car => car.Created).Skip(1).ToList());
152152

153153
StateHasChanged();
154154
}

0 commit comments

Comments
 (0)