Changes between Version 200 and Version 201 of WikiStart


Ignore:
Timestamp:
Mar 19, 2019, 9:48:24 PM (5 weeks ago)
Author:
jtv
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WikiStart

    v200 v201  
    3232
    3333
    34 == 2019-01-20: Big changes coming ==
    35 
    36 We're getting close to a 6.3 release, which introduces some important new features.  But it also gets us ready for some big '''incompatible changes''' in 7.0.  Beyond that, I have what could be a theme for 8.0.  Let's go through these one by one:
    37 
    38 === What's new in 6.3 ===
    39 
    40 Thanks to some major contributions from Joseph "!JadeMatrix" Durel, we now have:
     34== 2019-03-19: Recent changes ==
     35
     36Thanks to some major contributions from Joseph "!JadeMatrix" Durel in 6.3.0, we now have:
    4137
    4238Type-safe replacements for `tablereader` and `tablewriter`: `stream_from` and `stream_to`.  They support tuples (or tuple-like types) to represent database rows on the client side, so you could stream a `std::tuple` or `std::vector` straight into a database row, or vice versa.
     
    5450
    5551
    56 === Preparing for 7.0 ===
     52== 2019-03-19: Preparing for 7.0 ==
    5753
    5854We'll see some profound change in libpqxx 7.0.  Some of details still have to be worked out, but in 6.3 you'll start seeing deprecation warnings for features that will no longer work as before.
    5955
    6056
    61 ==== C++ upgrade ====
     57=== C++ upgrade ===
    6258
    6359C++11 has been great, but now I want more.  There are some wonderful things we can do if we bump the minimum requirement to C++17.  Is your compiler ready for them?
     
    6662 * `std::optional` as the one standard way to accommodate null values.
    6763 * Nested namespaces.  It'll make `pqxx::internal` easier for me to manage.
    68  * `std::string_view` may become really important later on; see my "libpqxx 8" plans below.
    69  * `std::to_chars` and `std::from_chars` could replace `a lot` of libpqxx code.
     64 * `std::string_view` will replace a lot of `std::string`.
     65 * `std::to_chars` and `std::from_chars` will replace `a lot` of libpqxx code.
    7066
    7167If your compiler is not ready for any of these new features, please file a bug on the [https://github.com/jtv/libpqxx Github page] so I can avoid breaking your build.
    7268
    7369
    74 ==== Connection classes ====
    75 
    76 The `connection` class hierarchy is going to change drastically.  If you have defined your own custom connection classes, these will no longer work, and you will start to see deprecation warnings in libpqxx 6.3.  The new design is not final, but it will be a lot simpler than what we have now.  Some esoteric features are going to disappear, and in return you'll get a move constructor and a much easier class hierarchy to work with.
    77 
    78 The plan is to fold essentially the entire class hierarchy into one single class.  It will support the current built-in connection types, but it won't be extensible.  We have always had an API for defining your own connection policies, and the library uses it to implement different types of connections, but I've never heard of anyone else using this API to define their own connection types.  The existing built-in connection types will just be thin wrappers for the single connection class, and eventually the single connection class should replace them all.
    79 
    80 
    81 ==== Replacing lazyconnection and asyncconnection ====
     70=== Connection classes ===
     71
     72The `connection` class hierarchy is going to change drastically.  If you have defined your own custom connection classes, these will no longer work, and you will start to see deprecation warnings in libpqxx 6.3.  The new design is not final, but it will be a lot simpler than what we have now.  Some esoteric features are going to disappear, and in return you'll get a move constructor, a type-safe destructor, and a much easier class hierarchy to work with.
     73
     74The plan is to fold the entire class hierarchy into one single class.  It will support the current built-in connection types, but it won't be extensible.  We have always had an API for defining your own connection policies, and the library uses it to implement different types of connections, but I've never heard of anyone else using this API to define their own connection types.  The existing built-in connection types will just be thin wrappers for the single connection class, and eventually the single connection class should replace them all.
     75
     76
     77=== Replacing lazyconnection and asyncconnection ===
    8278
    8379If you're using `lazyconnection` or `asyncconnection`, the API will change.  You'll have to do a bit of extra work.
     
    8581In older libpqxx versions, you got a connection object which looks just like a regular connection but only completes its actual connection to the database once you actually start using it.  Your code will have to go through an explicit check-or-wait step before using the connection.  It may end up looking similar to `std::future`, or it may just be a member function.  I'm not sure yet.
    8682
    87 
    88 ==== No more connection reactivation ====
    89 
    90 It's just a fact of life: network connections to the database can break.  It could happen because of a network problem, or the database may have been restarted.  The existing connection classes hide this from you.  They notice that the connection is broken and quietly try to re-establish it for you.  This feature is going to be removed.
    91 
    92 That may sound like a problem.  But your application already knows how to deal with a broken connection, right?  It may simply happen slightly more often.
    93 
    94 I believe doing it this way will make the application design issues clearer, eliminate a duplication of effort between libpqxx and your application, and clear out some dark corners where bugs might hide.  It will also remove an enormous source of complexity inside the connection classes.
    95 
    96 As a bonus, several operations on connection objects can finally get the `const` qualifier.  That's because they will no longer try to re-establish a broken connection, or finalise an incomplete lazy or asynchronous connection.  It will be a lot more obvious which operations make changes to your connection and which ones will not.  Some references in your code that don't look like they modify the connection may even become `const`.
    97 
    98 
    99 === A theme for 8.0? ===
    100 
    101 Kirit "!KayEss" Sælensminde has taught me a lot about C++ API performance.  And before he makes libpqxx obsolete with a library of his own, I'd like to give you some of his speedups myself.
    102 
    103 Here's what I have in mind.  (Your feedback would be welcome; feel free to file issues on the [https://github.com/jtv/libpqxx Github page].)
    104  * String conversions will change.  If you were defining your own `string_traits` types, you'll have to support some additional features.
    105  * You'll be able to avoid a lot of `std::string` copying, which is a major performance drag, at the cost of some convenience.
    106 
    107 I'm not quite sure how this will work yet.  One really simple idea is: a new version of `to_string` might accept a buffer of some kind, so it can write its output there without allocating a new one for you.  At a minimum it could take a `std::string` and reuse the storage it already has allocated.
    108 
    109 A more general idea is: you pass a lambda (or some other callable) to `to_string` as a new parameter.  Instead of just creating and returning a new `std::string`, `to_string` will construct its output ''in whatever form is convenient internally.''
    110 
    111 Then `to_string` calls your lambda, passing the output ''into'' it as (for example) a `std::string_view`, which is much cheaper than creating a new `std::string`.  The `to_string` call will return whatever your lambda returns.  The default lambda will simply construct a `std::string` and return it, so by default you keep the existing behaviour.
    112 
    113 As a silly example, let's say that you're writing numbers to a stream:
    114 {{{
    115 #!cpp
    116 for (auto i: items)
    117     stream << pqxx::to_string(i);
    118 }}}
    119 
    120 It's not very efficient for `to_string` to allocate a new buffer on the heap, for each `i`, just so its contents can immediately be copied into the internal buffer for `stream`.
    121 
    122 If `to_string` took a lambda, you could write something like:
    123 {{{
    124 #!cpp
    125 for (auto i: items)
    126     pqxx::to_string(i, [&stream](std::string_view text){ stream << text; });
    127 }}}
    128 
    129 This lets `to_string` construct its output in an efficient little buffer on the stack, and writes it straight to the `stream` buffer.  The `to_string` call doesn't even need to return a value.
    130 
    131 But there are some problems still.  In some cases it could be really helpful if the text buffer had a terminating zero byte.  Some `to_string` implementations may be able to provide that very cheaply, while it could be expensive for others.  Let me know what you think!
    132 
    133 
    134 == 2018-09-22: libpqxx turns 18 ==
    135 
    136 Today marks 18 years since I committed the first revision of libpqxx in its original CVS repo.  I later converted that repo to Subversion (svn), and imported it to Bazaar (bzr), and finally converted the Subversion repo to Git.  But amazingly, the 18-year revision history is still there.
    137 
    138 Happy birthday, libpqxx — you are now old enough to vote!
    139 
    140 It's been a real education to maintain my own code for 18 years.  ''The most important property'' a piece of code can have is '''clarity.'''  Not functionality, not correctness: you can fix those later, so long as the clarity is there.  To write software is to explain, to both computers and humans, a solution to a problem.
    141 
    142 Over 18 years you often find yourself wondering "what on Earth was I thinking when I wrote this?"  This code has provided me with a constant reminder that something which seemed perfectly obvious when you wrote it, can become a total mystery to you later.  Think kindly of the poor human who's struggling to understand your code, because it may be a future you.
    143 
    144 And so, I hope libpqxx today is clearer and more maintainable than it was even a few years ago.  C++11 helped a lot, and I hope to move the baseline to C++14 before too long.  C++17 will bring more radical improvements, streamlining the string conversions in particular, and maybe adding some optimisations.  The language is still evolving in wonderful ways, PostgreSQL is still getting better, and libpqxx has more changes to look forward to in its adult life.
     83Is this a major problem for you?  Please let me know by filing a bug on the Github page before it's too late!
    14584
    14685