Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Blob:
Table:

- Fixed "Unexpected EOF" error when batch InsertReplace entities with Go SDK (issue #2519)
- Added support to query entity with simple filters as empty string, 'true' or 'false'. (issue #2450, #1573)

## 2024.10 Version 3.33.0

Expand Down
12 changes: 10 additions & 2 deletions src/table/persistence/LokiTableStoreQueryGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,14 @@ export default class LokiTableStoreQueryGenerator {
public static generateQueryTableWhereFunction(
query: string | undefined
): (entity: Table) => boolean {
if (query === undefined) {
if (query === undefined || query === "" || query === "true") {
return () => true;
}

if (query === "false") {
return () => false;
}

const queryTree = parseQuery(query);
validateQueryTree(queryTree);
return (entity) => executeQuery(entity, queryTree);
Expand Down Expand Up @@ -80,10 +84,14 @@ export default class LokiTableStoreQueryGenerator {
private static generateQueryEntityWhereFunction(
query: string | undefined
): (entity: Entity) => boolean {
if (query === undefined || query === "") {
if (query === undefined || query === "" || query === "true") {
return () => true;
}

if (query === "false") {
return () => false;
}

const queryTree = parseQuery(query);
validateQueryTree(queryTree);
return (entity) => executeQuery(entity, queryTree);
Expand Down
143 changes: 142 additions & 1 deletion tests/table/apis/table.entity.issues.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import {
GetTableEntityResponse,
odata,
TableEntity,
TableEntityResult
TableEntityResult,
TableItem
} from "@azure/data-tables";
import { configLogger } from "../../../src/common/Logger";
import StorageError from "../../../src/table/errors/StorageError";
import TableServer from "../../../src/table/TableServer";
import { getUniqueName } from "../../testutils";
import {
createAzureDataTablesClient,
createAzureDataTableServiceClient,
createTableServerForTestHttps,
createUniquePartitionKey
} from "../utils/table.entity.test.utils";
Expand Down Expand Up @@ -454,5 +456,144 @@ describe("table Entity APIs test : Issues", () => {
assert.strictEqual(storageError.statusCode, "InvalidInput");
assert.strictEqual(storageError.storageErrorCode, 400);
});

await tableClient.deleteTable();
});

//from issue #2450
it("should parce a simple query entity @loki", async () => {
const partitionKeyForQueryTest1 = createUniquePartitionKey("1_");
const totalItems = 2;
const tableClient = createAzureDataTablesClient(
testLocalAzuriteInstance,
tableName
);
await tableClient.createTable();

// first partition
// creates entities individually
for (let i = 0; i < totalItems; i++) {
const result = await tableClient.createEntity({
partitionKey: partitionKeyForQueryTest1,
rowKey: `${i}`,
number: i
});
assert.notStrictEqual(result.etag, undefined);
}

const maxPageSize = 5; // this should work with a page size of 1000, but fails during response serialization on my machine
let testsCompleted = 0;
// take note of the different whitespacing and query formatting:
const queriesAndExpectedResult = [
{
queryOptions: {
filter: ``
},
expectedResult: 2
},
{
queryOptions: {
filter: `false`
},
expectedResult: 0
},
{
queryOptions: {
filter: `true`
},
expectedResult: 2
}
];

for (const queryTest of queriesAndExpectedResult) {
const entities = tableClient.listEntities<TableEntity<{ number: number }>>({
queryOptions: queryTest.queryOptions,
disableTypeConversion: true
});
let all: TableEntity<{ number: number }>[] = [];
for await (const entity of entities.byPage({
maxPageSize
})) {
all = [...all, ...entity];
}
assert.strictEqual(
all.length,
queryTest.expectedResult,
`Failed with query ${queryTest.queryOptions.filter}`
);
testsCompleted++;
}
assert.strictEqual(testsCompleted, queriesAndExpectedResult.length);
await tableClient.deleteTable();

});
//from issue #2450
it("should parce a simple query tables @loki", async () => {
const tableClient = createAzureDataTableServiceClient(
testLocalAzuriteInstance
);

// not all test remove tables after running
// so we need to remove the table if it exists
const maxPageSize = 5;
const tables = tableClient.listTables();
let all: TableItem[] = [];
for await (const table of tables.byPage({
maxPageSize
})) {
all = [...all, ...table];
}

for (const table of all) {
if(table.name) {
await tableClient.deleteTable(table.name);
}
}

await tableClient.createTable(tableName);

let testsCompleted = 0;
// take note of the different whitespacing and query formatting:
const queriesAndExpectedResult = [
{
queryOptions: {
filter: ``
},
expectedResult: 1
},
{
queryOptions: {
filter: `false`
},
expectedResult: 0
},
{
queryOptions: {
filter: `true`
},
expectedResult: 1
}
];

for (const queryTest of queriesAndExpectedResult) {
const tables = tableClient.listTables({
queryOptions: queryTest.queryOptions
});
let all: TableItem[] = [];
for await (const table of tables.byPage({
maxPageSize
})) {
all = [...all, ...table];
}
assert.strictEqual(
all.length,
queryTest.expectedResult,
`Failed with query ${queryTest.queryOptions.filter}`
);
testsCompleted++;
}
assert.strictEqual(testsCompleted, queriesAndExpectedResult.length);
await tableClient.deleteTable(tableName);

});
});
36 changes: 35 additions & 1 deletion tests/table/utils/table.entity.test.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import TableServer from "../../../src/table/TableServer";
import {
AzureNamedKeyCredential,
AzureSASCredential,
TableClient
TableClient,
TableServiceClient
} from "@azure/data-tables";
import { copyFile } from "fs";
import TableTestServerFactory, { ITableTestServerFactoryParams } from "./TableTestServerFactory";
Expand Down Expand Up @@ -183,7 +184,40 @@ export function createAzureDataTablesClient(
);
}
}
/**
* creates an Azure Data Tables client for local or service tests
*
* @export
* @param {boolean} local
* @param {string} tableName
* @return {*} {TableClient}
*/
export function createAzureDataTableServiceClient(
local: boolean
): TableServiceClient {
if (local) {
const sharedKeyCredential = new AzureNamedKeyCredential(
EMULATOR_ACCOUNT_NAME,
EMULATOR_ACCOUNT_KEY
);

return new TableServiceClient(
`https://${HOST}:${PORT}/${EMULATOR_ACCOUNT_NAME}`,
sharedKeyCredential
);
} else {
// return new TableClient(
// process.env[AZURE_DATATABLES_STORAGE_STRING]! +
// process.env[AZURE_DATATABLES_SAS]!,
// tableName
// );

return new TableServiceClient(
process.env[AZURE_DATATABLES_STORAGE_STRING]!,
new AzureSASCredential(process.env[AZURE_DATATABLES_SAS]!)
);
}
}
/**
* Default behavior will overwrite target.
* This will copy the old db file with older schema on which we then
Expand Down
Loading