mystic 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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