Skip to content

About Relations (associations, association_meta) #385

@IngwiePhoenix

Description

@IngwiePhoenix

Hey there!

About a weekend and some later, and I am much more confident in my driver - I feel like it's maturing, and so is the accompaning REL implementation. So, I have started to write some playground-style tests to see how far it works ... or does not.

Right now, I am trying to get related record loading to work; so let me give you the TL;DR:

DEFINE TABLE users SCHEMAFULl;
DEFINE FIELD name ON users TYPE string;
DEFINE FIELD tags ON users TYPE array<string>;
DEFINE FIELD photos ON users TYPE record<photos>;

DEFINE TABLE photos SCHEMAFULL;
DEFINE FIELD title ON photos TYPE string;
DEFINE FIELD file ON photos TYPE bytes;

That's a very basic 1:n relation. To query all users, with their photos:

SELECT * FROM users FETCH photos;

The resulting JSON will also contain the photos - as already attached objects.

{
    "id": "user:test",
    "name": "Test User",
    "tags": ["dev", "nerd"],
    "photos": [
        {
            "id": "photos:abcdef",
            "title": "A selfie",
            "data": [...]
        },
        {
            "id": "photos:zyxvut",
            "title": "Another selfie",
            "data": [...]
        }
    ]
}

This obviously isn't how the big classics, MySQL and PostgresQL behave.

The way the driver handles it, is that it returns both tags and photos as []byte.

This is demonstrated here. Unfortunately, inserting data does not work: Found NONE for field risks_rel, with record processes:Lohnabrechnung2, but expected a record<risks>. That's a SurrealDB error, and here is the query that produced that:

surrealdb:driver:connection:execWithArgs INSERT INTO processes (title, description, responsible, risks, storage, id, created_at, updated_at, legal_basis, tasks, affected_data) VALUES ($_1, $_2, $_3, $_4, $_5, $_6, $_7, $_8, $_9, $_10, $_11) ON DUPLICATE KEY UPDATE storage = $_12, title = $_13, description = $_14, responsible = $_15, risks = $_16, tasks = $_17, affected_data = $_18, id = $_19, created_at = $_20, updated_at = $_21, legal_basis = $_22;
surrealdb:driver:connection:execWithArgs map[string]interface {}{
surrealdb:driver:connection:execWithArgs     "_1":  "Lohnabrechnung",
surrealdb:driver:connection:execWithArgs     "_10": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Einholen der Bankdaten"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_11": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Kontoinformationen"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_12": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"NAS", "Aktenschrank"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_13": "Lohnabrechnung",
surrealdb:driver:connection:execWithArgs     "_14": "Beispiel der Lohnabrechnung",
surrealdb:driver:connection:execWithArgs     "_15": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Alex", "Daniel"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_16": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Datendiebstahl", "Ausnutzung"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_17": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Einholen der Bankdaten"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_18": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Kontoinformationen"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_19": "Lohnabrechnung2",
surrealdb:driver:connection:execWithArgs     "_2":  "Beispiel der Lohnabrechnung",
surrealdb:driver:connection:execWithArgs     "_20": "d'2025-02-16T02:10:20+01:00'",
surrealdb:driver:connection:execWithArgs     "_21": "d'2025-02-16T02:10:20+01:00'",
surrealdb:driver:connection:execWithArgs     "_22": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"GOB", "Wirtschaft"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_3": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Alex", "Daniel"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_4": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"Datendiebstahl", "Ausnutzung"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_5": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"NAS", "Aktenschrank"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs     "_6": "Lohnabrechnung2",
surrealdb:driver:connection:execWithArgs     "_7": "d'2025-02-16T02:10:20+01:00'",
surrealdb:driver:connection:execWithArgs     "_8": "d'2025-02-16T02:10:20+01:00'",
surrealdb:driver:connection:execWithArgs     "_9": surrealtypes.ArrayOf[string]{
surrealdb:driver:connection:execWithArgs         Values: {"GOB", "Wirtschaft"},
surrealdb:driver:connection:execWithArgs     },
surrealdb:driver:connection:execWithArgs }

(I have some actually usable debug logging now...it helps a lot.)

The actual struct being passed is:

	lohnabrechnung := Process{
		ID:           "Lohnabrechnung2",
		Title:        "Lohnabrechnung",
		Description:  "Beispiel der Lohnabrechnung",
		CreatedAt:    time.Now(),
		UpdatedAt:    time.Now(),
		Responsible:  st.ArrayOf[string]{Values: []string{"Alex", "Daniel"}},
		LegalBasis:   st.ArrayOf[string]{Values: []string{"GOB", "Wirtschaft"}},
		Risks:        st.ArrayOf[string]{Values: []string{"Datendiebstahl", "Ausnutzung"}},
		Storage:      st.ArrayOf[string]{Values: []string{"NAS", "Aktenschrank"}},
		Tasks:        st.ArrayOf[string]{Values: []string{"Einholen der Bankdaten"}},
		AffectedData: st.ArrayOf[string]{Values: []string{"Kontoinformationen"}},
		RelatedRisks: []Risk{ // <--- This does not get sent!
			{Title: "Beispiel", Description: "Beschreibungszeug"},
			{Title: "Beispiel 2", Description: "Beschreibungszeug 2"},
		},
	}

Is there any interface I can implement in my adapter to work with/around that?

Thank you and kind regards,

Ingwie

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions