feat: recognize generated schema types (SchemaTypeName + UnwrapSchema)#20
Open
mlwelles wants to merge 1 commit into
Open
feat: recognize generated schema types (SchemaTypeName + UnwrapSchema)#20mlwelles wants to merge 1 commit into
mlwelles wants to merge 1 commit into
Conversation
Add the Schema interface (SchemaTypeName), the UnwrapSchema reflection helper, and the DgraphMapper interface (record.go). The client unwraps schema-defining values at the mutation and query boundary so generated wrapper types route to their backing schema struct. Plain structs do not implement Schema and are unaffected — UnwrapSchema is identity for them.
There was a problem hiding this comment.
3 issues found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="record.go">
<violation number="1" location="record.go:45">
P2: UnwrapSchema misses pointer-receiver Unwrap() methods when wrapper is passed by value</violation>
<violation number="2" location="record.go:53">
P1: Potential panic when invoking reflected Unwrap() on typed nil pointer wrappers</violation>
</file>
<file name="record_test.go">
<violation number="1" location="record_test.go:73">
P2: Tests use a local `recordingClient` mock to simulate unwrapping instead of exercising real client methods, so regressions in the actual integration points (7 client mutation/query methods) may go undetected.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Comment on lines
+53
to
+54
| inner := m.Call(nil)[0].Interface() | ||
| if _, ok := inner.(Schema); ok { |
There was a problem hiding this comment.
P1: Potential panic when invoking reflected Unwrap() on typed nil pointer wrappers
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At record.go, line 53:
<comment>Potential panic when invoking reflected Unwrap() on typed nil pointer wrappers</comment>
<file context>
@@ -0,0 +1,58 @@
+ if mt.NumIn() != 0 || mt.NumOut() != 1 {
+ return obj
+ }
+ inner := m.Call(nil)[0].Interface()
+ if _, ok := inner.(Schema); ok {
+ return inner
</file context>
Suggested change
| inner := m.Call(nil)[0].Interface() | |
| if _, ok := inner.(Schema); ok { | |
| // Guard against typed-nil pointer wrappers | |
| if v.Kind() == reflect.Ptr && v.IsNil() { | |
| return obj | |
| } | |
| m := v.MethodByName("Unwrap") | |
| if !m.IsValid() { | |
| return obj | |
| } |
| if !v.IsValid() { | ||
| return obj | ||
| } | ||
| m := v.MethodByName("Unwrap") |
There was a problem hiding this comment.
P2: UnwrapSchema misses pointer-receiver Unwrap() methods when wrapper is passed by value
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At record.go, line 45:
<comment>UnwrapSchema misses pointer-receiver Unwrap() methods when wrapper is passed by value</comment>
<file context>
@@ -0,0 +1,58 @@
+ if !v.IsValid() {
+ return obj
+ }
+ m := v.MethodByName("Unwrap")
+ if !m.IsValid() {
+ return obj
</file context>
Suggested change
| m := v.MethodByName("Unwrap") | |
| m := v.MethodByName("Unwrap") | |
| if !m.IsValid() && v.Kind() != reflect.Ptr && v.CanAddr() { | |
| m = v.Addr().MethodByName("Unwrap") | |
| } | |
| if !m.IsValid() { | |
| return obj | |
| } |
| seen []any | ||
| } | ||
|
|
||
| func (c *recordingClient) capture(obj any) any { |
There was a problem hiding this comment.
P2: Tests use a local recordingClient mock to simulate unwrapping instead of exercising real client methods, so regressions in the actual integration points (7 client mutation/query methods) may go undetected.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At record_test.go, line 73:
<comment>Tests use a local `recordingClient` mock to simulate unwrapping instead of exercising real client methods, so regressions in the actual integration points (7 client mutation/query methods) may go undetected.</comment>
<file context>
@@ -0,0 +1,117 @@
+ seen []any
+}
+
+func (c *recordingClient) capture(obj any) any {
+ obj = UnwrapSchema(obj)
+ c.seen = append(c.seen, obj)
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a small mechanism so the client recognizes generated schema/wrapper types:
record.go: theSchemainterface (SchemaTypeName() string), theUnwrapSchemareflection helper, and theDgraphMapperinterface.UnwrapSchema, so a generated wrapper type routes to its backing schema struct. Plain user structs don't implementSchemaand are unaffected (UnwrapSchemais identity for them).Self-contained and additive: builds and tests green. This is the integration point that lets code generators (e.g. modusgraph-gen) emit wrapper types the client understands.
Part of a series upstreaming work from a downstream fork; opened for review/discussion.
Summary by cubic
Teach the
modusgraphclient to recognize generated schema wrapper types and route them to their underlying schema structs. This enablesmodusgraph-genwrappers to work transparently; plain user structs are unchanged.Schemainterface (SchemaTypeName() string) to tag generated schema records.UnwrapSchemato return the inner record when a wrapper exposesUnwrap(); ignoreserrors.Unwrap.UnwrapSchemainInsert,InsertRaw,Upsert,Update,Get,Query, andUpdateSchema(per-arg).Schemastructs pass through unchanged.Written for commit b74cec7. Summary will update on new commits.