Module: DataMapper::Cutie

Defined in:
lib/dm-cutie.rb,
lib/dm-cutie/cutie.rb,
lib/dm-cutie/version.rb,
lib/dm-cutie/tracker/hook/abstract.rb

Defined Under Namespace

Modules: Tracker

Constant Summary collapse

OPERATIONS =
[:select, :insert, :update, :delete]
MODELS =
[:repository_storage, :generalized_query, :executed_query, :query_storage_link]
CONFIG_DEFAULTS =
{                                                                
  :repo_name                   => :dm_cutie, #name of the repo
  :slow_query_length          => 3,      #in seconds
  :exclude_models             => false,  #[:array, :of, :model, :names]
  :only_models                => false,  #[:array, :of, :model, :names]
}
VERSION =
'0.4.0'.freeze

Class Method Summary collapse

Class Method Details

.add_internal_model(*model_names) ⇒ NilClass

Note:
  • These are the models that Cutie uses internally, and thus ignores.

  • add_internal_model - Adds a model to the list of models used for Tracking Queries

Parameters:

  • model_name (Array[~Symbol])

    Model names to treat as internal models

Returns:

  • (NilClass)


24
25
26
# File 'lib/dm-cutie/cutie.rb', line 24

def add_internal_model(*model_names)
  model_names.each{|m| MODELS << m.to_sym }
end

.add_tracker_hook(tracker_name) ⇒ Object

Registers a tracker hook by name



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dm-cutie/cutie.rb', line 49

def add_tracker_hook(tracker_name)
  tracker_hook_klass = get_klass(tracker_name)
  
  DataMapper.logger.debug "Hook: #{tracker_hook_klass.hook_name} was added"
    
  # Add this tracker hook class to all intersections of its suppored_adapters and supported_statements
  tracker_hook_klass.supported_adapters.each do |adapter_type|
    tracker_hook_klass.supported_statements.each do |statement|
      tracker_hooks_for(adapter_type,statement) << tracker_hook_klass
    end
  end
end

.clean_up!Object

Removes all Cutie tables from the repository



235
236
237
238
239
240
241
# File 'lib/dm-cutie/cutie.rb', line 235

def clean_up!
  DataMapper.logger.debug "Migrating down all Cutie Models"
  DataMapper::Cutie::MODELS.each do |m|
    DataMapper.logger.debug "Migrating down #{m}"
    DataMapper::Cutie.send(:get_klass,m).auto_migrate_down!
  end
end

.configObject

config - Running configuration of Cutie



229
230
231
# File 'lib/dm-cutie/cutie.rb', line 229

def config
  @__configuration ||= CONFIG_DEFAULTS.clone
end

.enable_adapter(adap) ⇒ Object

Loads files needed for adapter tracking for built in trackers



42
43
44
45
# File 'lib/dm-cutie/cutie.rb', line 42

def enable_adapter(adap)
  DataMapper::Adapters.send :load_adapter, adap
  require DataMapper::Cutie.root / :tracker / adap
end

.get_human_name(m) ⇒ Object

get_human_name gets the underscored name



253
254
255
# File 'lib/dm-cutie/cutie.rb', line 253

def get_human_name(m)
  Extlib::Inflection.underscore(m.name).to_sym
end

.get_klass(n) ⇒ Object

get_klass Gets a class from a name



247
248
249
# File 'lib/dm-cutie/cutie.rb', line 247

def get_klass(n)
  Extlib::Inflection.constantize(get_model_name(n)) rescue false
end

.get_model_name(n) ⇒ Object

get_model_name gets a model’s Class name



260
261
262
# File 'lib/dm-cutie/cutie.rb', line 260

def get_model_name(n)
  Extlib::Inflection.classify(n)
end

.missing_storageObject

Accessor for missing storage, set by calling #valid_repo?



132
133
134
# File 'lib/dm-cutie/cutie.rb', line 132

def missing_storage
  @_missing_storage ||= []
end

.process_tracker_hooks(adapter_type, statement, executed_query) ⇒ Object

  • process_tracker_hoooks - Run all trackers hooks for a given adapter_type / statement

Parameters:

  • adapter_type (Symbol)

    Adapter to look up

  • statement (Symbol)

    Symbol to look up

  • executed_query (ExecutedQuery)

    currently executed query



34
35
36
37
38
# File 'lib/dm-cutie/cutie.rb', line 34

def process_tracker_hooks(adapter_type, statement, executed_query)
  DataMapper::Cutie.tracker_hooks_for(adapter_type, statement).each do |tracker_hook|
    tracker_hook.track executed_query
  end
end

.repoObject

Accessor for the Cuties repository



90
91
92
93
94
95
96
# File 'lib/dm-cutie/cutie.rb', line 90

def repo
  if block_given?
    repository(repo_name){ yield }
  else
    repository(repo_name)
  end
end

.repo_nameObject



84
85
86
# File 'lib/dm-cutie/cutie.rb', line 84

def repo_name
  config[:repo_name]
end

.rootObject



16
17
18
# File 'lib/dm-cutie.rb', line 16

def root
  @_root_path ||= File.expand_path(File.dirname(__FILE__)) / 'dm-cutie'
end

.setupObject

setup - Configures tracker

Examples:

DataMapper::Cutie.setup do |c|
  c[:repo_name]   = :dm_cutie, #name of the repo
  c[:exclude_models]            = false #[:person, :car]
  c[:only_models]               = false #[:article, :address]
end


214
215
216
217
218
219
220
221
222
223
# File 'lib/dm-cutie/cutie.rb', line 214

def setup
  if block_given?
    yield(config)
  else
    config
  end

  validate_configuration
  format_configuration
end

.slow?(l) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/dm-cutie/cutie.rb', line 80

def slow?(l)
  (l > config[:slow_query_length].to_f)
end

.start(force_migration = false) ⇒ Object

start - enables tracking and tracks adapters @note, if the tables aren’t detected, they will always be migrated

@note, make sure you require your CUSTOM PROFILERS before calling start or their tables

will not be created

Parameters:

  • force_migration (Boolean) (defaults to: false)

    should the CUTIE tables be migrated



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/dm-cutie/cutie.rb', line 143

def start(force_migration = false)        
  if !was_previously_started? || force_migration 

    if !DataMapper::Cutie.valid_repo?(DataMapper::Cutie.repo_name) || force_migration
      MODELS.each do |m| 
        DataMapper.logger.info "Migrating Cutie model: #{m}"
        repo { get_klass(m).auto_migrate! }
      end
    end
          
    DataMapper.logger.info "Tracking models: #{tracked_models.to_a.join(', ')}"
    @__was_previously_started = true
  end                 
              
  @__tracking = true 
end

.stopObject

stop - Disable’s tracking of statements



200
201
202
203
# File 'lib/dm-cutie/cutie.rb', line 200

def stop
  @__tracking = false            
  !tracking?
end

.storage_name_for_model(m) ⇒ Object



76
77
78
# File 'lib/dm-cutie/cutie.rb', line 76

def storage_name_for_model(m)
  Extlib::Inflection.pluralize(m.to_s)
end

.tracked_modelsObject

tracked_models - list of models being tracked defaults to all descendants of DataMapper::Model

See Also:



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/dm-cutie/cutie.rb', line 167

def tracked_models 
  return @__tracked_models unless @__tracked_models.nil?
  
  model_descendants = DataMapper::Model.descendants.to_a.map{|m| get_human_name(m)}

  tmp_models = if config[:exclude_models]
    model_descendants - config[:exclude_models].map{|n| n.to_sym}
  elsif config[:only_models]
    config[:only_models].map{|n| n.to_sym }
  else
    model_descendants
  end
  
  # Make sure Cutie models aren't included, thus no infinite loop :)
  tmp_models -= MODELS

  @__tracked_models = Set.new( tmp_models.map{ |m| get_klass(m) } )
  @__tracked_models
end

.tracker_hooksObject

  • tracker_hooks - accessor for @__tracker_hooks

Returns:

  • Hash



72
73
74
# File 'lib/dm-cutie/cutie.rb', line 72

def tracker_hooks
  @__tracker_hooks ||={}
end

.tracker_hooks_for(adapter_type, statement) ⇒ Object

Looks for tracker hooks by adapter & executed statement



64
65
66
67
# File 'lib/dm-cutie/cutie.rb', line 64

def tracker_hooks_for(adapter_type,statement)
  tracker_hooks[adapter_type.to_sym]                   ||= {}
  tracker_hooks[adapter_type.to_sym][statement.to_sym] ||= []        
end

.tracking?Boolean

tracking? - is tracking enabled?

Returns:

  • (Boolean)


102
103
104
# File 'lib/dm-cutie/cutie.rb', line 102

def tracking?
  @__tracking ||= false
end

.tracking_query?(q) ⇒ Boolean

  • tracking_query? - Is this query being tracked

Parameters:

  • q (DataMapper::Query)

Returns:

  • (Boolean)

    Boolean



193
194
195
196
# File 'lib/dm-cutie/cutie.rb', line 193

def tracking_query?(q)
  tracking? &&               
    tracked_models.include?(q.model)
end

.valid_repo?(_repo_name_) ⇒ Boolean

Determines if a repo is a valid dm-cutie repo

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/dm-cutie/cutie.rb', line 115

def valid_repo?( _repo_name_ )
  @_missing_storage = []
  MODELS.inject(true) do |all_exist, _model|
    model_storage_name = storage_name_for_model(_model.to_s)
    does_exist = repository(_repo_name_).adapter.storage_exists? model_storage_name

    if does_exist
      DataMapper.logger.info "#{_model.to_s} exists: #{does_exist}"            
    else
      DataMapper::Cutie.missing_storage << model_storage_name
    end
    
    all_exist & does_exist
  end
end

.was_previously_started?Boolean

was_previously_started? - was it previously started during this runtime

(ie the storage engines are guaranteed to exist)

Returns:

  • (Boolean)


109
110
111
# File 'lib/dm-cutie/cutie.rb', line 109

def was_previously_started?
  @__was_previously_started ||= false
end