I just now noticed the "force encoding" plugin. I had mentioned something like this not too long ago and I don't know if it influenced this functionality, but the fact that it got added in there is really, really nice. Thanks so much!
On Oct 1, 9:12 am, Jeremy Evans <[email protected]> wrote: > Sequel 3.5.0 has been released and should be available on the gem > mirrors. The 3.5.0 release adds numerous improvements: > > New Plugins > ----------- > > * A class_table_inheritance plugin has been added, supporting model > inheritance in the database using a table-per-model-class approach. > Each table stores only attributes unique to that model or subclass > hierarchy. > > For example, with this hierarchy: > > Employee > / \ > Staff Manager > | > Executive > > the following database schema may be used (table - columns): > > * employees - id, name, kind > * staff - id, manager_id > * managers - id, num_staff > * executives - id, num_managers > > The class_table_inheritance plugin assumes that the main table > (e.g. employees) has a primary key field (usually > autoincrementing), and all other tables have a foreign key of the > same name that points to the same key in their superclass's table. > For example: > > * employees.id - primary key, autoincrementing > * staff.id - foreign key referencing employees(id) > * managers.id - foreign key referencing employees(id) > * executives.id - foreign key referencing managers(id) > > When using the class_table_inheritance plugin, subclasses use joined > datasets: > > Employee.dataset.sql # SELECT * FROM employees > Manager.dataset.sql # SELECT * FROM employees > # INNER JOIN managers USING (id) > Executive.dataset.sql # SELECT * FROM employees > # INNER JOIN managers USING (id) > # INNER JOIN executives USING (id) > > This allows Executive.all to return instances with all attributes > loaded. The plugin overrides deleting, inserting, and updating > in the model to work with multiple tables, by handling each table > individually. > > This plugin allows and encourages the use of a :key option to mark > a column holding the class name. This allows methods on the > superclass to return instances of specific subclasses. > > a = Employee.all # [<#Staff>, <#Manager>, <#Executive>] > > This plugin requires the lazy_attributes plugin and uses it to > handle subclass specific attributes that would not be loaded > when calling superclass methods (since those wouldn't join > to the subclass tables). For example: > > a.first.values # {:id=>1, name=>'S', :kind=>'Staff'} > a.first.manager_id # Loads the manager_id attribute from the > # database > > The class_table_inheritance plugin requires JOIN USING and > therefore is not supported on H2 or Microsoft SQL Server, which do > not support that SQL-92 feature. > > * An associations_dependencies plugin was added for deleting, > destroying, or nullifying associated objects when destroying a > model object. This just gives an easy way to add the necessary > before and after destroy hooks. The following association types > support the following dependency actions: > > * :many_to_many - :nullify (removes all related entries in join > table) > * :many_to_one - :delete, :destroy > * :one_to_many - :delete, :destroy, :nullify (sets foreign key to > NULL for all associated objects) > > This plugin works directly with the association datasets and does > not use any cached association values. The :delete action will > delete all associated objects from the database in a single SQL > call. The :destroy action will load each associated object from the > database and call the destroy method on it. > > The plugin call takes a hash of association symbol keys and > dependency action symbol values. Alternatively, you can specify > additional dependencies later using add_association_dependencies: > > Business.plugin :association_dependencies, :address=>:delete > # or: > Artist.plugin :association_dependencies > Artist.add_association_dependencies :albums=>:destroy, > :reviews=>:delete, :tags=>:nullify > > * A force_encoding plugin was added that forces the encoding of > strings used in model instances. When model instances are loaded > from the database, all values in the hash that are strings are > forced to the given encoding. Whenever you update a model column > attribute, the resulting value is forced to a given encoding if the > value is a string. There are two ways to specify the encoding. > You can either do so in the plugin call itself, or via the > forced_encoding class accessor: > > class Album < Sequel::Model > plugin :force_encoding, 'UTF-8' > # or > plugin :force_encoding > self.forced_encoding = 'UTF-8' > end > > This plugin only works on ruby 1.9, since strings don't have > encodings in 1.8. > > * A typecast_on_load plugin was added, for fixing bad database > typecasting when loading model objects. Most of Sequel's database > adapters don't have complete control over typecasting, and may > return columns that aren't typecast correctly (with correct being > defined as how the model object would typecast the same column > values). > > This plugin modifies Model.load to call the setter methods (which > typecast by default) for all columns given. You can either specify > the columns to typecast on load in the plugin call itself, or > afterwards using add_typecast_on_load_columns: > > Album.plugin :typecast_on_load, :release_date, :record_date > # or: > Album.plugin :typecast_on_load > Album.add_typecast_on_load_columns :release_date, :record_date > > If the database returns release_date and record_date columns as > strings instead of dates, this will ensure that if you access those > columns through the model object, you'll get Date objects instead of > strings. > > * A touch plugin was added, which adds Model#touch for updating an > instance's timestamp, as well as touching associations when an > instance is updated or destroyed. > > The Model#touch instance method saves the object with a modified > timestamp. By default, it uses the :updated_at column, but you can > set which column to use. It also supports touching of associations, > so that when the current model object is updated or destroyed, the > associated rows in the database can have their modified timestamp > updated to the current timestamp. Example: > > class Album < Sequel::Model > plugin :touch, :column=>:modified_on, :associations=>:artist > end > > * A subclasses plugin was added, for recording all of a models > subclasses and descendent classes. Direct subclasses are available > via the subclasses method, and all descendent classes are available > via the descendents method: > > c = Class.new(Sequel::Model) > c.plugin :subclasses > sc1 = Class.new(c) > sc2 = Class.new(c) > ssc1 = Class.new(sc1) > c.subclasses # [sc1, sc2] > sc1.subclasses # [ssc1] > sc2.subclasses # [] > ssc1.subclasses # [] > c.descendents # [sc1, ssc1, sc2] > > The main use case for this is if you want to modify all models > after the model subclasses have been created. Since mutable > options are copied when subclassing, modifying parent classes > does not affect current subclasses, only future ones. The > subclasses plugin allows you get all subclasses so that you can > easily modify them. The plugin only records subclasses > created after the plugin call, though. > > * An active_model plugin was added, giving Sequel::Model an > ActiveModel complaint API, in so much as it passes the > ActiveModel::Lint tests. > > New Extensions > -------------- > > * A named_timezones extension was added, allowing you to use named > timezones such as "America/Los_Angeles" (the default Sequel > timezone support only supports UTC or local time). This extension > requires TZInfo. It also sets the Sequel.datetime_class to > DateTime, so database timestamps will be returned as DateTime > instances instead of Time instances. This is because ruby's > Time class doesn't support timezones other than UTC and local time. > > This plugin allows you to pass either strings or TZInfo::Timezone > instance to Sequel.database_timezone=, application_timezone=, and > typecast_timezone=. If a string is passed, it is converted to a > TZInfo::Timezone using TZInfo::Timezone.get. > > Let's say you have the database server in New York and the > application server in Los Angeles. For historical reasons, data > is stored in local New York time, but the application server only > services clients in Los Angeles, so you want to use New York > time in the database and Los Angeles time in the application. This > is easily done via: > > Sequel.database_timezone = 'America/New_York' > Sequel.application_timezone = 'America/Los_Angeles' > > Then, before timestamps are stored in the database, they are > converted to New York time. When timestamps are retrieved from the > database, they are converted to Los Angeles time. > > * A thread_local_timezones extension was added. This allows you to > set a per-thread timezone that will override the default global > timezone while the thread is executing. The main use case is for > web applications that execute each request in its own thread, and > want to set the timezones based on the request. The most common > example is having the database always store time in UTC, but have > the application deal with the timezone of the current user. That > can be done with: > > Sequel.database_timezone = :utc > # In each thread: > Sequel.thread_application_timezone = current_user.timezone > > This extension is designed to work with the named_timezones > extension. > > * An sql_expr extension was added that adds .sql_expr methods to > all objects, giving them easy access to Sequel's DSL: > > 1.sql_expr < :a # 1 < a > false.sql_expr & :a # FALSE AND a > true.sql_expr | :a # TRUE OR a > ~nil.sql_expr # NOT NULL > "a".sql_expr + "b" #... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sequel-talk" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/sequel-talk?hl=en -~----------~----~----~----~------~----~------~--~---
