AmrDeveloper / GQL

Git Query language is a SQL like language to perform queries on .git files with supports of most of SQL features such as grouping, ordering and aggregations functions
https://amrdeveloper.github.io/GQL/
MIT License
3.24k stars 89 forks source link

ability to match on value #127

Closed fdncred closed 1 hour ago

fdncred commented 2 hours ago

This is not really a feature request but it's also not a bug. It's more of a question.

After the most recent changes I'm having a hard time using the library because I can't figure out how to match on value.

I have something like this.

        let mut rec = Record::new();
        for index in 0..titles_len {
            let column_name = &titles[index];
            let column_value = row.values.get(index).unwrap();
            match column_value.as_any() {
                v if v.is::<IntValue>() => {
                    let int_val = v.downcast_ref::<IntValue>().unwrap();
                    rec.insert(column_name, NuValue::test_int(int_val.value));
                }
                v if v.is::<BoolValue>() => {
                    let bool_val = v.downcast_ref::<BoolValue>().unwrap();
                    rec.insert(column_name, NuValue::test_bool(bool_val.value));
                }
                v if v.is::<DateValue>() => {
                    let date_val = v.downcast_ref::<DateValue>().unwrap();
                    rec.insert(column_name, NuValue::test_string(date_val.to_string()));
                }
                _ => {
                    rec.insert(column_name, NuValue::test_string(column_value.literal()));
                }
            }

Which is kind of ugly and hard to read.

Previously I had something like this, which seemed much more intuitive.

        let mut rec = Record::new();
        for index in 0..titles_len {
            let column_name = &titles[index];
            let column_value = row.values.get(index).unwrap();
            match column_value {
                gitql_core::value::Value::Integer(i) => {
                    rec.insert(column_name, Value::test_int(*i));
                }
                gitql_core::value::Value::Float(f) => {
                    rec.insert(column_name, Value::test_float(*f));
                }
                gitql_core::value::Value::Text(t) => {
                    rec.insert(column_name, Value::test_string(t.to_string()));
                }
                gitql_core::value::Value::Boolean(b) => {
                    rec.insert(column_name, Value::test_bool(*b));
                }
                gitql_core::value::Value::DateTime(dt) => {
                    rec.insert(column_name, Value::test_string(dt.to_string()));
                }
                gitql_core::value::Value::Date(dt) => {
                    rec.insert(column_name, Value::test_string(dt.to_string()));
                }

I'd like to do something like this so I can match on the column_value and use the variable that comes with it in the match arm. Is there no way to do this any longer? I'm assuming I'm making this harder than it needs to be but I'm lost. Any help you could provide would be appreciated.

fdncred commented 2 hours ago

I'm trying to update this nushell plugin to the latest published crates https://github.com/fdncred/nu_plugin_gitql

AmrDeveloper commented 1 hour ago

Hello @fdncred,

The new version has different type system outside the engine and not limited to enum of primitives so we can create advanced type safe queries like LLQL project

One solution is to write it like this

match value {
  v if v.is_int() => {
    rec.insert(column_name, NuValue::test_int(v.as_int().unwrap()));
  }
  v if v.is_float() => {
    rec.insert(column_name, NuValue::test_float(v.as_float().unwrap()));
  }
_ => {}
}

I will try to provide helper functions to deal with primitives like types, but i need to design a good way so SDK users can follow the same design for their types

fdncred commented 1 hour ago

ok. that's a little cleaner. I'll try that. yes, please, a helper function for this type of thing would be nice.

AmrDeveloper commented 1 hour ago

ok. that's a little cleaner. I'll try that. yes, please, a helper function for this type of thing would be nice.

Sure, if you have any suggestions feel free to share them

Thank you, and nice plugin