Cast the variable to the Value type

My function takes the data and inserts it into the Sqlite table. In order not to create functions to insert for each base type, I decided to accept Value, however, I cannt get a variable of the same type as Value using static or dynamic cast.

void main() {
    Value val = new Value(typeof(string));
    val = "sas";
    var a = val as (val.get_gtype()); //syntax error, expected `unowned'
    var a = (val.get_gtype)val;   //The symbol `val' could not be found
    var a = (string)val;          //works
    print (@"$a");
}

My temporary solution would be:

	string type_check(Value v){
		if (v.holds(typeof (string))) return "s";
		if (v.holds(typeof (int)))    return "i";
		if (v.holds(typeof (uint)))   return "ui";
		if (v.holds(typeof (char)))   return "c";
		if (v.holds(typeof (int64)))  return "i64";
		if (v.holds(typeof (bool)))   return "b";
        ...
	}

But it looks quite so-so, and produces a lot of duplicate code on the receiving side of type_check ().
UPD: Just found out that there is a function type_name() but it’s not much difference

var is only static type inference; the type is determined at compile time. Typically, you would just make methods with type suffixes (_string, _int64, etc.) because vala does not have function overloading.

Vala does have good support for GVariant though:

void do_something (Variant variant) {
    switch (variant.classify()) {
    case Variant.Class.STRING:
        print ("string %s\n", (string) variant);
        break;
    case Variant.Class.INT32:
        print ("int32 %" + int32.FORMAT + "\n", (int32) variant);
        break;
    default:
        break;
    }
}

void main () {
    do_something ("Hello World");
    do_something (42);
}

As you can see, you still need to dispatch on the type to use the value, but GVariant is serializable, so you could actually store the variant directly in the database.

Ty for answear. I good with thats vala doesnt support func overloading, think its even better, but all this situation looks sad. I already make it like this

public void add(Value data, string tableName=""){
...
        var typeName = data.type_name();
        string val = "";
        switch (typeName) {
            case "gint":      { val = @"$((int)data)";    break;}
            case "gchararray":{ val = quoting((string)data);    break;}
            case "gboolean":  { val = @"$((bool)data)";   break;}
            case "gdouble":   { val = @"$((double)data)"; break;}
            default: error("unknown type");  break;
        }

        query = @"CREATE TABLE IF NOT EXISTS $tableNameFinal (temp);\n" + 
                @"INSERT INTO $tableNameFinal VALUES ($val)";

...

}

It would be better to use prepared statements instead of building the query as a string.

FWIW, I am doing this in Rygel’s DB layer:

https://gitlab.gnome.org/GNOME/rygel/blob/rygel-0-36/src/librygel-db/database-cursor.vala#L71

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.