persistence.getAllStatesBetween() wrong for mapdb

From the docs:

.getAllStatesBetween(begin, end, serviceId) ⇒ Array[PersistedItem]

With a serviceId of ‘mapdb’ and a begin time after the last entry, the method should return an empty array, but instead it returns an array with 1 item.

That item has a timestamp of last update/change - even if it is before the begin time.

For this reason, several other methods fail, updatedSince and updatedBetween always return true, perhaps others.

Should there be a note in the docs?

A few things here:

  • getAllStatesBetween is irrelevant for mapDB as it only stores one value by definition.
  • all states between does include the state the item had at begin time of the period, as that is the first state it has in that period. It doesn’t matter it already had it before begin time, as long as it has it at begin time.
  • updatedSince and updatedBetween don’t use getAllStatesBetween at all. So the relation you assume isn’t there.
  • updatedBetween is irrelevant for mapDB, as it only stores one value.
  • updatedSince will return true if the value in persistence is different from the current state. And that’s the only one from the 3 persistence extensions you list that could have any relevance with mapDB.

Even with just one state, one should be able to tell if the one entry in the DB falls between the two timestamps or not, right? I would expect this to work even for MapDB.

Wouldn’t that be what changedSince does? updatedSince should be based on the timestamp (because you cannot guarantee that the state changed due to an update). Otherwise, there is no reason for updatedSince to even exist. It’s just changesSince by another name. But again, it should be based on the timestamp

I stand corrected, indeed. updatedSince will just look at the upate timestamp and should work with mapDB.

It could, but I am not sure it does. I need to check. I think the base query of getting a series of states may just not be implemented with mapDB.

Mapdb doesn’t store the data’s timestamp, afaik. Just item => state

It actually does.

I just checked. A query in mapDB ignores all filter criteria and just returns the stored item if any. Can you please create an enhancement request in the openhab-addons repository?

My journey here started as a user, writing javascript, trying to check if an item had been updated after a particular time.

updatedSince didn’t work for me, so I looked in the code.

Maybe I’m misunderstanding, but from PersistenceExtensions

public static @Nullable Boolean updatedSince(Item item, ZonedDateTime timestamp) {
        return internalUpdatedBetween(item, timestamp, null, null);
}


internalUpdatedBetween() then calls internalGetAllStatesBetween() - which is the guts of getAllStatesBetween()

And because internalGetAllStatesBetween returns a non empty array in this case, the check in internalUpdatedBetween always returns true.

So I agree with your ‘it doesn’t make sense…’ arguments in some sense, because I chose the wrong subject for the thread. Sorry about that.

No problem. See my previous comment. At this time, mapDB totally ignores all query filter arguments (and all persistence methods trigger a query of some sort).

Probably, when coding mapDB, it has never been foreseen to use these methods, just get the persisted item. It can be enhanced as there is more information available, so the returned item can be more meaningful.

MapDB stores (in OH5) an item state, last update time, last change time and the state before. This is used to be able to restore this information at startup. The query should at least look at the timestamps where it makes sense. It can never be complete though. E.g. previousState could return the state before, but without timestamp. Therefore, please create an issue in the openhab-addons repository so it does not get forgotten.

Still, using the item methods directly (without persistence), or using another persistence service that stores more information makes more sense to me.

https://github.com/openhab/openhab-addons/issues/19379

I am not a developer, so I’m not sure if this contains enough information, but the placeholder is there.