Merge branch 'master' of https://dev.finn.de/git/reporting-engine
commit
3fb406aaf6
@ -1,63 +0,0 @@ |
||||
module Report::InheritedNamespace |
||||
NESTED_NAMESPACES = %w[Validation Filter GroupBy Result Operator QueryUtils] |
||||
|
||||
module Hook |
||||
def const_missing(name, *) |
||||
super |
||||
rescue ArgumentError => error |
||||
# require 'ruby-debug'; debugger |
||||
rescue NameError => error |
||||
load_constant name, error |
||||
end |
||||
end |
||||
|
||||
def self.activate |
||||
Report.extend self |
||||
NESTED_NAMESPACES.each { |n| n.extend self } |
||||
end |
||||
|
||||
def inherited(klass) |
||||
super |
||||
propagate klass |
||||
end |
||||
|
||||
def included(klass) |
||||
super |
||||
propagate klass |
||||
end |
||||
|
||||
def propagate(klass) |
||||
klass.extend Report::InheritedNamespace |
||||
klass.extend Hook |
||||
return unless klass < Report |
||||
NESTED_NAMESPACES.each do |name| |
||||
if file = ActiveSupport::Dependencies.search_for_file("#{klass.name}::#{name}".underscore) |
||||
require_or_load file |
||||
propagate klass.const_get(name) |
||||
else |
||||
const_missing name |
||||
end |
||||
end |
||||
end |
||||
|
||||
def load_constant(name, error = NameError) |
||||
zuper = (Class === self ? superclass : ancestors.second).const_get(name) |
||||
klass = case zuper |
||||
when Class then const_set name, Class.new(zuper) |
||||
when Module then const_set name, Module.new { include zuper } |
||||
else const_set name, zuper |
||||
end |
||||
propagate klass |
||||
klass |
||||
rescue NameError, ArgumentError => new_error |
||||
if file = ActiveSupport::Dependencies.search_for_file("#{self.name}::#{name}".underscore) |
||||
require_or_load file |
||||
const_get name |
||||
else |
||||
error.message << "\n\tWas #{new_error.class}: #{new_error.message}" |
||||
new_error.backtrace[0..9].each { |l| error.message << "\n\t\t#{l}" } |
||||
error.message << "\n\t\t..." if new_error.backtrace.size > 10 |
||||
raise error |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,71 @@ |
||||
## |
||||
# From Urban Dictionary: |
||||
# proactive (91 up, 9 down) |
||||
# |
||||
# Originally a psychological term indicating an empowered, self-reliant |
||||
# individual, this has evolved through misuse into a neo-antonym of 'reactive', |
||||
# and is used as such to emphasise the preferability of one attitude or course |
||||
# of action over another. It connotes alertness, awareness and preparedness, and |
||||
# seeks to dispel any conceivable impression of incompetence. |
||||
# |
||||
# 'Proactive' is interesting in that it is perhaps the classic example of the |
||||
# unnecessary neologism. It serves as an antonym to 'reactive', yet 'reactive' |
||||
# is itself the antonym of 'active'. |
||||
# |
||||
# Arguably, since 'proactive' is now perhaps more widely used than 'active' for |
||||
# the specific purpose covered by the newer word, 'proactive' must be recognised |
||||
# as a legitimate word. The cult of hatred that has understandably grown up |
||||
# around the word can only help it endure further. |
||||
# |
||||
# One is 'active' as opposed to being 'passive' or 'reactive'. One is |
||||
# 'proactive' as opposed to 'speaking English'. |
||||
module ProactiveAutoloader |
||||
extend self |
||||
|
||||
## |
||||
# Improved Module#autoload: |
||||
# * if path is not given, generate path according to ruby common sense |
||||
# * allow passing multiple constant names as symbols |
||||
# |
||||
# Example: |
||||
# autoload :Foo, :Bar, :Blah |
||||
def autoload(*list) |
||||
return super if list.size == 2 and String === list.last |
||||
list.each do |const| |
||||
super const, "#{name.underscore}/#{const.to_s.underscore}" |
||||
end |
||||
end |
||||
|
||||
## |
||||
# Sets up autoload hooks in +klass+ for all Ruby files in +dir+, following |
||||
# common naming conventions. Subdirectories are *not* scanned. |
||||
def setup_autoloaders(klass, dir) |
||||
Dir.glob File.expand_path('*.rb', dir) do |file| |
||||
klass.autoload File.basename(file, '.rb').camelize, file |
||||
end |
||||
end |
||||
|
||||
## |
||||
# If subclassed, say in foo/bar.rb and there is a directory foo/bar, |
||||
# set up autoload hooks in subclass for all ruby files in foo/bar |
||||
# (see setup_autoloaders). |
||||
def inherited(klass) |
||||
auto_setup_autoloaders(klass) |
||||
super |
||||
end |
||||
|
||||
## |
||||
# If extending a class, say in foo/bar.rb and there is a directory foo/bar, |
||||
# set up autoload hooks in subclass for all ruby files in foo/bar |
||||
# (see setup_autoloaders). |
||||
def self.extended(klass) |
||||
auto_setup_autoloaders(klass) if klass.respond_to? :autoload |
||||
super |
||||
end |
||||
|
||||
private |
||||
|
||||
def auto_setup_autoloaders(klass) |
||||
setup_autoloaders klass, caller[1][/^((?!\.[^\.]+:\d+).)+/] |
||||
end |
||||
end |
@ -1,13 +1,10 @@ |
||||
require 'forwardable' |
||||
require 'proactive_autoloader' |
||||
|
||||
class Report < ActiveRecord::Base |
||||
InheritedNamespace.activate unless defined? Rails && Rails.version =~ /^3./ |
||||
|
||||
extend ProactiveAutoloader |
||||
extend Forwardable |
||||
include Enumerable |
||||
#belongs_to :user |
||||
#belongs_to :project |
||||
#attr_protected :user_id, :project_id, :created_at, :updated_at |
||||
self.abstract_class = true # lets have subclasses have their own SQL tables |
||||
|
||||
def self.accepted_properties |
@ -1,6 +1,10 @@ |
||||
require "set" |
||||
|
||||
class Report::Filter |
||||
extend ProactiveAutoloader |
||||
autoload :Base, 'report/filter/base' |
||||
autoload :NoFilter, 'report/filter/no_filter' |
||||
|
||||
def self.all |
||||
@all ||= Set[] |
||||
end |
@ -1,7 +1,12 @@ |
||||
require "set" |
||||
|
||||
class Report::GroupBy |
||||
extend ProactiveAutoloader |
||||
include Report::QueryUtils |
||||
autoload :Base, 'report/group_by/base' |
||||
autoload :RubyAggregation, 'report/group_by/ruby_aggregation' |
||||
autoload :SingletonValue, 'report/group_by/singleton_value.rb' |
||||
autoload :SqlAggregation, 'report/group_by/sql_aggregation' |
||||
|
||||
def self.all |
||||
Set[engine::GroupBy::SingletonValue] |
@ -1,4 +1,10 @@ |
||||
module Report::Validation |
||||
extend ProactiveAutoloader |
||||
include Report::QueryUtils |
||||
autoload :Dates, 'report/validation/dates' |
||||
autoload :Integers, 'report/validation/integers' |
||||
autoload :Sql, 'report/validation/sql' |
||||
|
||||
def register_validations(*validation_methods) |
||||
validation_methods.flatten.each do |val_method| |
||||
register_validation(val_method) |
Loading…
Reference in new issue