dquery 0.1.4

A neat little wrapper for convenient type information in D.

To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:

dquery - Chainable compile-time metaprogramming

dquery is a light helper for processing types, traits, and other information at compile time. It provides filtering, mapping, iteration, and validation functions for queried types and members.

Example Code

Here's a little demo class we're going to query in these examples. Assume the types for @Id and @Column are structs defined elsewhere.

class User
    ulong id;

    string username;

    string email;


The query!() template function produces a query for a type. This is the starting point for every dquery chain.

auto elements = query!User;

You can also query a type from a value via the query() function, shown here using UFCS.

User user = new User;

auto elements = user.query;

Simple Filters

dquery provides filters for the 5 common types of members defined in types; fields, functions, constructors, destructors, and aggregates.

// Filter fields in User.
auto fields = query!User.fields;

// Filter functions in User.
auto functions = query!User.functions;

// Filter constructors in User.
auto constructors = query!User.constructors;

// Filter destructors in User.
auto destructors = query!User.destructors;

// Filter inner types in User.
auto aggregates = query!User.aggregates;

Simple Validations

dquery also provides simple functions to perform validations without breaking chains.

auto elements =

        // Filter fields,

        // That have @Id and @Column,
        .allOf!(Id, Column)

        // Ensure exactly 1 exists.
            .exactly!(1, "User needs exactly 1 @Id.");

Chaining Logic

dquery focuses on chainable functions so that complex logic can be broken down into the sequence

auto elements =

        // Filter constructors,

        // With arity 0,

        // Ensure at least 1 exists,
            .minimum!(1, "User needs a 0 argument constructor.")

        // Clear filters,

        // Filter constructors,

        // That accept User,

        // Ensure none exist.
            .maximum!(0, "User must not define a copy constructor.");

Loops and Iteration

Query results can be iterated over with a foreach.

foreach(element; elements)
    static if(element.isTypeOf!string)
        // Handle fields.
        // Do something else.

You can also use the each!() template function to iterate over results without breaking a chain.

auto elements =

        // Filter fields,

        // That have @Id or @Column,
        .anyOf!(Id, Column)

        // Ensure at least 1 exists.
            .minimum!(1, "User needs at least 1 @Id or @Column.")

        // Do something for each,
            field => doSomething(field)

        // Keep going...


dquery includes a filter!() for custom or advanced filtering in chains.

auto elements =

        // Custom filter.
        .filter!(element =>
            element.isTypeOf!string ||

dquery also includes a map!() transform function for transforming the result of a chain.

string[] names =

        // Filter fields,

        // That have @Id or @Column,
        .anyOf!(Id, Column)

        // Map to their names.
        .map!(field => field.name);

All dquery transform functions can take a function or delegate, or a template.

Joining Results

Mutliple chains can be joined together to produce even more complex queries easily.

auto elements =

        // Filter fields,

        // That have @Id or @Column,
        .anyOf!(Id, Column)

        // And are a string,

        // Join with,

                // Filter functions,

                // With both @Column and @Mappable,
                .allOf!(Column, Mappable)

                // And arity 0,

                // That return a string.

You can also use a query's unique property to remove any duplicate elements.


dquery also provides functions for handling attributes attached to queried types and elements.

// Iterate over the list of elements,
foreach(element; elements)
    // Iterate over each attribute that is a @Column,
    foreach(attribute; element.attributes!Column)
        // Get value of attribute, or use a fallback if it's a type.
        Column column = attribute.value!(Column(element.name));

        // . . .


Because of how traits are setup in D, dquery can't operate on private or protected types, fields, or functions. Querying a type will only produce its public members.

  • Mihail K.
0.1.8 2015-Sep-29
0.1.7 2015-Sep-29
0.1.6 2015-Jul-18
0.1.5 2015-Jul-13
0.1.4 2015-Jul-11
Show all 10 versions
Download Stats:
  • 0 downloads today

  • 0 downloads this week

  • 0 downloads this month

  • 341 downloads total

Short URL: