Skip to content

Feature/281 plugin system to choose storagemanager implementation#301

Merged
abdessamad-abdoun merged 8 commits into
feature/corese-nextfrom
feature/281-plugin-system-to-choose-storagemanager-implementation
Mar 18, 2026
Merged

Feature/281 plugin system to choose storagemanager implementation#301
abdessamad-abdoun merged 8 commits into
feature/corese-nextfrom
feature/281-plugin-system-to-choose-storagemanager-implementation

Conversation

@abdessamad-abdoun
Copy link
Copy Markdown
Contributor

No description provided.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 5, 2026

Overall Project 46.74% -0.07% 🍏
Files changed 30.71%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
StoragePluginManager.java 36.99% -63.01%
MemoryStoragePlugin.java 14.89% -85.11%
GraphStoragePlugin.java 9.59% -90.41%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 5, 2026

Test Results

  357 files  + 8    357 suites  +8   41s ⏱️ -3s
1 940 tests +21  1 940 ✅ +21  0 💤 ±0  0 ❌ ±0 
1 941 runs  +21  1 941 ✅ +21  0 💤 ±0  0 ❌ ±0 

Results for commit eed6db0. ± Comparison against base commit 443d795.

♻️ This comment has been updated with latest results.

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from fe23b6a to 1742824 Compare March 5, 2026 10:12
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 5, 2026

Overall Project 46.78% -0.07% 🍏
Files changed 30.71%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
StoragePluginManager.java 36.99% -63.01%
MemoryStoragePlugin.java 14.89% -85.11%
GraphStoragePlugin.java 9.59% -90.41%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch 2 times, most recently from 763dc26 to 39cd813 Compare March 6, 2026 12:57
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 6, 2026

Overall Project 47.34% -0.07% 🍏
Files changed 30.71%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
StoragePluginManager.java 36.99% -63.01%
MemoryStoragePlugin.java 14.89% -85.11%
GraphStoragePlugin.java 9.59% -90.41%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

Copy link
Copy Markdown
Contributor

@MaillPierre MaillPierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a section to the main README on:

  • How to switch between storage managers (taking graph and Memory as examples)
  • What to implement to create your own storage manager

*
* @return the plugin priority
*/
default int getPriority() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment in the class description about the intended usage of priority ?

*
* @return {@code true} if transaction support is enabled
*/
public boolean isTransactionSupport() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor fix: "supportsTransaction" or "hasTransactionSupport"

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 9, 2026

Overall Project 47.34% -0.07% 🍏
Files changed 30.71%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
StoragePluginManager.java 36.99% -63.01%
MemoryStoragePlugin.java 14.89% -85.11%
GraphStoragePlugin.java 9.59% -90.41%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 9, 2026

Overall Project 47.44% -0.09% 🍏
Files changed 54.61%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 78.07% -21.93% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@github-actions
Copy link
Copy Markdown

Overall Project 47.44% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@MaillPierre MaillPierre linked an issue Mar 11, 2026 that may be closed by this pull request
@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from 4b33ed7 to ed1db20 Compare March 11, 2026 09:58
@github-actions
Copy link
Copy Markdown

Overall Project 47.5% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from ed1db20 to 76fecad Compare March 11, 2026 14:04
@github-actions
Copy link
Copy Markdown

Overall Project 47.73% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from 76fecad to 6466b3b Compare March 13, 2026 09:48
@github-actions
Copy link
Copy Markdown

Overall Project 47.72% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from 6466b3b to e4d5ca4 Compare March 13, 2026 10:14
@github-actions
Copy link
Copy Markdown

Overall Project 47.77% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from e4d5ca4 to 55fb41d Compare March 16, 2026 11:01
@abdessamad-abdoun abdessamad-abdoun force-pushed the feature/281-plugin-system-to-choose-storagemanager-implementation branch from 55fb41d to 047d03b Compare March 16, 2026 12:41
* @return the ValueFactory instance
*/
@Override
public ValueFactory valueFactory() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this redundant method which is the same as a default one.

import fr.inria.corese.core.kgram.api.core.Edge;
import fr.inria.corese.core.kgram.api.core.Node;
import fr.inria.corese.core.next.data.api.*;
import fr.inria.corese.core.next.storagemanager.api.plugin.PluginException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import fr.inria.corese.core.next.storagemanager.api.plugin.PluginException is never used

// Use Graph.addTriple() or Graph.add() instead of create() + addEdge()
// This bypasses the Edge creation issue
Edge edge;
if (context == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The named-graph branch seems to call the wrong Graph.addEdge overload. The 4-arg signature is (source, subject, predicate, value), but this passes (subject, predicate, object, context). That means model.add(s, p, o, ctx) will not insert into ctx as intended. Could we swap this to graph.addEdge(context, subject, predicate, object) and add a regression test covering named-graph inserts?

        Edge edge;
        if (context == null) {
            edge = graph.addEdge(subject, predicate, object);
        } else {
            edge = graph.addEdge(context, subject, predicate, object);
        }

@@ -78,14 +95,20 @@ public Set<Statement> find(Resource s, IRI p, Value o, Resource[] contexts) {
edges = graph.getEdgesRDF4J(subject, predicate, object);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the context semantics should be explicit and consistent across backends:

  • null context array => wildcard
  • empty context array => wildcard
  • {null} => default graph
  • mixed arrays such as {ctx1, ctx2, null} => union of ctx1, ctx2, and the default graph

At the moment, non-empty context arrays containing null are forwarded as raw null values to the Graph backend, and that path does not handle them correctly. Could we normalize null entries to the Corese default graph node here and add regression tests for these four cases?

* @throws PluginException if the memory storage fails to initialize
*/
public Model createModel(String storageType) throws PluginException {
StorageConfig config = switch (storageType) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is still more hardcoded than the plugin system suggests.

StoragePluginManager is designed to discover storage backends dynamically, so in principle adding a new StoragePlugin should be enough to make a new backend available. But ModelFactory.createModel(String) still only knows "memory" and "graph" through this switch.

So if someone adds a new plugin later, StoragePluginManager could support it, but ModelFactory would still reject it before the plugin manager is even called.

There is also a smaller inconsistency here: the plugins use case-insensitive matching (equalsIgnoreCase), but this switch is case-sensitive.

Would it make sense to keep this method as a convenience for the built-in backends and also add a createModel(StorageConfig config) overload that delegates directly to StoragePluginManager?

@github-actions
Copy link
Copy Markdown

Overall Project 47.81% -0.09% 🍏
Files changed 54.12%

File Coverage
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 74.78% -25.22% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
StoragePluginManager.java 52.51% -47.49%
GraphAdapter.java 51.05% -18.57%
StoragePlugin.java 0%
PluginException.java 0%
PluginNotFoundException.java 0%

@github-actions
Copy link
Copy Markdown

Overall Project 47.81% -0.12% 🍏
Files changed 50.98%

File Coverage
PluginNotFoundException.java 100% 🍏
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 72.12% -27.88% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
StoragePluginManager.java 66.9% -33.1% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
GraphAdapter.java 50.63% -20.64%
PluginException.java 45.45% -54.55%
StoragePlugin.java 0%
ExternalPluginLoader.java 0%

@MaillPierre MaillPierre added the Refactoring Issue created during the 2025 refactoring effort label Mar 17, 2026
@@ -287,10 +361,6 @@ private Edge statementToEdge(Statement stmt) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the same 4-argument ordering issue still remains here in the delete/contains path.

Graph.create(...) expects (source, subject, predicate, value), but this code still passes (subject, predicate, object, context). As a result, statements with a context are not converted to an Edge with the expected graph/source node layout.

Since both remove() and contains() rely on statementToEdge(), could we align this with the fixed add() path and build the edge as (context, subject, predicate, object) when a context is present?

Could we also add tests for these cases (especially with a context) to ensure remove() and contains() use the correct edge construction?

@github-actions
Copy link
Copy Markdown

Overall Project 47.81% -0.13% 🍏
Files changed 49.79%

File Coverage
PluginNotFoundException.java 100% 🍏
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 72.12% -27.88% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
StoragePluginManager.java 66.9% -33.1% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
GraphAdapter.java 50.21% -23.51%
PluginException.java 45.45% -54.55%
StoragePlugin.java 0%
ExternalPluginLoader.java 0%

Value object = nodeToValue(objectNode);

// Context (named graph)
Node graphNode = edge.getGraph();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the default-graph mapping is still not fully symmetric here.

The query-side behavior now looks like:

  • null / empty context array => wildcard
  • {null} => default graph
  • mixed arrays such as {ctx1, ctx2, null} => union including the default graph

If that is the intended contract, then the statement/edge conversion should follow the matching mapping as well:

  • Statement with null context -> Corese default graph node
  • Corese default graph node -> null statement context
  • named graph node -> corresponding Resource

At the moment, statementToEdge() still maps a null statement context to graph.create(null, ...), and edgeToStatement() converts any non-null graph node directly to a Resource. Could we special-case the default graph node in both directions?

private Statement edgeToStatement(Edge edge) {
    if (edge == null) {
        throw new IllegalArgumentException("Edge cannot be null");
    }

    Node subjectNode = edge.getSubjectNode();
    Node predicateNode = edge.getEdgeNode();
    Node objectNode = edge.getObjectNode();

    if (subjectNode == null) {
        throw new IllegalArgumentException("Edge subject node is null");
    }
    if (predicateNode == null) {
        throw new IllegalArgumentException("Edge predicate node is null");
    }
    if (objectNode == null) {
        throw new IllegalArgumentException("Edge object node is null");
    }

    Resource subject = nodeToResource(subjectNode);
    IRI predicate = nodeToIRI(predicateNode);
    Value object = nodeToValue(objectNode);

    Node graphNode = edge.getGraph();
    Resource context = (graphNode == null || graph.isDefaultGraphNode(graphNode))
            ? null
            : nodeToResource(graphNode);

    if (context == null) {
        return valueFactory.createStatement(subject, predicate, object);
    } else {
        return valueFactory.createStatement(subject, predicate, object, context);
    }
}

Comment on lines +354 to +363
Node object = valueToNode(stmt.getObject());

Resource ctxResource = stmt.getContext();
Node context = (ctxResource != null) ? resourceToNode(ctxResource) : null;

return graph.create(subject, predicate, object, context);
if (ctxResource == null) {
return graph.create(null, subject, predicate, object);
} else {
Node context = resourceToNode(ctxResource);
return graph.create(context, subject, predicate, object);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private Edge statementToEdge(Statement stmt) {
    Node subject = resourceToNode(stmt.getSubject());
    Node predicate = iriToNode(stmt.getPredicate());
    Node object = valueToNode(stmt.getObject());

    Resource ctxResource = stmt.getContext();
    Node context = (ctxResource != null)
            ? resourceToNode(ctxResource)
            : graph.getDefaultGraphNode();

    return graph.create(context, subject, predicate, object);
}

Copy link
Copy Markdown
Contributor

@remiceres remiceres left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a regression test covering the default-graph round-trip here?

A useful case would be:

  • insert a statement with no context / {null}
  • query it back
  • verify that the returned Statement has getContext() == null, not an explicit default-graph resource

That would help lock in the intended Statement <-> Graph context conversion semantics.

@github-actions
Copy link
Copy Markdown

Overall Project 47.81% -0.13% 🍏
Files changed 50.8%

File Coverage
PluginNotFoundException.java 100% 🍏
ErrorCode.java 94.83% 🍏
StorageConfig.java 92.38% -7.62% 🍏
ModelFactory.java 72.12% -27.88% 🍏
GraphStoragePlugin.java 67.12% -32.88% 🍏
StoragePluginManager.java 66.9% -33.1% 🍏
MemoryStoragePlugin.java 65.96% -34.04% 🍏
GraphAdapter.java 50.98% -22.49%
PluginException.java 45.45% -54.55%
StoragePlugin.java 0%
ExternalPluginLoader.java 0%

@abdessamad-abdoun abdessamad-abdoun merged commit e9b1442 into feature/corese-next Mar 18, 2026
2 checks passed
@MaillPierre MaillPierre deleted the feature/281-plugin-system-to-choose-storagemanager-implementation branch March 18, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Refactoring Issue created during the 2025 refactoring effort

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugin system to choose StorageManager implementation

3 participants