Vala and Custom Widgets

There is a case when you wish to use a custom widget, when you use the same set of widgets to handle data. When you create a Gtk.ListBoxRow you have to attach to it a Gtk.Widget, in that case, should be easiest if you just do

var w = new MyWidget ();
w.data = data;

Second line, sets your data to the widget’s data property, so the class initialize the UI with the provided data.

In other case, you have a Widget you can re-use in different parts of the UI, maybe showed up in a popup window. This is the process you can use to create such a widget.

Create a Widget in Glade

Yes, use Glade to create a template UI file for your new widget, for the example, lets start with this simple user interface:

Key aspects is set Composite in order to define it as a Widget class definition, make sure you set Class Name to the same C name of your class, that is include the namespace, in our example the namespace is My so the widget class name is set to MyWidget.

Define your Class

Now, make sure you setup the Widget class to  use the UI  you will use. Name all entries and buttons, or any other UI elements you plan to use in your custom widgets at UI design time; use that name in your source code as follows:

Gtk.Entry evalue1 will be linked to your entry with the Id evalue1 so you can use it as any other variable. To link, use [GtkChild] annotation and [GtkTemplate]  one for the class, setting the attribute uiwith the name of the UI file in the resources file; in this case defined as:

UI file linked to the widget class, should be embedded in your program as a GLib resource. Set prefix to the path for the resource resolution, useful to classify different resources.

If you misspell the UI file or the ChildWidge‘s name you’ll get the following kind of errors:

Make it Interactive

Lets take a view at the bmultiply variable, linked to a Gtk.Button with the id set to, and how above code connect to its clicked signal to perform an operation and set the result to the text of the Gtk.Entry with the Id eresult  just accessing the variables defined as private in the My.Widget.

Base for your Class

Above widget, is a subclass of  Gtk.Box so you should make sure your top level widget in the UI definition is of the same type, as you can see at the Glade screenshot. You can take any other base class, depending on the functionality you want to start from.

GVls 0.14.0 Released

GNOME Vala Language Server, GVls, 0.14.0 has been released!

GVls has been integrated with GNOME Builder and now is its default Vala Language Server!

New features include:

* Completion: implementing filtering on partial words
* SourceView: on completion now provides just the position on code
* onChange: improved UTF-8 handling
* Server: can configure its defaults
* Server: request configuration after ‘initialized’ notification from the client
* Server: can handle configuration changes notifications
* Server: scan for all vala sources in workspace at initialization
* Server: can request configuration from Client
* Server: implemented diagnostics publication
* Server: can response both DocumentSymbol[] or SymbolInformation[] for textDocument/documentSymbol
* Server: search all symbols in a namespace
* Client: can provide build environment server configuration
* Client: expose Vala build settings at server initialization
* Client: can send configuration changes notifications
* Client: notify ‘initialized’ to the server
* Client: notify ‘didChangeConfiguration’ to the server
* ValaConfiguration: new Vala build environment settings object
* General fixes on Variant deserialization
* GNOME Builder: fixes to handle its requests
* API changes due to fixes

Current features will help to integrate GVls with other LSP clients like VSCode, implementing a Client to connect to GVls’s Server.

Now opening for 0.16 release cycle will include a refactoring of the server to share more common VAPI files like glib-2.0 and others.

Memory Footprint

For small projects like GVls or GXml, you have descent 150MB memory footprint and good response time, but for large projects like Vala, that will be increased to 6.9GB!!! unacceptable in my small resources machine, so we need to take action here!

Database driven storage can help on! Store parsed symbols in a database will help to share common used VAPI and reduce footprint on large projects with a possible impact on Server’s response time. My first is to use VDA to get access to simple SQLite or more powerful PostgreSQL servers (may you want to implement any other native or use existing GDA backend), some of the work has been made by Anjuta, so we can share databases or data model or make GVls the server for Anjuta.

Implementing a Vala Language Server

There is a Language Server Specification (LSP) published by Microsoft. Is a set of interfaces to manage information about a set of source files in an specific programming language, like symbols, classes, properties, variables, enumerations, and so on.

LSP uses JSON to communicate between a Server and a Client, so all interfaces must be translated to its counterpart in JSON before to transmit over. The communication is bidirectional, so when a request is sent from one side to another, a response is sent back with the result.

An LSP Client can used by Source Code Editors, like GNOME Builder or elementary’s code, or Anjuta, in order to provide specific services to the coder, like completion, goto symbol definitions, diagnostics, code formatting and others. A Client request all above services from a Server. This way, a source code editor can support multiple programming languages, just implementing an LSP Client and connect to an LSP Server.

Client and Server should cooperate in order to provide power full tools to the user. Some times one or other, provides limitations or the cooperation requires to changes in the source code editor design.

Anjuta for example, has implemented a database to track symbols definitions, this is no necessary as an LSP Client, because the Server should track them for you. Client just need to request if a symbol is found and get back its type and children (a very common concept on Object Oriented Programming Languages like Vala).

A Server requires lot of information from the Client, like the root directory and compilation flags used, so it can provide reliable diagnostics and, like in Vala, the --pkg switches in use so it can find the namespaces in use for both, completion and diagnostics.

Vala has its own Language Compiler and as many others, creates a tree of structured information about the code in order to translate it to C and then use another compiler to transform the resulted code to machine code. The Vala’s tree lot of the information we need to implement an LSP.

Recently GVls was accepted by GNOME Builder, as The Vala Language Server for source editing. It provides completion, goto definition and diagnostics, with more services coming.

There are improvements and new implementations in GVls to work on and hope a Client for Microsoft Visual Studio Code will be implemented soon.

Vala will be impacted by GVls for sure, in order to improve diagnostics messages, symbol resolution, completion and so on, just need to push it to its limits and find new opportunities for improvements.

GNOME Builder, has gained some new LSP implementations while integrating GVls and hope both projects found a way to provide more powerful features for Object Oriented Programmers. One area to work on, is on Vala Source Code Highlighting, in order to help programmers to know if an used symbol is correctly spelled by seeking for in the Server’s symbols database. Diagnostics is other one, where we need a way to introspect the Build System, in order to find Vala’s compiler’s switches in use, so we can improve error or warning messages.

JSON to/from GObject

In order to implement LSP in GVls, a new GVls.VariantObject interface to be implemented by any GObject class. It provides any GObject the capability to be converted to/from its GLib.Variant representation. In GVls we use JSON-GLIB, so a GLib.Variant is converted to JSON and back, so now you can use any JSON based service to serialize and parse information using, for example, JSON-RPC which in turn is the one used to implement a LSP Client and Server communication.

GNOME Calculator and GTK’s Entry

Recently GNOME Calculator has gained a library for math expression parsing and calculation, as a parallel effort to the one used internally for the application, called GCalc.

While GCalc allows to take a string to create an object oriented representation of it and can perform multi-precision calculations, this feature was unable to be used outside, just VDA is using it for math expression parsing, but no-more, yet.

In order to expose GCalc features to user oriented applications, now a new library called GCi was added. GCi provides, for now, a controller for GTK Entries.

GTK Entries controller in GCi, can add calculation features to your Entry. Once you have created a GCi.EntryController and set its entry property to the one in your UI application, a secondary icon using a calculator is added, while allows your users to  write =8*2+1, hit enter or click on the secondary icon and the math expression is replaced by its calculation result (and yes you should use = in order to establish it as a math expression to replace).

VDA 0.90 Beta 1 Released

Vala Data Access library has reached a 0.90 Beta 1 release.

VDA provides a set of interfaces to wraps database connection, execution of SQL commands and access to returned values of the queries. Read the previous introduction post.

This version supports:

  • First Beta version of VDA
  • Native implementation for PostgreSQL
  • GDA implementation with support for SQLite and PosgreSQL
  • Basic SqlValue implementation and conversion between values
  • Basic SQL commands parsing support for SELECT, INSERT, DELETE, UPDATE, using parameters in order to provide the values required to execute it
  • Object Oriented API for SQL commands: SELECT, INSERT, DELETE, UPDATE
  • Support for Parameters in queries using GDA declaration syntax
  • SQL command parsing use GCalc from GNOME Calculator
  • Async queries execution
  • Support to map Row’s values to GObject based classes’ properties using DataObject interface
  • Support for row modification/insert using DataObject interface
  • DataObject supports Vda.SqlValue properties, both generic or specific
  • DataObject support conversion between Vda.SqlValue values and between basic properties’ types like string, int, double, float, bool

No pre-releases was made, because the API was changed while implementing database providers and included most of the interfaces to implement for better more powerful features.

VDA return Vda.SqlValue objects when you access a Table’s row’s column’s value; the provider is responsible to create it when is requested, so no overhead is present for SQL queries execution.

GXml and on-the-fly-post-parsing technique

I think this is new, so I’ll describe a new technique used in GXml to parse a large set of nodes in an XML document.

Parsing Large XML documents

If you have a large XML document, with a root with a number of child nodes, the standard technique is read all of them, including the child’s children ones, to create the XML tree. This process can take a while.

New on-the-fly parser

GXml now has a new custom parser called StreamReader used to read the root element and its children, but without any attribute and without any child’s children; the attributes and the children’s children are stored in a string on-the-fly in order to read the document almost at the same time it is read from the IO stream, for the root and for each children, improving the loading time of large XML documents up to 400% times faster than the previous technique already present in GXml.

On-the-fly-post-parsing

By using this On-the-fly-post-parsing technique, You can’t access the child’s children or the root’s attributes immediately after first read, you have to parse it from a temporally location in the GXml.Element class, using the new GXml.Element.parse_buffer() method, this one use the standard method, already present in GXml, to parse the root’s properties and the children’s children. When GXml.Element.parse_buffer() is called over the root, all children’s children are parsed recursively, but you can choose to parse just one of the root’s child, making a really convenient technique when you need just one root’s child node in a large XML document.

Multi-threading parsing

Currently GXml.Element.parse_buffer_async(), when called on root’s element, uses GLib.ThreadPool to parse each child in a different thread each and uses as many as threads are usable (less one) in your system. The expected behavior is getting a parse boost over the standard technique using in GXml: Xml.TextReader from the veteran libxml2 library running over just one thread. Currently a standard time parsing is provided when GXml.Element.parse_buffer_async() is called on document’s root, this maybe is a limitation on libxml2, because we have lot of Xml.TextReader running at the same time parsing element’s children; or a limitation on GLib.ThreadPool. Maybe the solution is a step away.

How to map objects to databases

GDA stands for GNOME Data Access and is a library to wrap database connections and its data using GObject classes, you can execute queries and much more.

VDA stands for Vala Data Access, is a library providing a heavily object oriented API to access databases’s data.

The API developed for VDA is going to be:

  • Heavily Object Oriented
  • Asynchronous almost by default
  • Provides GObject to database mapping

Object Oriented

GDA uses lot of structures, they are hard to be introspectable, so hard to be used outside C and Vala.

Providers now are Connection objects, so you have to instantiate them and then call open and catch opened signal to know if you are up with the connection.

SQL statements now are Query objects, created from string and now from structured objects with simple API, they can use execute on itself to get a TableModel, AffectedRows or any other Result object. An object for almost all kind of SQL commands will be added, with a simple easy to use API to provides the data it needs to be executed over the Connection.

There are models for tables, rows and columns, some of them implementing GLib.ListModel, so can iterate over their members, like rows in a table or columns in a row.

Asynchronous

Database operations can take time to be executed on servers, locally or remote, so you now have all Query execution as async methods, so for opening connections.

API

As you can notice, some API are still in development for VDA, so you can use the one already working or access GDA’s Connection objects if you are using Providers from it.

Eventually all API will be implemented by native Connection objects, without bind GDA. Searching to provide an easy and fast way to access introspection data from databases.

Easy API for New Database Servers

Currently GDA implementation for Providers is hard to implement for new database servers. VDA provides a new easy to implement interfaces, for new database servers, so is possible to extend VDA by creating new libraries, without depend on plugins.

Map objects to databases

Recently, VDA gains Vda.DataObject interface, it provides mapping your object to database’s table’s row, where the row’s columns are mapped to object’s properties and back.

Vda.DataObject supports:

  • Gets data from the database, through a SELECT query execution
  • Sets data in a table’s row using an UPDATE command
  • Creates new rows in the tables using  an INSERT command
  • Removes a row in the table using a DELETE command

Best of all you just need:

  • Implement Vda.DataObject with just 3 properties
  • Mark your object’s properties you want to map to the database’s table’s row’s column, using its nick with a text like: @Property Name::id, this is: your field’s in the data base can have any supported name, including spaces, we use @ to mark a property as to be mapped and ::id to mark it as an ID property used to query from the database.

All queries to read/write data to the database will be calculated automatically for you. Your class should set a Vda.Connection and the table’s name, through Vda.DataObject.database_connection and Vda.DataObject.database_table properties, this last one just at construction time.

This an example on how your code could be seen. Pay attention at initialization() method, was added here to show you how the table is created in the database and how the data is mapped using compatible types, in this case string to variant. In the near feature, could be possible to add automatic table creation if it doesn’t exits yet.

public class Client : Object, Vda.DataObject {

    // Database mapping
    [Description (nick="@id::id")]
    public string id { get; set; }
    [Description (nick="@name")]
    public string name { get; set; }
    [Description (nick="@description")]
    public string description { get; set; }
    [Description (nick="@phone")]
    public string phone { get; set; }

    construct {
      database_table_name = "clients";
      id = GLib.Uuid.string_random ();
    }

    public async string initialization () throws GLib.Error {
      var qct = database_connection.parse_string ("CREATE TABLE IF NOT EXISTS clients (id varchar(50), name varchar(50), description varchar(50), phone varchar(50))");
      yield qct.execute (null);
      var qi = database_connection.parse_string ("INSERT INTO clients (id, name, description, phone) VALUES ('"+id+"','"+name+"','"+description+"','"+phone+"')");
      yield qi.execute (null);
      return id;
    }

    // DataObject
    public string database_table_name { get; construct set; }
    public Vda.Connection database_connection { get; set; }
    public Cancellable cancellable { get; set; }
  }


GDA 5.2.9 Released

GDA is the GNOME Data Access library, able you to use GObject like API to access database provides like PostgreSQL, SQLite and MySQL, among others like JDBC, running queries and get data in data models for your application use.

This new release is an effort to fix bugs in 5.2 stable branch, including:

  • Fix Sun JRE 1.8 detection
  • Fix JDK 11.0 detection
  • Drop unneeded JAVAH variable check
  • Fix build for System Installed SQLite libs
  • Non-Dates and Timestamps values returns ‘NULL’ string when converted
  • Fix –with-ui, now UI is buildable when enable

Expect more fixes as this version is available in LTS distribution versions and current master targeting 6.0 release is getting more and more fixed on memory leaks, than ever.

GDA Starts Beta Stage

GDA 6.0 Beta has been Released. Valgrind tests and memory leak fixes are in progress.

To reach Beta stage, some providers and tools, like GTK widgets, has been cataloged as experimental and disable by default.

Now we start a Beta stage, where translation continue and release notes is a work in progress.

Please test it. Thanks to all contributions, translators and reporters. Report any issue you find, thanks in advance.

GDA and disable old stuff

After hundred of commits, GDA is getting fixes for most of its bugs around SQLite, PostgreSQL and MySQL providers. Lot of modernization work has been landing in master, making GCC more and more happy avoiding warnings, some of them are present, yet.

To have a warning free release, GDA needs to modify some internals, hope they are not too invasive in order to avoid bugs.

Internals in GDA is a long history, started in January 2002, evolving and implementing stuff not available in GLib or GObject at that time. But the things have changed and now we have modern techniques to implement interfaces and objects, so a modernization was started since I took the maintainership.

GDA has lot of tools, like entire applications and command line (a la psql), allowing you  to access your data. The one I use the most is its GObject Introspection bindings through Python, to extract, manipulate and push to or from different databases providers; this was the main task on modernization: change the API to be more binding friendly, specially on GObject Introspection; I think it is in a better shape now.

Unfortunately, most tools are buggy, like GTK widgets and so its derived GUI tools, in a level that is difficult to fix with the limited resources we have; this is true for some providers, because they are outdated. This is the reason we have put them in the “experimental zone“, to reduce the burden.

The advantage is that putting things aside, will help to push 6.0 out to the streets in a more short time.

For 6.0, we need to think about if we will keep current API and a very difficult way to implement new in-tree providers; or we take a big step forward and create interfaces you allow out-of-tree plugins. But that will be a different post.