mystic 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a973cbbc63678d2696964dbcb54892c5ec5bfa35
4
- data.tar.gz: 26a6ed4f17e3dce193ce7e3fbbd366f4c648014c
3
+ metadata.gz: de71da34560e28fba2d04b9dbf75551368b45200
4
+ data.tar.gz: 5f688c1bb8c7b8c462091d15c8a422dba19cc72a
5
5
  SHA512:
6
- metadata.gz: a6c3350a6dfb06f75a45022a2aa0f9797e9483336b8522c8329ac71912d11896d960b49f676604f71bfbd51e27cc5841d39742214fa1b07fc9f2a9fefc8641eb
7
- data.tar.gz: 1abe0eb03af85781c9ae40d3b6429b92133249fc0fa990d7c1aacff5a3578c2659aa29db63846f663132d1d4f3c07b6c6fc96b9c792781a4e16e37f5cda3932b
6
+ metadata.gz: 6e8b6eff90145b201529b59269e33ac59f6cf44c19d0d1f96680ec13f45db449aba0379e0599048c490f983156ae3b033bd3d36f162cac51dd79a69895d1748f
7
+ data.tar.gz: 35eb2a83a67ff3542b4320fc6db0a414c4137213d1d8129323cfcf4055345064f36ad6e5a25a257e422198b5b9ea511e85edf10edb58ab0177976d120dc5a6ec
@@ -1,99 +1,92 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "yaml"
4
+ require "erb"
4
5
  require "pathname"
5
- require "mystic/extensions"
6
- require "mystic/constants"
7
- require "mystic/sql"
8
- require "mystic/adapter"
9
- require "mystic/migration"
10
- require "mystic/model"
6
+ require "densify"
7
+ require_relative "./mystic/extensions.rb"
8
+ require_relative "./mystic/sql.rb"
9
+ require_relative "./mystic/postgres.rb"
10
+ require_relative "./mystic/migration.rb"
11
+ require_relative "./mystic/model.rb"
11
12
 
12
- module Mystic
13
- @@adapter = nil
14
-
13
+ module Mystic
14
+ MysticError = Class.new StandardError
15
+ RootError = Class.new StandardError
16
+ EnvironmentError = Class.new StandardError
17
+ AdapterError = Class.new StandardError
18
+ ConnectionError = Class.new StandardError
19
+ CLIError = Class.new StandardError
20
+ MIG_REGEX = /^(?<num>\d+)_(?<name>[a-zA-Z]+)\.rb$/ # example: 1_MigrationClassName.rb
21
+ JSON_COL = "mystic_return_json89788"
22
+
15
23
  class << self
16
- def adapter
17
- @@adapter
18
- end
19
-
20
- # Mystic.connect
21
- # Connects to a database. It's recommended you use it like ActiveRecord::Base.establish_connection
22
- # Arguments:
23
- # env - The env from database.yml you wish to use
24
- def connect(env="")
25
- load_env
26
- @@env = (env || ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development").to_s
27
- yaml = root.join("config","database.yml").read
28
- db_yml = YAML.load(yaml) rescue YAML.load(ERB.new(yaml).result) # Heroku uses ERB here because rails makes assumptions
29
-
30
- raise EnvironmentError, "Environment '#{@@env}' doesn't exist." unless db_yml.member? @@env
31
-
32
- conf = db_yml[@@env].symbolize
33
- conf[:dbname] = conf[:database]
34
-
35
- @@adapter = Adapter.create(
36
- conf[:adapter],
37
- :pool_size => conf[:pool_size].to_i,
38
- :pool_timeout => conf[:timeout].to_i,
39
- :pool_expires => conf[:expires].to_i
40
- )
41
-
42
- @@adapter.connect conf
43
- true
44
- end
45
-
46
- alias_method :env=, :connect
47
-
48
- def env
49
- @@env
24
+ attr_reader :postgres
25
+
26
+ #
27
+ ## Accessors
28
+ #
29
+
30
+ def db_yml
31
+ if @db_yml.nil?
32
+ # Heroku uses ERB cuz rails uses it errwhere
33
+ yaml = ERB.new(root.join("config","database.yml").read).result
34
+ @db_yml = YAML.load yaml
35
+ end
36
+ @db_yml
37
+ end
38
+
39
+ def env
40
+ @env
41
+ end
42
+
43
+ def env= new_env
44
+ @postgres.disconnect unless @postgres.nil?
45
+ @postgres = nil
46
+
47
+ load_env
48
+
49
+ @env = (new_env || ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development").to_s
50
+ raise EnvironmentError, "Environment '#{@env}' doesn't exist." unless db_yml.member? @env
51
+
52
+ conf = db_yml[@env].symbolize
53
+ conf[:dbname] = conf.delete :database
54
+ raise MysticError, "Mystic only supports Postgres." unless /^postg.+$/i =~ conf[:adapter]
55
+
56
+ @postgres = Postgres.new(conf)
57
+
58
+ @env
59
+ end
60
+
61
+ def root path=Pathname.new(Dir.pwd)
62
+ raise RootError, "Failed to find the application's root." if path == path.parent
63
+ mystic_path = path.join "config", "database.yml"
64
+ return root(path.parent) unless mystic_path.file? # exist? is implicit with file?
65
+ path
50
66
  end
51
67
 
52
- # Mystic.disconnect
53
- # Disconnects from the connected database. Use it like ActiveRecord::Base.connection.disconnect!
68
+ #
69
+ ## DB functionality
70
+ #
71
+
72
+ alias_method :connect, :env=
73
+
54
74
  def disconnect
55
- @@adapter.disconnect
56
- @@adapter = nil
57
- true
75
+ postgres.disconnect
58
76
  end
59
77
 
60
- # Mystic.execute
61
- # Execute some sql. It will be densified (the densify gem) and sent to the DB
62
- # Arguments:
63
- # sql - The SQL to execute
64
- # Returns: Native Ruby objects representing the response from the DB (Usually an Array of Hashes)
65
- def execute(sql="")
66
- raise AdapterError, "Adapter is nil, so Mystic is not connected." if @@adapter.nil?
67
- @@adapter.execute sql.sql_terminate.densify
78
+ def execute sql=""
79
+ #raise ConnectionError, "Not connected to Postgres" unless postgres.connected?
80
+ postgres.execute sql.sql_terminate.densify
68
81
  end
69
-
70
- # Mystic.sanitize
71
- # Escape a string so that it can be used safely as input. Mystic does not support statement preparation, so this is a must.
72
- # Arguments:
73
- # str - The string to sanitize
74
- # Returns: the sanitized string
75
- def sanitize(str="")
76
- raise AdapterError, "Adapter is nil, so Mystic is not connected." if @@adapter.nil?
77
- @@adapter.sanitize str
78
- end
79
-
80
- # Mystic.root
81
- # Get the app root
82
- # Aguments:
83
- # To be ignored
84
- # Returns:
85
- # A pathname to the application's root
86
- def root(path=Pathname.new(Dir.pwd))
87
- raise RootError, "Failed to find the application's root." if path == path.parent
88
- mystic_path = path.join "config", "database.yml"
89
- return path if mystic_path.file? # exist? is implicit with file?
90
- root path.parent
91
- end
92
-
93
- # TODO: Make this a migration
94
- # TODO: Silence this
95
- # Mystic.create_table
96
- # Create migration tracking table
82
+
83
+ def escape str=""
84
+ # raise ConnectionError, "Not connected to Postgres" unless postgres.connected?
85
+ postgres.escape str
86
+ end
87
+
88
+ alias_method :sanitize, :escape
89
+
97
90
  def create_mig_table
98
91
  execute "CREATE TABLE IF NOT EXISTS mystic_migrations (mig_number integer, filename text)"
99
92
  end
@@ -109,10 +102,10 @@ module Mystic
109
102
  mp = root.join("mystic","migrations").to_s
110
103
 
111
104
  Dir.entries(mp)
112
- .reject{ |e| MIG_REGEX.match(e).nil? }
113
- .reject{ |e| migrated_filenames.include? e }
114
- .sort{ |a,b| MIG_REGEX.match(a)[:num].to_i <=> MIG_REGEX.match(b)[:num].to_i }
115
- .each{ |fname|
105
+ .reject { |e| MIG_REGEX.match(e).nil? }
106
+ .reject { |e| migrated_filenames.include? e }
107
+ .sort { |a,b| MIG_REGEX.match(a)[:num].to_i <=> MIG_REGEX.match(b)[:num].to_i }
108
+ .each { |fname|
116
109
  load File.join mp,fname
117
110
 
118
111
  mig_num,mig_name = MIG_REGEX.match(fname).captures
@@ -137,11 +130,10 @@ module Mystic
137
130
  end
138
131
 
139
132
  # Creates a blank migration in mystic/migrations
140
- def create_migration(name="")
133
+ def create_migration name=""
141
134
  name.strip!
142
135
  raise CLIError, "Migration name must not be empty." if name.empty?
143
-
144
- name[0] = name[0].capitalize
136
+ name.capitalize_first!
145
137
 
146
138
  migs = root.join "mystic","migrations"
147
139
 
@@ -149,21 +141,22 @@ module Mystic
149
141
 
150
142
  File.open(migs.join("#{num}_#{name}.rb").to_s, 'w') { |f| f.write(template name) }
151
143
  end
152
-
144
+
145
+ private
146
+
153
147
  # Loads the .env file
154
148
  def load_env
155
149
  root.join(".env").read
156
150
  .split("\n")
157
151
  .map { |l| l.strip.split "=", 2 }
158
- .each { |k,v| ENV[k] = v } rescue nil
152
+ .each { |k,v| ENV[k] = v }
153
+ rescue nil
159
154
  end
160
-
161
- private
162
-
155
+
163
156
  # Retuns a blank migration's code in a String
164
- def template(name=nil)
157
+ def template name
165
158
  raise ArgumentError, "Migrations must have a name." if name.nil?
166
- <<-mig_template
159
+ <<-RUBY
167
160
  #!/usr/bin/env ruby
168
161
 
169
162
  require "mystic"
@@ -177,7 +170,7 @@ class #{name} < Mystic::Migration
177
170
 
178
171
  end
179
172
  end
180
- mig_template
173
+ RUBY
181
174
  end
182
175
  end
183
176
  end
@@ -11,14 +11,20 @@ module Kernel
11
11
  end
12
12
 
13
13
  class String
14
+ def capitalize_first!
15
+ self[0] = self[0].upcase
16
+ end
17
+
14
18
  def desnake
15
19
  downcase.split("_").map(&:capitalize)*' '
16
20
  end
17
21
 
18
- def sanitize
19
- Mystic.sanitize(self).untaint
22
+ def escape
23
+ Mystic.escape(self).untaint
20
24
  end
21
25
 
26
+ alias_method :sanitize, :escape
27
+
22
28
  def truncate(len)
23
29
  self[0..len-1]
24
30
  end
@@ -57,11 +63,11 @@ class Array
57
63
  end
58
64
 
59
65
  class Hash
60
- def subhash(*keys)
66
+ def subhash *keys
61
67
  Hash[values_at(*keys).merge_keys(*keys).reject{ |k,v| v.nil? }]
62
68
  end
63
69
 
64
- def parify(delim=" ")
70
+ def parify delim=" "
65
71
  map { |pair| pair * delim }
66
72
  end
67
73
 
@@ -96,7 +102,7 @@ class Pathname
96
102
  @path[0] != File::SEPARATOR
97
103
  end
98
104
 
99
- def join(*args)
105
+ def join *args
100
106
  Pathname.new(File.join @path, *args.map(&:to_s))
101
107
  end
102
108
  end
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- module Mystic
3
+ module Mystic
4
4
  class Migration
5
- Error = Class.new(StandardError)
6
- IrreversibleError = Class.new(StandardError)
5
+ Error = Class.new StandardError
6
+ IrreversibleError = Class.new StandardError
7
7
 
8
8
  def initialize
9
9
  @irreversible = false
@@ -17,21 +17,26 @@ module Mystic
17
17
  def rollback
18
18
  exec_migration :down
19
19
  end
20
-
21
- # TODO: This is ugly... It needs cleaning up.
22
- def exec_migration(direction)
23
- @sql = ""
24
-
25
- direction = direction.to_sym
26
-
27
- raise ArgumentError, "Direction must be either :up or :down." unless [:up, :down].include? direction
28
- raise IrreversibleError, "Impossible to roll back an irreversible migration." if direction == :down && irreversible?
20
+
21
+ def to_sql direction
22
+ @sql = ""
23
+ _direction = direction.to_sym
29
24
 
30
- execute Mystic::SQL::Operation.start_transaction
31
- method(direction).call
32
- execute Mystic::SQL::Operation.commit_transaction
25
+ raise ArgumentError, "Direction must be either :up or :down." unless [:up, :down].include? _direction
26
+ raise IrreversibleError, "Impossible to roll back an irreversible migration." if _direction == :down && irreversible?
33
27
 
34
- Mystic.adapter.execute @sql # bypass densification
28
+ execute "BEGIN"
29
+ method(_direction).call
30
+ execute "COMMIT"
31
+
32
+ res = @sql.dup
33
+ @sql = ""
34
+ res
35
+ end
36
+
37
+ def exec_migration direction
38
+ sql = to_sql direction
39
+ Mystic.postgres.execute sql
35
40
  end
36
41
 
37
42
 
@@ -40,7 +45,7 @@ module Mystic
40
45
  #
41
46
 
42
47
  # All migration SQL goes through here
43
- def execute(obj)
48
+ def execute obj
44
49
  @sql << obj.to_s.sql_terminate # to_sql isn't defined for strings, to_sql is aliased to to_s
45
50
  end
46
51
 
@@ -52,58 +57,43 @@ module Mystic
52
57
  @irreversible
53
58
  end
54
59
 
55
- def create_table(name)
60
+ def create_table name
56
61
  raise ArgumentError, "No block provided, a block is required to create a table." unless block_given?
57
62
  table = Mystic::SQL::Table.create :name => name
58
63
  yield table
59
64
  execute table
60
65
  end
61
66
 
62
- def alter_table(name)
67
+ def alter_table name
63
68
  raise ArgumentError, "No block provided, a block is required to alter a table." unless block_given?
64
69
  table = Mystic::SQL::Table.alter :name => name
65
70
  yield table
66
71
  execute table
67
72
  end
68
73
 
69
- def drop_table(name, opts={})
74
+ def drop_table name, opts={}
70
75
  irreversible!
71
- execute Mystic::SQL::Operation.drop_table(
72
- :table_name => name.to_s,
73
- :cascade? => opts[:cascade]
74
- )
76
+ execute "DROP TABLE #{name} #{opts[:cascade] ? "CASCADE" : "RESTRICT" }"
75
77
  end
76
78
 
77
- def drop_index(*args)
78
- execute Mystic::SQL::Operation.drop_index(
79
- :index_name => args[0],
80
- :table_name => args[1]
81
- )
79
+ def drop_index idx_name
80
+ execute "DROP INDEX #{idx_name}"
82
81
  end
83
82
 
84
- def create_ext(extname)
85
- execute Mystic::SQL::Operation.create_ext(
86
- :name => extname.to_s
87
- )
83
+ def create_ext extname
84
+ execute "CREATE EXTENSION \"#{extname.to_s}\""
88
85
  end
89
86
 
90
- def drop_ext(extname)
91
- execute Mystic::SQL::Operation.drop_ext(
92
- :name => extname.to_s
93
- )
87
+ def drop_ext extname
88
+ execute "DROP EXTENSION \"#{extname.to_s}\""
94
89
  end
95
90
 
96
- def create_view(name, sql)
97
- execute Mystic::SQL::Operation.create_view(
98
- :name => name.to_s,
99
- :sql => sql.to_s
100
- )
91
+ def create_view name, sql
92
+ execute "CREATE VIEW #{name} AS #{sql}"
101
93
  end
102
94
 
103
- def drop_view(name)
104
- execute Mystic::SQL::Operation.drop_view(
105
- :name => name.to_s
106
- )
95
+ def drop_view name
96
+ execute "DROP VIEW #{name}"
107
97
  end
108
98
  end
109
99
  end
@@ -1,131 +1,137 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Mystic
4
- class Model
5
- def self.table_name
6
- to_s.downcase
4
+ module Model
5
+ def self.included base
6
+ base.extend ClassMethods
7
7
  end
8
+
9
+ module ClassMethods
10
+ def table_name
11
+ to_s.downcase
12
+ end
8
13
 
9
- def self.visible_cols
10
- ["*"]
11
- end
14
+ def visible_cols
15
+ ["*"]
16
+ end
12
17
 
13
- def self.wrapper_sql(opts={})
14
- sym_opts = opts.symbolize
18
+ def wrapper_sql opts={}
19
+ sym_opts = opts.symbolize
15
20
 
16
- sql = sym_opts[:sql] || "SELECT 1"
17
- op = sql.split(/\s+/,2).first.upcase
18
- return_rows = sym_opts[:return_rows] || false
19
- return_json = sym_opts[:return_json] || false
20
- return_rows = true if return_json
21
- plural = opts[:plural] && op != "INSERT"
21
+ sql = sym_opts[:sql] || "SELECT 1"
22
+ op = sql.split(/\s+/,2).first.upcase
23
+ return_rows = sym_opts[:return_rows] || false
24
+ return_json = sym_opts[:return_json] || false
25
+ return_rows = true if return_json
26
+ plural = opts[:plural] && op != "INSERT"
22
27
 
23
- sql << " RETURNING #{visible_cols*','}" if return_rows && op != "SELECT"
28
+ sql << " RETURNING #{visible_cols*','}" if return_rows && op != "SELECT"
24
29
 
25
- s = []
30
+ s = []
26
31
 
27
- if return_json
28
- s << "WITH res AS (#{sql}) SELECT"
29
- s << "array_to_json(array_agg(res))" if plural
30
- s << "row_to_json(res)" unless plural
31
- s << "AS #{Mystic::JSON_COL}"
32
- s << "FROM res"
33
- else
34
- s << sql
35
- end
32
+ if return_json
33
+ s << "WITH res AS (#{sql}) SELECT"
34
+ s << "array_to_json(array_agg(res))" if plural
35
+ s << "row_to_json(res)" unless plural
36
+ s << "AS #{Mystic::JSON_COL}"
37
+ s << "FROM res"
38
+ else
39
+ s << sql
40
+ end
36
41
 
37
- s*' '
38
- end
42
+ s*' '
43
+ end
39
44
 
40
- def self.function_sql(returns_rows, funcname, *params)
41
- "SELECT #{returns_rows ? "* FROM" : ""} #{funcname}(#{params.sqlize*','})"
42
- end
45
+ def function_sql returns_rows, funcname, *params
46
+ "SELECT #{returns_rows ? "* FROM" : ""} #{funcname}(#{params.sqlize*','})"
47
+ end
43
48
 
44
- def self.select_sql(params={}, opts={})
45
- sym_opts = opts.symbolize
46
- count = sym_opts[:count] || 0
47
- where = params.sqlize
49
+ def select_sql params={}, opts={}
50
+ sym_opts = opts.symbolize
51
+ count = sym_opts[:count] || 0
52
+ where = params.sqlize
48
53
 
49
- sql = []
50
- sql << "SELECT #{visible_cols*','} FROM #{table_name}"
51
- sql << "WHERE #{where*' AND '}" if where.count > 0
52
- sql << "LIMIT #{count.to_i}" if count > 0
54
+ sql = []
55
+ sql << "SELECT #{visible_cols*','} FROM #{table_name}"
56
+ sql << "WHERE #{where*' AND '}" if where.count > 0
57
+ sql << "LIMIT #{count.to_i}" if count > 0
53
58
 
54
- wrapper_sql(
55
- :sql => sql.join(' '),
56
- :return_rows => true,
57
- :return_json => sym_opts[:return_json] && Mystic.adapter.json_supported?,
58
- :plural => count > 1
59
- )
60
- end
59
+ wrapper_sql(
60
+ :sql => sql.join(' '),
61
+ :return_rows => true,
62
+ :return_json => sym_opts[:return_json],
63
+ :plural => count > 1
64
+ )
65
+ end
61
66
 
62
- def self.update_sql(where={}, set={}, opts={})
63
- return "" if where.empty?
64
- return "" if set.empty?
67
+ def update_sql where={}, set={}, opts={}
68
+ return "" if where.empty?
69
+ return "" if set.empty?
65
70
 
66
- sym_opts = opts.symbolize
71
+ sym_opts = opts.symbolize
67
72
 
68
- wrapper_sql(
69
- :sql => "UPDATE #{table_name} SET #{set.sqlize*','} WHERE #{where.sqlize*' AND '}",
70
- :return_rows => sym_opts[:return_rows],
71
- :return_json => sym_opts[:return_json] && Mystic.adapter.json_supported?
72
- )
73
- end
73
+ wrapper_sql(
74
+ :sql => "UPDATE #{table_name} SET #{set.sqlize*','} WHERE #{where.sqlize*' AND '}",
75
+ :return_rows => sym_opts[:return_rows],
76
+ :return_json => sym_opts[:return_json]
77
+ )
78
+ end
74
79
 
75
- def self.insert_sql(params={}, opts={})
76
- return "" if params.empty?
80
+ def insert_sql params={}, opts={}
81
+ return "" if params.empty?
77
82
 
78
- sym_opts = opts.symbolize
83
+ sym_opts = opts.symbolize
79
84
 
80
- wrapper_sql(
81
- :sql => "INSERT INTO #{table_name} (#{params.keys*','}) VALUES (#{params.values.sqlize*','})",
82
- :return_rows => sym_opts[:return_rows],
83
- :return_json => sym_opts[:return_json] && Mystic.adapter.json_supported?
84
- )
85
- end
85
+ wrapper_sql(
86
+ :sql => "INSERT INTO #{table_name} (#{params.keys*','}) VALUES (#{params.values.sqlize*','})",
87
+ :return_rows => sym_opts[:return_rows],
88
+ :return_json => sym_opts[:return_json]
89
+ )
90
+ end
86
91
 
87
- def self.delete_sql(params={}, opts={})
88
- return "" if params.empty?
92
+ def delete_sql params={}, opts={}
93
+ return "" if params.empty?
89
94
 
90
- sym_opts = opts.symbolize
95
+ sym_opts = opts.symbolize
91
96
 
92
- wrapper_sql(
93
- :sql => "DELETE FROM #{table_name} WHERE #{params.sqlize*' AND '}",
94
- :return_rows => sym_opts[:return_rows],
95
- :return_json => sym_opts[:return_json] && Mystic.adapter.json_supported?
96
- )
97
- end
97
+ wrapper_sql(
98
+ :sql => "DELETE FROM #{table_name} WHERE #{params.sqlize*' AND '}",
99
+ :return_rows => sym_opts[:return_rows],
100
+ :return_json => sym_opts[:return_json]
101
+ )
102
+ end
98
103
 
99
- def self.select(params={}, opts={})
100
- Mystic.execute select_sql(params, opts)
101
- end
104
+ def select params={}, opts={}
105
+ Mystic.execute select_sql(params, opts)
106
+ end
102
107
 
103
- def self.fetch(params={}, opts={})
104
- res = select params, opts.merge({:count => 1})
105
- return res if res.is_a? String
106
- res.first rescue nil
107
- end
108
+ def fetch params={}, opts={}
109
+ res = select params, opts.merge({:count => 1})
110
+ return res if res.is_a? String
111
+ res.first rescue nil
112
+ end
108
113
 
109
- def self.create(params={}, opts={})
110
- res = Mystic.execute insert_sql(params, opts)
111
- return res if res.is_a? String
112
- res.first rescue nil
113
- end
114
+ def create params={}, opts={}
115
+ res = Mystic.execute insert_sql(params, opts)
116
+ return res if res.is_a? String
117
+ res.first rescue nil
118
+ end
114
119
 
115
- def self.update(where={}, set={}, opts={})
116
- Mystic.execute update_sql(where, set, opts.merge({ :return_rows => true }))
117
- end
120
+ def update where={}, set={}, opts={}
121
+ Mystic.execute update_sql(where, set, opts.merge({ :return_rows => true }))
122
+ end
118
123
 
119
- def self.delete(params={}, opts={})
120
- Mystic.execute delete_sql(params, opts)
121
- end
124
+ def delete params={}, opts={}
125
+ Mystic.execute delete_sql(params, opts)
126
+ end
122
127
 
123
- def self.exec_func(funcname, *params)
124
- Mystic.execute function_sql(false, funcname, *params)
125
- end
128
+ def exec_func funcname, *params
129
+ Mystic.execute function_sql(false, funcname, *params)
130
+ end
126
131
 
127
- def self.exec_func_rows(funcname, *params)
128
- Mystic.execute function_sql(true, funcname, *params)
129
- end
132
+ def exec_func_rows funcname, *params
133
+ Mystic.execute function_sql(true, funcname, *params)
134
+ end
135
+ end
130
136
  end
131
137
  end