CHANGELOG.md in alf-0.9.3 vs CHANGELOG.md in alf-0.10.0

- old
+ new

@@ -1,164 +1,290 @@ -# 0.9.3 / FIX ME +# 0.10.0 / 2011-08-15 -* New operators (available both in shell and in Lispy DSL) +## New recognized data sources - * Added MATCHING and NOT MATCHING operators. These operators are useful - shortcuts for the following expressions. - - (matching l, r) := (project (join l, r), [l's attributes]) - (not_matching l, r) := (minus l, (matching l, r)) +* Alf now provides an Environment implementation on top of a SQL database. + This means that SQL tables can now be used as data-sources. This feature + relies on the sequel gem ('gem install sequel' is required), that drives + recognized SQL servers. Then (don't forget that ALF_OPTS also exists): + + % alf --env=postgres://user:password@host/database show table + +* Alf now recognizes and allows manipulating .csv files as first-class data + sources. CSV output is also supported of course. Under ruby <= 1.9, the + fastercsv gem is required ('gem install fastercsv' is required). Then: + + % alf restrict suppliers.csv -- "city == 'Paris'" (input) + % alf show suppliers --csv (output) + +* Alf now recognizes and allows manipulating .log files as first-class data + sources. This feature relies on request-log-analyzer gem that provides the + parsers that Alf uses, and the log formats it recognizes + ('gem install request-log-analyzer' is required). See examples/logs. + +## New operators and enhancements + +* A GENERATOR operator is introduced. It allows generating a relation with one + auto-number attribute, up to a given size. + +* A COERCE operator is introduced. It provides a quick way to obtain type-safe + relations from type-unsafe sources like .csv files. For example: + + % alf coerce mydirtyfile.csv -- name String price Float at Time - For example: - - # Give suppliers that supply at least one part - (matching suppliers, supplies) + The coerce operator is of course available in Ruby as well: + + (coerce "mydirtyfile.csv", :name => String, :price => Float, :at => Time) + +* The DEFAULTS (non-relational) operator now accepts default values as tuple + expressions. When used in shell, provided default values are now evaluated + that way. This allows specifying default values as being computed on the + current tuple. - # Give suppliers that don't supply any part - (not_matching suppliers, supplies) +* Aggregations in the Lispy DSL must not be prefixed by Agg:: anymore. - * Added RANK operator. The RANK operator is useful for for computing quota - queries, as shown below. See 'alf help rank' for details. - - # Give the three heaviest parts - (allbut (restrict (rank :parts, [[:weight, :desc]], :pos), lambda{ pos < 3 }), [:pos]) +## Miscellaneous enhancements -* Enhancements when using Alf in shell +* Added 'alf --input-reader' to specify $stdin format (csv, rash, etc.) +* Added 'alf -Ipath' that mimics ruby's -I (add path to $LOAD_PATH before run) +* Lispy#run supports command arguments to be passed as a string +* Lispy#run supports piped commands, with '|' as in shell - * added alf's -r option, that mimics ruby's one (require library before run) +## Hurting changes to Lispy DSL (and therefore to Relation) - * When alf is invoked in shell using bin/alf (and only in this case), - ENV['ALF_OPTS'] is used a global options to apply as they were specified - inline: - - % export ALF_OPTS="--env=. --yaml" - % alf show suppliers - - is the same as - - % alf --env=. --yaml show suppliers - - * 'alf --help' now distinguish experimental operators from those coming from - the (much more stable) TUTORIAL D specification. The former should be used - with care as they specification may change at any time. +* The attribute-name syntax of aggregation operators has been removed. The Agg:: + prefix must not be specified anymore. -* Enhancements when using Alf in Ruby + Agg::sum(:qty) # !! error !! + Agg::sum{ qty } # !! error !! + sum{ qty } # simply, and only! - * Alf.lispy now accepts any argument recognized by Environment.autodetect; it - obtains its working Environment this way. Among others: +* The group aggregation operator has been removed. It will probably be replaced + in a future version. In the meantime, the GROUP relational operator allows + obtaining similar results. + +* Lispy syntax of CLIP has changed (when used with --allbut option) + + (clip :suppliers, [:name, :city], true) (before) + (clip :suppliers, [:name, :city], :allbut => true) (after) + +* Lispy syntax of DEFAULTS has changed (when used with --strict option) + + (defaults :suppliers, {:country => 'Belgium'}, true) (before) + (defaults :suppliers, {:country => 'Belgium'}, :strict => true) (after) + +* Lispy syntax of GROUP has changed (when used with --allbut option) + + (group :supplies, [:sid], :supplying, true) (before) + (group :supplies, [:sid], :supplying, :allbut => true) (after) + +* Lispy syntax of PROJECT has changed (when used with --allbut option) + + (project :suppliers, [:name, :city], true) (before) + (project :suppliers, [:name, :city], :allbut => true) (after) + +* Lispy syntax of SUMMARIZE has changed (when used with --allbut option) + + (summarize :supplies, [:qty, :pid], {...}, true) (before) + (summarize :supplies, [:qty, :pid], {...}, :allbut => true) (after) + +## Hurting changes in shell + +* The attribute-name syntax of aggregation operators has been removed + + sum(:qty) # !! error !! + sum{ qty } # works + +* Shell syntax of GROUP has changed (option separator before introduced name) + + % alf --text group supplies -- pid qty supplying (before) + % alf --text group supplies -- pid qty -- supplying (after) + +* Shell syntax of WRAP has changed (option separator before introduced name) + + % alf --text wrap suppliers -- city status loc_and_status (before) + % alf --text wrap suppliers -- city status -- loc_and_status (after) + +* Shell syntax of QUOTA has changed (--by and --order become pure arguments) + + % alf quota supplies --by=sid --order=qty -- position count sum_qty "sum{ qty }" (before) + % alf quota supplies -- sid -- qty -- position count sum_qty "sum{ qty }" (after) + +* Shell syntax of RANK has changed (--order becomes a pure argument) + + % alf rank parts --order=weight,desc,pid,asc -- position (before) + % alf rank parts -- weight desc pid asc -- position (after) + +* Shell syntax of SUMMARIZE has changed (--by becomes a pure argument) + + % alf summarize supplies --by=sid -- total_qty "sum{ qty }" (before) + % alf summarize supplies -- sid -- total_qty "sum{ qty }" (after) + +## Bug fixes + +* [In shell] Options are now correctly parsed in presence of option separators. + That is, every argument after a '--' separator is considered a non-option + argument. + +# 0.9.3 / 2011-07-23 + +## New operators (available both in shell and in Lispy DSL) + +* Added MATCHING and NOT MATCHING operators. These operators are useful + shortcuts for the following expressions. + + (matching l, r) := (project (join l, r), [l's attributes]) + (not_matching l, r) := (minus l, (matching l, r)) - Alf.lispy(Alf::Environment.folder("path/to/an/existing/folder")) - - is the same as: - - Alf.lispy("path/to/an/existing/folder") + For example: + + # Give suppliers who supply at least one part + (matching suppliers, supplies) - * Added Relation::DUM and Relation::DEE constants (relations of empty heading - with no and one tuple, respectively). They are also available as DUM and DEE - in Lispy functional expressions. + # Give suppliers who don't supply any part + (not_matching suppliers, supplies) + +* Added RANK operator, which is useful for for computing quota queries as + illustrated below. See 'alf help rank' for details. - * Added a Heading abstraction, as a set of attribute (name, type) pairs + # Give the three heaviest parts + (restrict (rank :parts, [[:weight, :desc]], :pos), lambda{ pos < 3 }) -* Internal enhancements (extension points) +## Enhancements when using Alf in shell - * The Reader and Renderer classes now accept a Hash of options as third - argument of the constructor (friendly varargs applies there). These options - can be used by extension points. - - * The Environment class now provides a class-based registering mechanism 'ala' - Reader and Renderer. This allows auto-detecting the target environment when - --env=... is used in shell. See Environment.autodetect and - Environment#recognizes? for contributing to this extension point. - - * Internals now rely on Myrrha for code generation. This means that all - datatypes can now be safely used in relations and dumped to .rash files in - particular. +* added 'alf -r', that mimics 'ruby -r' (require library before run) -* Bug fixes +* When alf is invoked in shell (and only in this case), ALF_OPTS is used as + global options to apply as if they were specified inline: + + % export ALF_OPTS="--env=. --yaml" + % alf show suppliers + + is the same as + + % alf --env=. --yaml show suppliers + +* 'alf --help' now distinguishes experimental operators (quota in particular) + from those coming from the (much more stable) **Tutorial D** specification. The + former should be used with care as their specification may change at any + time. - * Added Relation#allbut, forgotten in two previous releases - * Fixed (join xxx, DEE) and (join xxx, DUM) - * Fixed scoping bug when using attributes named :path, :expr or :block in - Lispy compiled expressions (coming from .alf files) - * Fixed 'alf --yaml show suppliers' that renderer a --text table instead of - a yaml output - * Fixed bugs when using Date and Time attributes with .rash files - * Fixed bugs when using Date and Time attributes in restrict expressions - compiled from the commandline - * Fixed a few bugs when using attribute names that are ruby keywords - (restrict & extend) +## Enhancements when using Alf in Ruby +* Alf.lispy now accepts any argument recognized by Environment.autodetect; it + obtains its working Environment that way. Among others: + + Alf.lispy(Alf::Environment.folder("path/to/an/existing/folder")) + + is the same as: + + Alf.lispy("path/to/an/existing/folder") + +* Added Relation::DUM and Relation::DEE constants (relations of empty heading + with no and one tuple, respectively). They are also available as DUM and DEE + in Lispy functional expressions. + +* Added a Heading abstraction, as a set of attribute (name, type) pairs. + +## Internal enhancements (extension points) + +* The Reader and Renderer classes accept a Hash of options as third + constructor argument. These options can be used by extension points. + +* The Environment class now provides a class-based registering mechanism 'ala' + Reader and Renderer. This allows auto-detecting the target environment when + --env=... is used in shell. See Environment.autodetect and + Environment#recognizes? for contributing to this extension point. + +* Internals now rely on Myrrha for code generation. This means that all + datatypes can now be safely used in relations and dumped to .rash files in + particular. + +## Bug fixes + +* Added Relation#allbut, forgotten in two previous releases +* Fixed (join xxx, DEE) and (join xxx, DUM) +* Fixed scoping bug when using attributes named :path, :expr or :block in + Lispy compiled expressions (coming from .alf files) +* Fixed 'alf --yaml show suppliers' that renderer a --text table instead of + a yaml output +* Fixed bugs when using Date and Time attributes with .rash files +* Fixed bugs when using Date and Time attributes in restrict expressions + compiled from the commandline +* Fixed a few bugs when using attribute names that are ruby keywords + (restrict & extend) + # 0.9.2 / 2011.07.13 -* Bug fixes +# Bug fixes - * Fixed the "alf show" command (undefined method `chain') +* Fixed the "alf show" command (undefined method `chain') # 0.9.1 / 2011.07.13 -* Enhancements (public APIs) +## Enhancements (public APIs) - * Added the in-memory Alf::Relation data structure and associated tooling. - This allows using Alf in a object-oriented usual way, in addition to the - functional DSL: - - Alf.lispy.evaluate { - (join (restrict :suppliers, lambda{ status > 10 }), :cities) - } - - is equivalent to - - suppliers, cities = [...], [...] - suppliers.restrict(lambda{ status > 10 }).join(cities) - - see README about how to obtain suppliers and cities relations in the first - place. +* Added the in-memory Alf::Relation data structure and associated tooling. + This allows using Alf in a object-oriented usual way, in addition to the + functional DSL: - * Summarize now accepts a --allbut option, to specify 'by' attributes from an - exclusion perspective + Alf.lispy.evaluate { + (join (restrict :suppliers, lambda{ status > 10 }), :cities) + } + + is equivalent to + + suppliers, cities = [...], [...] + suppliers.restrict(lambda{ status > 10 }).join(cities) + + see README about how to obtain suppliers and cities relations in the first + place. - * .alf files are now evaluated in such a way that backtraces are "traceability - friendly" +* Summarize now accepts a --allbut option, to specify 'by' attributes from an + exclusion perspective -* Non backward-compatible changes to public APIs +* .alf files are now evaluated in such a way that backtraces are "traceability + friendly" - * Lispy#with has been removed because not being stable enough. The clean way - of reusing sub-queries is as follows (non purely functional, so far) - - kept_suppliers = (restrict :suppliers, lambda{ status > 10 }) - with_countries = (join kept_suppliers, :cities) - supplying = (join with_countries, :supplies) - (summarize supplying, - [:country], - :which => Agg::group(:pid), - :total => Agg::sum{ qty }) - - * As a consequence, named data sources (Symbols, like :suppliers above) are - now resolved at compile time, which is less powerful, yet much simpler and - sound. +## Non backward-compatible changes to public APIs - * Nest and Unnest have been renamed to Wrap and Unwrap respectively. This is - to better conform to TUTORIAL D's terminology. - - * Lispy#chain was kept public in 0.9.0 by error and has been entirely removed - from the DSL. +* Lispy#with has been removed because not being stable enough. The clean way + of reusing sub-queries is as follows (non purely functional, so far) + + kept_suppliers = (restrict :suppliers, lambda{ status > 10 }) + with_countries = (join kept_suppliers, :cities) + supplying = (join with_countries, :supplies) + (summarize supplying, + [:country], + :which => Agg::group(:pid), + :total => Agg::sum{ qty }) + +* As a consequence, named data sources (Symbols, like :suppliers above) are + now resolved at compile time, which is less powerful, yet much simpler and + sound. -* Enhancements (internals) +* Nest and Unnest have been renamed to Wrap and Unwrap respectively. This is + to better conform to **Tutorial D**'s terminology. + +* Lispy#chain was kept public in 0.9.0 by error and has been entirely removed + from the DSL. - * Reader.reader delegates to Reader.coerce when its first argument is not - a String. This allows calling Reader.reader(args.first || $stdin) in quickl - commands for example. +## Enhancements (internals) + +* Reader.reader delegates to Reader.coerce when its first argument is not + a String. This allows calling Reader.reader(args.first || $stdin) in quickl + commands for example. + +* Operator, Operator::Relational and Operator::NonRelational have a .each + class method that yields operator classes - * Operator, Operator::Relational and Operator::NonRelational have a .each - class method that yields operator classes - -* Bug fixes +## Bug fixes - * Fixed a bug that led to an Nil error when using unary operators on $stdin - * Fixed a bug when summarizing or sorting on Symbol attributes with ruby 1.8 - * Fixed numerous crashes under rubinius +* Fixed a bug that led to an Nil error when using unary operators on $stdin +* Fixed a bug when summarizing or sorting on Symbol attributes with ruby 1.8 +* Fixed numerous crashes under rubinius # 0.9.0 / 2011.06.19 -* Enhancements +## Enhancements - * Birthday! +* Birthday!