Module: MongoScript::Execution::ClassMethods

Defined in:
lib/mongoscript/execution.rb

Instance Method Summary collapse

Instance Method Details

#code_for(script_name) ⇒ Object

Note:

10gen recommends not using stored functions, but that’s mainly because they should be stored and versioned with other code. However, automatic installation and versioning via MD5 hashes should meet that objection.

Note:

this is currently cached in LOADED_SCRIPTS without hashing. (To do!)

Get code from stored files. This looks through each of the script directories, returning the first match it finds.

Longer term, we could store functions on the server keyed by both name and a hash of the contents (to ensure uniqueness).



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mongoscript/execution.rb', line 45

def code_for(script_name)
  script_name = script_name.to_s.underscore
  # we can use underscore since we use ActiveSupport
  dir = @script_dirs.find {|d| File.exists?(File.join(d, "#{script_name}.js"))}
  raise ScriptNotFound, "Unable to find script #{script_name}" unless dir
  code = File.read(File.join(dir, "#{script_name}.js"))
  LOADED_SCRIPTS[script_name] ||= code

  # for future extension
  # code_hash = Digest::MD5.hex_digest(code)
  # LOADED_SCRIPTS[script_name] = {
  #   :code => code,
  #   :hash => code_hash,
  #   :installed => false
  # }
  # code
end

#execute(code, args = [], options = {}) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/mongoscript/execution.rb', line 104

def execute(code, args = [], options = {})
  # see http://mrdanadams.com/2011/mongodb-eval-ruby-driver/
  result = MongoScript.database.command({:$eval => code, :args => resolve_arguments(args)}.merge(options))
  unless result["ok"] == 1.0
    raise ExecutionFailure, "MongoScript.execute JS didn't return {ok: 1.0}!  Result: #{result.inspect}"
  end
  result["retval"]
end

#execute_readonly_code(code, *args) ⇒ Object

raw code note: to pass in Mongo options for the $exec call, like nolock, you need to call execute directly since otherwise we have no way to tell Mongo options from an argument list ending in a JS hash



94
95
96
97
98
# File 'lib/mongoscript/execution.rb', line 94

def execute_readonly_code(code, *args)
  # for readonly operations, set nolock to true to improve concurrency
  # http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCodeExecution-NotesonConcurrency
  execute(code, args, {:nolock => true})
end

#execute_readonly_routine(script_name, *args) ⇒ Object

Note:

The name of this function may change before 1.0.

Execute read-only code stored in a file. The code will be run non-blockingly; it should not contain any statements that write to the database.

Parameters:

  • script_name

    the name of the script file (see #code_for)

  • args

    any arguments to the function



73
74
75
# File 'lib/mongoscript/execution.rb', line 73

def execute_readonly_routine(script_name, *args)
  execute_readonly_code(code_for(script_name), *args)
end

#execute_readwrite_code(code, *args) ⇒ Object



100
101
102
# File 'lib/mongoscript/execution.rb', line 100

def execute_readwrite_code(code, *args)
  execute(code, args)
end

#execute_readwrite_routine(script_name, *args) ⇒ Object

Note:

This call will block MongoDB, so use this method sparingly.

Note:

The name of this function may change before 1.0.

Execute code stored in a file that can write to the database.

Parameters:

  • script_name

    the name of the script file (see #code_for)

  • args

    any arguments to the function



87
88
89
# File 'lib/mongoscript/execution.rb', line 87

def execute_readwrite_routine(script_name, *args)
  execute_readwrite_code(code_for(script_name), *args)
end