BrickSchema / py-brickschema

Python package for working with Brick (brickschema.org/)
Other
55 stars 15 forks source link

Issue with VersionedGraphCollection undoing/redoing "timelines" #96

Closed rileywong311 closed 1 year ago

rileywong311 commented 1 year ago

When I think of undo/redo, I guess an analogy is that, with google docs or word, I could undo text I've typed--then, it will give me the option to redo those undoes, but if I type something new, that redo option dissapears.

However, I realize that undo/redo can mean something different in the context of graphs. For VersionedGraphCollection, I can redo even if I've made changes since an undo. How should undo/redo work for a VersionedGraphCollection in this regard?

Here is some code below of me adding some changesets, undoing one, then making new changes, and still being able to redo

from brickschema.persistent import VersionedGraphCollection
from brickschema.namespaces import BRICK, A

vgc = VersionedGraphCollection(uri="sqlite://")

with vgc.new_changeset("project") as cs:
  cs.add((BRICK["11111"], A, BRICK.Building)) # add some dummy entity "11111"

with vgc.new_changeset("project") as cs:
  cs.add((BRICK["22222"], A, BRICK.Building)) # add some dummy entity "22222"

vgc.undo()

# this new changeset alters the "timeline" like going down a new path,
# so I would think that the previous undo data should lose its point (?)
with vgc.new_changeset("project") as cs:
  cs.add((BRICK["33333"], A, BRICK.Building)) # add some dummy entity "33333"

# I can redo even though that undo should be lost as we are no longer on that "timeline"
# this is code from the VersionedGraphCollection.redo() code, which recovers the most recent undo
with vgc.conn() as conn:
  redo_record = conn.execute(
    "SELECT * from redos " "ORDER BY timestamp ASC"
  ).fetchone()
if redo_record is not None:
  print("CAN REDO")
else:
  print("CANNOT REDO")

# similarly, actually running the redoing does not raise an exception
vgc.redo() 

# when I serialize the graph collecton as a whole, it is the version with "11111" and "22222"
# this suggest to me that the redo worked, but in the process it erased the "33333" version
vgc.serialize("Union.ttl") 

# ==================
# @prefix brick: <https://brickschema.org/schema/Brick#> .
#
# brick:11111 a brick:Building .
#
# brick:22222 a brick:Building .
# ==================

# when I serialize just the isolated graph, it only has "11111"
# I don't even know how this happened
g = vgc.graph_at(graph="project")
g.serialize("IndividualGraph.ttl")

# ==================
# @prefix brick: <https://brickschema.org/schema/Brick#> .
#
# brick:11111 a brick:Building .
# ==================

The best way to showcase the current state of the VersionedGraphCollection/Graph that I could think of is just to serialize it, but I know that doesn't quite make sense for just looking at the code. Let me know if there could be a better way to showcase the results.

If this is the proper way undo/redo should work, then why does taking the graph at the name "project" differ from the entire VGC?

rileywong311 commented 1 year ago

Unless I'm misunderstanding this as an issue, I guess a possible solution to this would be to clear to redo record data whenever a change_set is made

rileywong311 commented 1 year ago

Okay. I think the issue is not actually with the "merge conflicts" that arise from redoing after making changesets. The weird aftermath I found from serializing the graphs may actually be because redo() doesn't add the entities back under the same graph name, so the don't serialize with it anymore. I created a new issue to exemplify this potential bug, and I might close this issue.