I am using this:
https://github.com/Azure/azure-storage-table-php
to insert data to azure table.
However, when I retrieve the data, I don’t get the latest entries unless I use a do...while loop, as shown in the commented section of the function below.
My question is:
How can I retrieve the latest data while using pagination? I want the newest records to always appear first in the list, and then use the continuation token to load the next set of results. I don't want to use the do..while as it will retrieve all the data from the azure table at once.
I have also implemented this function(invertedTicksRowKey) to use the value as rowKey:
function invertedTicksRowKey(): string
{
$now = new DateTime('now', new DateTimeZone('UTC'));
$ticks = ($now->format('U') * 10000000) + ($now->format('u') * 10) + 621355968000000000;
$inverted = 9223372036854775807 - $ticks;
$suffix = bin2hex(random_bytes(4)); // 8-char hex
return str_pad($inverted, 19, "0", STR_PAD_LEFT) . '-' . $suffix;
}
public function get_table_data(string $tableName, int $pageSize = 1000, ?TableContinuationToken $continuationToken = null, $filter = []): array
{
try {
$allData = [];
$token = $continuationToken;
//do {
$options = new QueryEntitiesOptions();
$options->setTop($pageSize);
// Build combined filter
$filters = [];
if (!empty($filter['date_range_filter'])) {
$filters[] = $filter['date_range_filter'];
}
if (!empty($filter['function'])) {
$filters[] = "PartitionKey eq '" . $filter['function'] . "'";
}
if ($filters) {
$filterString = implode(' and ', $filters);
$options->setFilter(Filter::applyQueryString($filterString));
}
if ($token) {
$options->setContinuationToken($token);
}
$result = $this->_tableClient->queryEntities($tableName, $options);
$token = $result->getContinuationToken();
$entities = $result->getEntities();
foreach ($entities as $entity) {
$row = [];
foreach ($entity->getProperties() as $key => $prop) {
$row[$key] = $prop->getValue();
}
$row['PartitionKey'] = $entity->getPartitionKey();
$row['RowKey'] = $entity->getRowKey();
$row['Timestamp'] = $entity->getTimestamp();
$allData[] = $row;
}
//} while ($token !== null);
// Sort newest first by RowKey (smallest = newest)
usort($allData, fn($a, $b) => strcmp($a['RowKey'], $b['RowKey']));
return [
'data' => $allData,
'continuationToken' => $token
];
} catch (\Exception $e) {
log_message('error', 'Azure Table query failed: ' . $e->getMessage());
return ['data' => [], 'continuationToken' => null];
}
}
Log tail pattern(Retrieve the n entities most recently added to a partition by using a RowKey value that sorts in reverse date and time order.)