Codify
Transparently encodes text before saving to your database. Automatically encodes any desired text attributes for saving to database, and decodes when retrieving the field. Includes encoding for compression, encryption and error checking.
Many encodings can be useful, for example, compression can be useful for large text fields, to save disk space, encryption may be used to safeguard data.
This is not suitable if you plan to do fulltext searching directly on encoded attributes, although it can still be used where a separate fulltext search engine is used.
Currently, only activerecord is supported.
Installation
Add this line to your application''s Gemfile:
gem 'codify'
And then execute:
$ bundle
Or install it yourself as:
$ gem install codify
Usage
In general, to encode an attribute, just call attr_encoder
on the attribute:
class DataBlock < ActiveRecord::Base
attr_encoder :data, :encoder => :base64
end
Codify will now expect to save data to an encoded_data field. So you should add the column via a migration. Notice that we can now to save binary data to the database, and can use a text type, because of the Base64Encoder.
add_column :data_blocks, :encoded_data, :text
Now, you can easily read or write, and leave the encoding and decoding to Codify.
# writing
datablock = DataBlock.create(:data => "Data, could be binary, like these: \0\x43!")
# reading
datablock = DataBlock.first
datablock.data # => "Data, could be binary, ..."
You can change the default encoded attribute column name with :prefix and :suffix options.
Convenience methods for specific types of encoding are also available. For example, attr_compressor compresses an attribute.
class Page < ActiveRecord::Base
attr_compressor :body #, :encoder => :zlib # this is already the default for attr_compressor
end
Each method applies an appropriate set of default options:
Method | :encoder | :prefix | :encoder_type | :verb | :reverse_verb | Recommended Usage |
---|---|---|---|---|---|---|
attr_encoder | :none | encoded_ | :all | :encode | :decode | Encoding |
attr_compressor | :zlib | compressed_ | :compressor | :compress | :uncompress | Compression |
attr_digestor | :sha512 | digested_ | :digestor | :digest | :decode (not used) | Digest/Hashing |
Options
Options can be passed to some encoders. The exact options possible depend on the encoder. Probably the easiest way is just to pass them to attr_encoder when an encoded attribute is declared.
attr_compressor :body, :encoder => :zlib, :level => 9 # highest possible compression
They can also be passed when initializing an encoder object:
attr_compressor :body, :encoder => Codify::Encoders::ZlibEncoder.new(:level => 9)
Chaining Encoders
A number of encoders can be chained, to apply them one after the other for a single attribute.
class Page < ActiveRecord::Base
attr_compressor :body, :encoder => [:zlib, :base64]
end
This will first compress with ZlibEncoder, then encode the resulting binary with Base64Encoder.
Custom Encoders
If the included encoders are not sufficient, you can use your own, just inherit from Codify::Encoders::AbstractEncoder, and define encode and decode methods. To use options which may be passed to the encoder, just call options with a symbol.
class MyEncoder < Codify::Encoders::AbstractEncoder
def encode(data)
"#{options(:header)}#{data}#{options(:footer)}" # wrap data in header and footer
end
def decode(data)
data[options(:header).length...options(:footer).length] # remove header and footer from data
end
end
class Model < ActiveRecord::Base
attr_encoder :data, :encoder => MyEncoder
end
Instead of passing a class to attr_encoder, it is also possible to register custom encoders with a symbol.
Codify::Encoders.register :my_encoder, MyEncoder, :encoding
class Model < ActiveRecord::Base
attr_encoder :data, :encoder => :my_encoder, :encoder_type => :encoding
end
The :encoder_type option specifies a registration namespace which will be searched first for :my_encoder. The global registration namespace will only be searched after a specific namespace does not include the desired encoder. This can be useful if multiple encoders are given the same name. If they are in different namespaces, the can still be specified.
An encoder may also be registered by passing a block to register. This can be used to dynamically register a set of symbols.
Codify::Encoders.register MyEncoder do |symbol|
return MyEncoder if [:myencoder, :my_encoder, :MYENCODER].include?(symbol)
nil # if symbol is not found, return nil
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
License
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
Copyright (c) 2012 Ronald Ping Man Chan