todo: - fix AR again - blocks for joins - fix sql insertions - implement mnesia adapter - CLEANUP!!!!! - rename externalize to derived. - deal with table tests in algebra - fix grouping - audit unit coverage of algebra - data objects - remove all explicit aliasing - scoped writes - refactor adapter pattern - break out adapters into sep modules - projection is by definition distincting? - union/intersection - cache expiry on write - transactions done: - and/or w/ predicates . Relation <=> Relation -> InnerJoinOperation . Relation << Relation -> LeftOuterJoinOperation . InnerJoinOperation.on(*Predicate) -> InnerJoinRelation . LeftOuterJoinOperation.on(*Predicate) -> LeftOuterJoinRelation . Relation[Symbol] -> Attribute . Relation[Range] -> Relation . Attribute == Attribute -> EqualityPredicate . Attribute >= Attribute -> GreaterThanOrEqualToPredicate . Relation.include?(Column) -> Predicate . Relation.project(*Column) -> ProjectRelation . Relation.select(*Predicate) -> SelectionRelation . Relation.order(*Column) -> OrderRelation . #to_sql . Remove Builder . Namespace . Audit SqlAlchemy for missing features - Generalized denormalizations on any aggregation (count, yes, but also max, min, average) - Remove operator overloading of << and <=> for joins. Make it just foo.join(bar) and foo.outer_join(bar). - Remove operator overloading of == for predicates. make it a.eq(b) (note lack of question mark). - hookup more predicates (=, <=, =>) - get some basic aggregations working: users.project(user[:points].max) - Alias Table Names - When joining with any sort of aggregation, it needs to be a nested select - get a value select working: users.project(users[:name], addresses.select(addresses[:user_id] == users[:id]).project(addresses[:id].count)) - Session - sublimate values to deal with the fact that they must be quoted per engine - clean-up singleton monstrosity - extract hashing module - hash custom matcher - make session engine stuff follow laws of demeter - currently doing some odd method chaining? rethink who is responsible for what - session just calls execute, passing in a connection; by default it gets a connection from the relation. - #formatter is now on value, attribute and relation; you must admit it's name is confusing given that e.g., relation already has a formatter (Sql::Relation) ... should it be called predicate formatter? operand1.to_sql(operand2.predicate) maybe prefer operand1.cast(operand2) or project or in light of - renamed to #format: operand1.format(operand2) - rename sql strategies - need to_sql for ranges - {:conditions=>{:id=>2..3}} - nested orderings - string passthrough - conditions - orderings - relation inclusion when given an array (1,2,3,4) should quote the elements using the appropriate quoting formatter taken from the attribute - descend on array, along with bind written in terms of it - re-evaluate bind -- does bind belong inside the relation / predicate classes or in the factory methods? - string passthrough: :joins=>"INNER JOIN posts ON comments.post_id = posts.id" - finish pending tests - test relation, table reset - test Value, in particular bind. - test blank checks in relation.rb - rename active_relation to arel - mock out database - fix complex joining cases: - active record query adapter - anonymous table names - Explicitly model recursive structural decomposition / polymorphism - Explicitly model the namer/externalizer using interpreter jargon - All Sql Strategies should be accumulations with the top-level relation? - instance methodify externalize - test: find_attribute_given_attribute and all @attribute ||= everywhere and memoization of table class. - rename select to where - rename all ion classes - joining with LIMIT is like aggregations!! - blocks for non-joins - expressions should be class-based, and joins too, anything _sql should be renamed - implement in memory adapter - clean up block_given stuff - reorganize sql tests - recursive memory operations - reorganize memory tests - result sets to attr correlation too - implement joins in memory - result sets should be array relations - fix AR - insertions for in memory - cross-engine joins icebox: - #bind in Attribute and Expression should be doing a descend? - try to make aggegration testing in join spec to be a bit more unit-like - standardize quoting - use strings everywhere, not symbols ? - "unit" test sql strategies - use real world examples, so they should be like a tutorial. - rename the tion (Selection) classes so that words that don't end in tion don't seem inconsistent - consider this code from has_many: # replace the SELECT clause with COUNT(*), preserving any hints within /* ... */ @reflection.options[:counter_sql] = @reflection.options[:finder_sql].sub(/SELECT (\/\*.*?\*\/ )?(.*)\bFROM\b/im) { "SELECT #{$1}COUNT(*) FROM" } - lock - SELECT suchandsuch FOR UPDATE - joins become subselects in writes: users.delete().where( addresses.c.user_id== select([users.c.id]). where(users.c.name=='jack') )