Created
November 23, 2011 02:31
-
-
Save FestivalBobcats/1387748 to your computer and use it in GitHub Desktop.
beginning of a DSL for me to abuse embedding and linking in MongoDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Facets are little bits of info about visitors | |
# Each facet has it's own Mongo collection; however, | |
# Essential attributes of the facet are imbedded in an Impression. | |
# This greatly improves performance by avoiding extraneous lookups, | |
# but also links Facets to their respectful impressions, much like | |
# facet :has_many => :impressions | |
# The containing module serves to provide "facet definitions" -- | |
# A DSL for creating the essential skeleton of a facet | |
module Arbiter | |
class << self | |
attr_accessor :facets | |
end | |
self.facets = [] | |
module Facets | |
# Meta-magic for the syntactically lip-smacking DSL below | |
def self.method_missing(meth, *args, &blk) | |
if meth.to_s[/^[A-Z]/]# && args[0] && blk | |
colname = args[0] | |
# Instantiate a new facet class | |
eval "#{meth} = Class.new" | |
# Extend facet class | |
class << klass = Kernel.const_get(meth) | |
attr_reader :param_keys | |
attr_reader :parse_proc | |
attr_reader :key | |
def key(k) | |
@key = k | |
end | |
def parse(*k, &proc) | |
@param_keys = k | |
@parse_proc = proc | |
end | |
# Parse parameter values into Impression-mergeable hash | |
def parse_params(params) | |
vals = @param_keys.select {|k| params[k] && !params[k].empty? } | |
if vals.all? | |
{ @key => @parse_proc.call(*vals) } | |
end | |
end | |
end | |
# Apply constructor definitions to facet class | |
blk.call(klass) | |
Arbiter.facets << klass | |
Collection.register(colname, klass) | |
else | |
super(meth, *args, &blk) | |
end | |
end | |
# Facet Definitions_________________________________________ | |
Region('regions') do | |
key :l | |
parse(:ip) do |ip| | |
geo = GeoIP.get_location(ip) | |
if geo.location | |
{ :_id => geo.location['_id'], :f => geo.region.f } | |
end | |
end | |
end | |
Referrer('refs') do | |
key :r | |
parse do |url| | |
ref = @collection.find_or_create('url' => url) | |
{ :_id => ref.id, :f => ref.url } | |
end | |
end | |
ScreenRes('screens') do | |
key :sr | |
parse(:sx, :sy) do |x, y| | |
@collection.find_or_create_from_dim(x, y).id | |
end | |
end | |
Agent('agents') do | |
key :a | |
parse do |raw| | |
agent = @collection.find_or_create('raw' => raw) | |
{ :_id => agent.id, :f => agent.raw } | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment