monetdb 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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDVhN2NmYTg2YWQwZTA5M2ExNTg5NzVhZGMxNWY1YjBlY2U4YjcxOQ==
5
+ data.tar.gz: !binary |-
6
+ ZDdmNWE5YWI2NWI0ZjM4NGI1YWU0YTM3M2NkNjdmMzk2N2U3MjQyNg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ M2JjNTcwY2JjOWViMTM2YTVmOTFlZGQ0MWY0NDVlZDNiNjg3NGMyZmMzNmQ2
10
+ OGJhMjdjN2RlM2FiY2UyNzhjYjc5NDQ0NWRiMzdmMWM1M2VhZjAwNGM0M2Fh
11
+ OGY2NWVkYWMwYTc5MWRhYWZjYmI3Y2Y0MDFlOTAyY2UwY2UzYmU=
12
+ data.tar.gz: !binary |-
13
+ ZjNhMzJjMjUzODZiN2M4N2M1OWYyNjJjMzdjNmU3YzQzZWYyMGUyNjJkZmZk
14
+ N2Q2NmJiNWU3MDA0YmNhMzg4MjJjMDRkZGExZDhkOWFkYzU2MDhhNzZjZTVl
15
+ ZDk0MmZmODE5MTUwMmQwYjQxMDI0ZGZiZDM3YzZhNGJhYWFlNmQ=
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ .DS_Store
2
+ .bundle
3
+ .yardoc
4
+ .rvmrc
5
+ Gemfile.lock
6
+ doc
7
+ pkg
8
+ test/coverage
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ = MonetDB CHANGELOG
2
+
3
+ == Version 0.1.0 (August 28, 2014)
4
+
5
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "yard"
7
+ end
8
+
9
+ group :development, :test do
10
+ gem "monetdb", :path => "."
11
+ gem "pry"
12
+ end
13
+
14
+ group :test do
15
+ gem "simplecov", :require => false
16
+ gem "minitest"
17
+ gem "mocha"
18
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ monetdb (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ coderay (1.1.0)
10
+ docile (1.1.5)
11
+ metaclass (0.0.4)
12
+ method_source (0.8.2)
13
+ minitest (5.4.0)
14
+ mocha (1.1.0)
15
+ metaclass (~> 0.0.1)
16
+ multi_json (1.10.1)
17
+ pry (0.10.0)
18
+ coderay (~> 1.1.0)
19
+ method_source (~> 0.8.1)
20
+ slop (~> 3.4)
21
+ rake (10.3.2)
22
+ simplecov (0.9.0)
23
+ docile (~> 1.1.0)
24
+ multi_json
25
+ simplecov-html (~> 0.8.0)
26
+ simplecov-html (0.8.0)
27
+ slop (3.6.0)
28
+ yard (0.8.7.4)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ minitest
35
+ mocha
36
+ monetdb!
37
+ pry
38
+ rake
39
+ simplecov
40
+ yard
data/LICENSE ADDED
@@ -0,0 +1,17 @@
1
+ The contents of this repository are subject to the MonetDB Public License
2
+ Version 1.1 (the "License"); you may not use this file except in
3
+ compliance with the License. You may obtain a copy of the License at
4
+ https://www.monetdb.org/Legal/MonetDBLicense
5
+
6
+ Software distributed under the License is distributed on an "AS IS"
7
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
8
+ License for the specific language governing rights and limitations
9
+ under the License.
10
+
11
+ The Original Code is the MonetDB Database System.
12
+
13
+ The Initial Developer of the Original Code is CWI.
14
+ Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
15
+
16
+ Copyright August 2008-2011 MonetDB B.V.
17
+ All Rights Reserved.
data/README.rdoc ADDED
@@ -0,0 +1,154 @@
1
+ == Standalone driver ==
2
+ This directory contains the a ruby interface to monetdb5
3
+ written in pure ruby.
4
+
5
+ lib/MonetDB.rb
6
+ lib/MonetDBConnection.rb
7
+ lib/MonetDBStatements.rb
8
+ lib/MonetDBData.rb
9
+ lib/MonetDBExceptions.rb
10
+ lib/hasher.rb
11
+ lib/demo.rb: demo application how to interact with the database
12
+
13
+ ruby-monetdb-sql-0.1.gemspec: make file for rubygems
14
+
15
+ doc/: rubydoc in HTML format
16
+
17
+ == Installation ==
18
+
19
+ The standalone monetdb driver can be installed using the RubyGems Package Manager.
20
+
21
+ First build a gem file starting from the gemspec configuration:
22
+
23
+ $ gem build ruby-monetdb-sql-0.1.gemspec
24
+
25
+ Then install with the command:
26
+
27
+ $ gem install ruby-monetdb-sql-0.1.gem
28
+
29
+ == Usage ==
30
+ To use the standalone driver import the 'MonetDB' class and 'rubygems' (in case you installed it using gems).
31
+
32
+ A typical sequence of events is as follows:
33
+ Invoke query using the database handle to send the statement to the server and get back a result set object.
34
+
35
+ A result set object has methods for fetching rows, moving around in the result set, obtaining column metadata, and releasing the result set.
36
+ Use a row fetching method such as fetch_row or an iterator such as each to access the rows of the result set.
37
+ If you want a count of the number of rows in the result set: invoke 'num_rows' method.
38
+ Invoke 'free' to release the result set.
39
+
40
+ == Example ==
41
+
42
+ require 'MonetDB'
43
+
44
+ db = MonetDB.new
45
+ db.connect(user = "monetdb", passwd = "monetdb", lang = "sql", host="127.0.0.1", port = 50000, db_name = "demo", auth_type = "SHA1")
46
+
47
+ # set type_cast=true to enable MonetDB to Ruby type mapping
48
+ res = db.query("SELECT * from tables;", type_cast = false)
49
+
50
+ #puts res.debug_columns_type
51
+
52
+ puts "Number of rows returned: " + res.num_rows.to_s
53
+ puts "Number of fields: " + res.num_fields.to_s
54
+
55
+
56
+ # Get the columns' name
57
+ col_names = res.name_fields
58
+
59
+
60
+ # Iterate over the record set and retrieve on row at a time
61
+ puts res.fetch
62
+ while row = res.fetch do
63
+ printf "%s \n", row
64
+ end
65
+
66
+ # Release the result set.
67
+ res.free
68
+
69
+ # Disconnect from server
70
+ db.close
71
+
72
+ See lib/demo.rb and the MonetDBDatar class documentation for more examples.
73
+
74
+
75
+
76
+ == ActiveRecord connector adapter ==
77
+ Active Record connects business objects and database tables to create a persistable domain model where logic and data are presented in one wrapping. It‘s an implementation of the object-relational mapping (ORM) pattern.
78
+
79
+ Required files:
80
+
81
+ adapter/lib/active_record/monetdb_adapter.rb
82
+
83
+ Usage example follows:
84
+ require 'active_record'
85
+
86
+ ActiveRecord::Base.logger = Logger.new(STDERR)
87
+ ActiveRecord::Base.colorize_logging = true
88
+
89
+ ActiveRecord::Base.establish_connection(
90
+ :adapter => "monetdb",
91
+ :host => "localhost",
92
+ :database => "demo"
93
+ )
94
+
95
+ # Create a new table
96
+ class AddTests < ActiveRecord::Migration
97
+ def self.up
98
+ create_table :tests do |table|
99
+ table.column :name, :string
100
+ table.column :surname, :string
101
+ end
102
+ end
103
+
104
+ def self.down
105
+ drop_table :tests
106
+ end
107
+
108
+ end
109
+
110
+ AddTests.up
111
+
112
+ # Migration: add a column name with a default value
113
+ class AddAge < ActiveRecord::Migration
114
+ def self.up
115
+ add_column :tests, :age, :smallint, :default => 18
116
+ end
117
+
118
+ def self.down
119
+ remove_column :tests, :age
120
+ end
121
+
122
+ end
123
+
124
+ class Test < ActiveRecord::Base
125
+ end
126
+
127
+ # Insert an entry in the table
128
+ Test.create(:name => 'X', :surname => 'Y')
129
+
130
+ # add a column
131
+ AddAge.up
132
+
133
+ # return the first result of the query SELECT * from tables
134
+ row = Test.find(:first)
135
+ printf "SELECT * from tests LIMIT 1:\n"
136
+ printf "Name: %s, Surname: %s, Age: %s\n", row.name, row.surname, row.age
137
+
138
+ # Drop the table
139
+ AddTests.down
140
+
141
+ == Rubygem ==
142
+
143
+ The standalone ruby driver can be distributed as a ruby gem.
144
+ A gem file is already available; however, it can be generated
145
+ starting from the ruby-monetdb-sql-0.1.gemspec file:
146
+
147
+ $ gem build ruby-monetdb-sql-0.1.gemspec
148
+
149
+ To install the file run the command:
150
+
151
+ $ gem install ruby-monetdb-sql-0.1.gem
152
+
153
+ Documentation in ri and html format will be generated and installed as well
154
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ task :default => :test
7
+
8
+ Rake::TestTask.new do |test|
9
+ test.pattern = "test/**/test_*.rb"
10
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/monetdb.rb ADDED
@@ -0,0 +1,263 @@
1
+ require "monetdb/core_ext"
2
+ require "monetdb/hasher"
3
+ require "monetdb/connection"
4
+ require "monetdb/transaction"
5
+ require "monetdb/data"
6
+ require "monetdb/error"
7
+ require "monetdb/version"
8
+
9
+ # A typical sequence of events is as follows: Create a database instance (handle), invoke query using the database handle to send the statement to the server and get back a result set object.
10
+ #
11
+ # A result set object is an instance of the MonetDB::Data class and has methods for fetching rows, moving around in the result set, obtaining column metadata, and releasing the result set.
12
+ #
13
+ # Records can be returned as arrays and iterators over the set.
14
+ #
15
+ # A database handler (dbh) is an instance of the MonetDB class.
16
+ #
17
+ #
18
+ # = Connection management
19
+ #
20
+ # connect - establish a new connection
21
+ # * user : username (default is monetdb)
22
+ # * passwd : password (default is monetdb)
23
+ # * lang : language (default is sql)
24
+ # * host : server hostanme or ip (default is localhost)
25
+ # * port : server port (default is 50000)
26
+ # * db_name : name of the database to connect to
27
+ # * auth_type : hashing function to use during authentication (default is SHA1)
28
+ # connected? - returns true if there is an active connection to a server, false otherwise
29
+ # reconnect - reconnect to a server
30
+ # close - terminate a connection
31
+ # auto_commit? - returns ture if the session is running in auto commit mode, false otherwise
32
+ # auto_commit - enable/disable auto commit mode
33
+ # query - fire a query
34
+ #
35
+ # Currently MAPI protocols 8 and 9 are supported.
36
+ #
37
+ #
38
+ # = Managing record sets
39
+ #
40
+ # A record set is represented as an instance of the MonetDB::Data class; the class provides methods to manage retrieved data.
41
+ #
42
+ # The following methods allow to iterate over data:
43
+ #
44
+ # fetch - iterates over the record set and retrieves on row at a time. Each row is returned as an array
45
+ # fetch_hash - iterates over columns (on cell at a time)
46
+ # fetch_all_hash - returns record set entries hashed by column name orderd by column position
47
+ #
48
+ # To return the record set as an array (with each tuple stored as array of fields) the following method can be used:
49
+ #
50
+ # fetch_all - fetch all rows and store them
51
+ #
52
+ # Information about the retrieved record set can be obtained via the following methods:
53
+ #
54
+ # num_rows - returns the number of rows present in the record set
55
+ # num_fields - returns the number of fields (columns) that compose the schema
56
+ # name_fields - returns the (ordered) name of the schema's columns
57
+ # type_fields - returns the (ordered) types list of the schema's columns
58
+ #
59
+ # To release a record set MonetDB::Data#free can be used.
60
+ #
61
+ #
62
+ # = Type conversion
63
+ #
64
+ # A mapping between SQL and ruby type is supported. Each retrieved field can be converted to a ruby datatype via
65
+ # a getTYPE method.
66
+ #
67
+ # The currently supported cast methods are:
68
+ #
69
+ # getInt - convert to an integer value
70
+ # getFloat - convert to a floating point value
71
+ # getString - return a string representation of the value, with trailing and leading " characters removed
72
+ # getBlob - convert an SQL stored HEX string to its binary representation
73
+ # getTime - return a string representation of a TIME field
74
+ # getDate - return a string representation of a DATE field
75
+ # getDateTime - convert a TIMESTAMP field to a ruby Time object
76
+ # getChar - on Ruby >= 1.9, convert a CHAR field to char
77
+ # getBool - convert a BOOLEAN field to a ruby bool object. If the value of the field is unknown, nil is returned
78
+ # getNull - convert a NULL value to a nil object
79
+ #
80
+ #
81
+ # = Transactions
82
+ #
83
+ # By default MonetDB works in auto_commit mode. To turn this feature off MonetDB#auto_commit(flag = false) can be used.
84
+ #
85
+ # Once auto_commit has been disabled it is possible to start transactions, create/delete savepoints, rollback and commit with
86
+ # the usual SQL statements.
87
+ #
88
+ # Savepoints IDs can be generated using the MonetDB#save method. To release a savepoint ID use MonetDB#release.
89
+ #
90
+ # You can access savepoints (as a stack) with the MonetDB#transactions method.
91
+ #
92
+
93
+ class MonetDB
94
+
95
+ Q_TABLE = "1" # SELECT operation
96
+ Q_UPDATE = "2" # INSERT/UPDATE operations
97
+ Q_CREATE = "3" # CREATE/DROP TABLE operations
98
+ Q_TRANSACTION = "4" # TRANSACTION
99
+ Q_PREPARE = "5" # QPREPARE message
100
+ Q_BLOCK = "6" # QBLOCK message
101
+
102
+ MSG_REDIRECT = "^" # auth redirection through merovingian
103
+ MSG_QUERY = "&"
104
+ MSG_SCHEMA_HEADER = "%"
105
+ MSG_INFO = "!" # info response from mserver
106
+ MSG_TUPLE = "["
107
+ MSG_PROMPT = ""
108
+
109
+ REPLY_SIZE = "-1"
110
+ MAX_AUTH_ITERATION = 10 # maximum number of auth iterations (through merovingian) allowed
111
+ MONET_ERROR = -1
112
+
113
+ LANG_SQL = "sql"
114
+ LANG_XQUERY = "xquery"
115
+ XQUERY_OUTPUT_SEQ = true # use MonetDB XQuery's output seq
116
+
117
+ def self.logger=(logger)
118
+ @logger = logger
119
+ end
120
+
121
+ def self.logger
122
+ @logger
123
+ end
124
+
125
+ def self.configurations=(configurations)
126
+ @configurations = configurations.inject({}){|h, (k, v)| h[k.to_s] = v; h}
127
+ end
128
+
129
+ def self.configurations
130
+ @configurations
131
+ end
132
+
133
+ def self.establish_connection(arg)
134
+ config = arg.is_a?(Hash) ? arg : (configurations || {})[arg.to_s]
135
+ if config
136
+ @connection = MonetDB.new.tap do |connection|
137
+ config = {language: "sql", encryption: "SHA1"}.merge(config.inject({}){|h, (k, v)| h[k.to_sym] = v; h})
138
+ connection.instance_variable_set(:@config, config)
139
+ connection.connect *config.values_at(:username, :password, :language, :host, :port, :database, :encryption)
140
+ end
141
+ else
142
+ raise Error, "Unable to establish connection for #{arg.inspect}"
143
+ end
144
+ end
145
+
146
+ def self.connection
147
+ @connection
148
+ end
149
+
150
+ # Establish a new connection.
151
+ # * user : username (default is monetdb)
152
+ # * passwd : password (default is monetdb)
153
+ # * lang : language (default is sql)
154
+ # * host : server hostanme or ip (default is localhost)
155
+ # * port : server port (default is 50000)
156
+ # * db_name : name of the database to connect to
157
+ # * auth_type : hashing function to use during authentication (default is SHA1)
158
+ def connect(username = "monetdb", password = "monetdb", lang = "sql", host = "127.0.0.1", port = "50000", db_name = "test", auth_type = "SHA1")
159
+ # TODO: Handle pools of connections
160
+ @username = username
161
+ @password = password
162
+ @lang = lang
163
+ @host = host
164
+ @port = port
165
+ @db_name = db_name
166
+ @auth_type = auth_type
167
+ @connection = MonetDB::Connection.new(user = @username, passwd = @password, lang = @lang, host = @host, port = @port)
168
+ @connection.connect(@db_name, @auth_type)
169
+ end
170
+
171
+ # Send a <b>user submitted</b> query to the server and store the response.
172
+ #
173
+ # Returns an instance of MonetDB::Data.
174
+ def query(q = "")
175
+ unless @connection.nil?
176
+ @data = MonetDB::Data.new(@connection)
177
+ @data.execute(q)
178
+ end
179
+ @data
180
+ end
181
+
182
+ # Send a <b>user submitted select</b> query to the server and store the response.
183
+ #
184
+ # Returns an array of arrays with casted values.
185
+ def select_rows(qry)
186
+ start = Time.now
187
+ data = query(qry)
188
+ log :info, "\n SQL (#{((Time.now - start) * 1000).round(1)}ms) #{qry}"
189
+ column_types = data.instance_variable_get(:@header)["columns_type"]
190
+ types = data.instance_variable_get(:@header)["columns_name"].collect{|x| column_types[x]}
191
+ data.fetch_all.collect do |array|
192
+ row = []
193
+ array.each_with_index do |value, index|
194
+ row << begin
195
+ unless value == "NULL"
196
+ case types[index]
197
+ when "bigint", "int"
198
+ value.to_i
199
+ when "double"
200
+ value.to_f
201
+ else
202
+ value.force_encoding("UTF-8")
203
+ end
204
+ end
205
+ end
206
+ end
207
+ row
208
+ end
209
+ end
210
+
211
+ # Returns whether a "connection" object exists.
212
+ def connected?
213
+ !@connection.nil?
214
+ end
215
+
216
+ # Reconnect to the server.
217
+ def reconnect
218
+ if @connection != nil
219
+ self.close
220
+ @connection = MonetDB::Connection.new(user = @username, passwd = @password, lang = @lang, host = @host, port = @port)
221
+ @connection.connect(db_name = @db_name, auth_type = @auth_type)
222
+ end
223
+ end
224
+
225
+ # Turn auto commit on/off.
226
+ def auto_commit(flag = true)
227
+ @connection.set_auto_commit(flag)
228
+ end
229
+
230
+ # Returns the current auto commit (on/off) setting.
231
+ def auto_commit?
232
+ @connection.auto_commit?
233
+ end
234
+
235
+ # Returns the name of the last savepoint in a transactions pool.
236
+ def transactions
237
+ @connection.savepoint
238
+ end
239
+
240
+ # Create a new savepoint ID.
241
+ def save
242
+ @connection.transactions.save
243
+ end
244
+
245
+ # Release a savepoint ID.
246
+ def release
247
+ @connection.transactions.release
248
+ end
249
+
250
+ # Close an active connection.
251
+ def close
252
+ @connection.disconnect
253
+ @connection = nil
254
+ end
255
+
256
+ private
257
+
258
+ # Log message.
259
+ def log(type, msg)
260
+ MonetDB.logger.send type, msg if MonetDB.logger
261
+ end
262
+
263
+ end