fnc12/sqlite_orm

API has changed a bit : what is c<Type>?

juandent opened this issue · 1 comments

In column aliases, there is a relatively new way of doing things and I just wanted to make sure I understand it. The code is like this:

   struct LastResult : Result {};
   constexpr auto last_result = c<LastResult>();
    std::string sql = storage.dump(select(columns(last_result->*&LastResult::id, last_result->*&LastResult::stamp)));

Documentation says c<> creates a table reference...what is that?

Furthermore it says:

 /*
  *  Identity wrapper around a mapped object, facilitating uniform column pointer expressions.
  */
 template<class O>
 struct table_reference : std::type_identity<O> {};

What are uniform column pointer expressions? I assume this came up to support CTE?

Thanks

  1. Table reference: A table reference is a means of hoisting a C++ class ("mapped" as a table) into sqlite_orm's type system, and facilitates legible notation of explicit "column pointers", using the over-loadable pointer-to-member operator->*().
  2. Uniformity: With CTEs you end up using a lot of explicit column pointers. The pointer-to-member operator->*() provides a very legible notation compared to column<>().
    But then we would have 3 different notations of explicitly referring to a column: column<X>(&X::x) for "mapped" classes, alias_column<A>(&X::id) for aliased tables, x_cte->*&X::id for CTEs.
    Being able to use the same notation using the pointer-to-member operator->*() for all is what I called "Uniform column pointer expressions".

You see the benefits of this notation in the description of PR #1247.

I would argue that explicit column pointer notation should be used before all others and should even be the canonical way. Writing SQL expressions requires less thinking and follows the same concept of "referencing columns"/"referring to columns" in all cases:

  1. You define a "moniker" for a result set, i.e. either table, aliased result set, or CTE.
  2. Then work with the columns of a result set using this defined moniker.

Short history for your edification:
Table references, the new way of defining tables aliases and uniform column pointer expressions arrived after the CTE feature, they were just merged before (see PR #1247 and #1144). I recognized the pattern of forming column pointers that refer to a column mapped into a CTE, using the strange but very convenient pointer-to-member operator->*(). Extending the same syntactic sugar notation to aliased tables and result sets, the original column pointers felt like 2nd-class citizens. That's when "table references" came into existence.