Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple secondary keys from a single record #143

Open
leontoeides opened this issue May 8, 2024 · 3 comments
Open

Multiple secondary keys from a single record #143

leontoeides opened this issue May 8, 2024 · 3 comments
Assignees

Comments

@leontoeides
Copy link

leontoeides commented May 8, 2024

According to the documentation regarding secondary keys a custom function can be defined in the macro that can be used to finagle a secondary key from the user's struct.

The following tells native_db to use the user-supplied function custom_name to get the secondary key for the struct:

#[derive(Serialize, Deserialize)]
#[native_model(id=1, version=1)]
#[native_db(secondary_key(custom_name, optional))]
struct Data {
    #[primary_key]
    id: u64,
    #[secondary_key]
    name: String,
    flag: bool,
}

I wonder, is #[secondary_key] necessary if #[native_db(secondary_key(custom_name, optional))] is defined?

The user-defined custom_name function returns an Option<String> as the secondary key:

impl Data {
    fn custom_name(&self) -> Option<String> {
        if self.flag {
            Some(self.name.clone().to_uppercase())
        } else {
            None
        }
    }
}

Since, according to the documentation, users can define "define it or not, define one or more" I assume it should be possible to return multiple secondary keys for a single struct?

If so, I'd like to propose an additional secondary_keys definition that can return a Vec<T> rather than an Option<T>. If the secondary key isn't optional, an empty Vec would fail.

I get the impression that native_db's internal structure should support this, it's just a matter of implementing the feature? Any thoughts?

@vincent-herlemont
Copy link
Owner

vincent-herlemont commented May 8, 2024

I wonder, is #[secondary_key] necessary if #[native_db(secondary_key(custom_name, optional))] is defined?

Actually, no, it's not linked. You can have as many secondary_key associated with fields as you have custom secondary_key defined in the macro.

Here are some examples:

Each time it is a new key whether it is custom or not, you can have a mix of the two without any problem. And you can create as many as you want.

Does this answer your questions?

@leontoeides
Copy link
Author

leontoeides commented May 12, 2024

Thank you, yes that did answer my question.

I still think it would be very useful to be able to return an arbitrary number of secondary keys for a record using a function or by implementing a trait for the struct?

Just a hypothetical example here - let's say each struct in the database represented a country. A person could use an enum as a key:

enum CountryKey {
    City(String)
    State(String)
}

struct CountryValue {
    cities: Vec<String>,
    states: Vec<String>,
}

let united_states = CountryValue {
    cities: vec!["Houston", "San Antonio", "Galveston"], // etc.
    states: vec!["Texas"], // etc.
}

The custom #[native_db(secondary_keys(function_name))] function could return a collection of cities and states for the CountryValue. For example:

[City("Houston"), City("San Antonio"), City("Galveston"), State("Texas")]

And then when searching the database for City("Houston") or State("Texas") the database would return united_states struct.

@vincent-herlemont
Copy link
Owner

vincent-herlemont commented May 14, 2024

It's an interesting idea, I see several things in your example:

  1. The fact of having multiple values available for search for a single secondary key. And the possibility to search by value.
  2. The fact that a custom type like City is used as a key.

  • For the first case: it could be possible, do you have a real specific use case in mind?
  • For the second case: you are right, it should be possible to add these custom types in the search. I will open a PR for that. feat: allow to implement custom type #149

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants