Remove files from monetdb-sql gem

parent 8ecdcc2d
Pipeline #4886 skipped
* Tue 30 Jun 2009 22:14:38 CEST
Added test cases for the standalone driver (ruby unit test).
* Thu 25 Jun 2009 17:31:02 CEST
Fixed a major bug that resulted in data corruption;
MAPI implementation code cleanup and bug fixes;
Support to ruby 1.9;
Both the standalone driver and activerecord now support transactions; nested transactions
are simulated via savepoints in activerecord.
Added a Rakefile and script to run activerecord unit test suite.
Type conversion in the standalone driver is now performed after data has been retrieved and can be executed on single fields.
* Mon 25 May 2009 17:52:01 CEST
Imported last week changes (protocol 9 support, parametrized the connection options in the activerecord adapter, fixed a bug in the auth protocol v8).
Fixed a bug in the mapi protocol that resulted in data loss (wrong handling of TRANSACTIONS).
Began to port the activerecord test suite to monetdb (not all test cases can be performed).
Removed an unneeded file ('lib/MonetDBStatement.rb') from the gemspec of the standalone driver (the feature will be moved to HEAD).
Began to port the driver to ruby 1.9.
Removed *.gem files from cvs.
* Mon 18 May 2009 15:22:31 CEST
Fixed bugs that prevented the correct working of activerecords' migration;
The activerecord connector now supports insertion, update and alter table operations;
Type casting is working in activerecord;
Added a rubygem and rakefile for activerecord-monetdb-adapter;
Added a new usage example for activerecord to the README file;
Added an example directory to the cvs tree;
The driver now correctly works with merovingian.
* Sat 9 May 2009 15:58:36 CEST
Fixed bugs with the query processing in the standalone driver;
Added INSERT and UPDATE methods in the activerecord connector.
* Thu 7 May 2009 17:03:01 CEST
Added a check against the protocol version during authentication;
Imported the activerecord code (available under adapter/).
== Standalone driver ==
This directory contains the a ruby interface to monetdb5
written in pure ruby.
lib/MonetDB.rb
lib/MonetDBConnection.rb
lib/MonetDBStatements.rb
lib/MonetDBData.rb
lib/MonetDBExceptions.rb
lib/hasher.rb
lib/demo.rb: demo application how to interact with the database
ruby-monetdb-sql-0.1.gemspec: make file for rubygems
doc/: rubydoc in HTML format
== Installation ==
The standalone monetdb driver can be installed using the RubyGems Package Manager.
First build a gem file starting from the gemspec configuration:
$ gem build ruby-monetdb-sql-0.1.gemspec
Then install with the command:
$ gem install ruby-monetdb-sql-0.1.gem
== Usage ==
To use the standalone driver import the 'MonetDB' class and 'rubygems' (in case you installed it using gems).
A typical sequence of events is as follows:
Invoke query using the database handle to send the statement to the server and get back a result set object.
A result set object has methods for fetching rows, moving around in the result set, obtaining column metadata, and releasing the result set.
Use a row fetching method such as fetch_row or an iterator such as each to access the rows of the result set.
If you want a count of the number of rows in the result set: invoke 'num_rows' method.
Invoke 'free' to release the result set.
== Example ==
require 'MonetDB'
db = MonetDB.new
db.connect(user = "monetdb", passwd = "monetdb", lang = "sql", host="127.0.0.1", port = 50000, db_name = "demo", auth_type = "SHA1")
# set type_cast=true to enable MonetDB to Ruby type mapping
res = db.query("SELECT * from tables;", type_cast = false)
#puts res.debug_columns_type
puts "Number of rows returned: " + res.num_rows.to_s
puts "Number of fields: " + res.num_fields.to_s
# Get the columns' name
col_names = res.name_fields
# Iterate over the record set and retrieve on row at a time
puts res.fetch
while row = res.fetch do
printf "%s \n", row
end
# Release the result set.
res.free
# Disconnect from server
db.close
See lib/demo.rb and the MonetDBDatar class documentation for more examples.
== ActiveRecord connector adapter ==
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.
Required files:
adapter/lib/active_record/monetdb_adapter.rb
Usage example follows:
require 'active_record'
ActiveRecord::Base.logger = Logger.new(STDERR)
ActiveRecord::Base.colorize_logging = true
ActiveRecord::Base.establish_connection(
:adapter => "monetdb",
:host => "localhost",
:database => "demo"
)
# Create a new table
class AddTests < ActiveRecord::Migration
def self.up
create_table :tests do |table|
table.column :name, :string
table.column :surname, :string
end
end
def self.down
drop_table :tests
end
end
AddTests.up
# Migration: add a column name with a default value
class AddAge < ActiveRecord::Migration
def self.up
add_column :tests, :age, :smallint, :default => 18
end
def self.down
remove_column :tests, :age
end
end
class Test < ActiveRecord::Base
end
# Insert an entry in the table
Test.create(:name => 'X', :surname => 'Y')
# add a column
AddAge.up
# return the first result of the query SELECT * from tables
row = Test.find(:first)
printf "SELECT * from tests LIMIT 1:\n"
printf "Name: %s, Surname: %s, Age: %s\n", row.name, row.surname, row.age
# Drop the table
AddTests.down
== Rubygem ==
The standalone ruby driver can be distributed as a ruby gem.
A gem file is already available; however, it can be generated
starting from the ruby-monetdb-sql-0.1.gemspec file:
$ gem build ruby-monetdb-sql-0.1.gemspec
To install the file run the command:
$ gem install ruby-monetdb-sql-0.1.gem
Documentation in ri and html format will be generated and installed as well
* test and improve utf8 and type conversion
* documentation cleanup
* OSM on rails demo (slowed down due to third party plugins requirements)
# The contents of this file are subject to the MonetDB Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the MonetDB Database System.
#
# The Initial Developer of the Original Code is CWI.
# Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
# Copyright August 2008-2011 MonetDB B.V.
# All Rights Reserved.
gem_adapter = {
FILES = activerecord-monetdb-adapter-0.1.gemspec
DIR = $(prefix)/$(RUBY_DIR)
}
EXTRA_DIST = activerecord-monetdb-adapter-0.1.gemspec
EXTRA_DIST_DIR = active_record lib
Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.1.0'
s.name = %q{activerecord-monetdb-adapter}
s.version = "0.2"
s.date = %q{2009-05-18}
s.authors = ["G Modena"]
s.email = %q{gm@cwi.nl}
s.summary = %q{ActiveRecord Connector for MonetDB}
s.homepage = %q{http://monetdb.cwi.nl/}
s.description = %q{ActiveRecord Connector for MonetDB built on top of the pure Ruby database driver}
s.files = [ "lib/active_record/connection_adapters/monetdb_adapter.rb" ]
s.has_rdoc = true
s.require_path = 'lib'
s.add_dependency(%q<activerecord>, [">= 2.3.2"])
s.add_dependency(%q<ruby-monetdb-sql>, [">= 0.1"])
# placeholder project to avoid warning about not having a rubyforge_project
s.rubyforge_project = "nowarning"
end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# The contents of this file are subject to the MonetDB Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the MonetDB Database System.
#
# The Initial Developer of the Original Code is CWI.
# Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
# Copyright August 2008-2011 MonetDB B.V.
# All Rights Reserved.
# Exception classes for the ruby-monetdb driver
class MonetDBQueryError < StandardError; end
class MonetDBDataError < StandardError; end
class MonetDBCommandError < StandardError; end
class MonetDBConnectionError < StandardError; end
class MonetDBSocketError < StandardError; end
class MonetDBProtocolError < StandardError; end
\ No newline at end of file
# The contents of this file are subject to the MonetDB Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the MonetDB Database System.
#
# The Initial Developer of the Original Code is CWI.
# Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
# Copyright August 2008-2011 MonetDB B.V.
# All Rights Reserved.
require 'MonetDB'
db = MonetDB.new
db.conn({ :user => "monetdb", :passwd => "monetdb", :port => 50000, :language => "sql", :host => "localhost", :database => "ruby_test", :auth_type => "SHA1" })
# set type_cast=true to enable MonetDB to Ruby type mapping
#res = db.query("select * from tables, tables, tables;")
#db.query("DROP TABLE tests2 ")
#db.query(" CREATE TABLE tests2 ( col1 varchar(255), col2 varchar(255)) " )
#puts "Number of rows returned: " + res.num_rows.to_s
#puts "Number of fields: " + res.num_fields.to_s
# Get the columns' name
# print res.name_fields
###### Fetch all rows and store them
#puts res.fetch_all
# Iterate over the record set and retrieve on row at a time
#puts res.fetch
#while row = res.fetch do
# printf "%s \n", row
#end
###### Get all records and hash them by column name
#row = res.fetch_all_hash()
#puts col_names[0] + "\t\t" + col_names[1]
#0.upto(res.num_rows) { |i|
# puts row['id'][i]
#}
###### Iterator over columns (on cell at a time)
#while row = res.fetch_hash do
# printf "%s\n", row["id"]
#end
# SQL TRANSACTIONS and SAVE POINTS
db.query('DROP TABLE tests2')
db.auto_commit(false)
puts db.auto_commit?
# create a savepoint
db.save
db.query("CREATE TABLE tests2 (col1 VARCHAR(255), col2 VARCHAR(255))")
res = db.query("SAVEPOINT #{db.transactions} ;")
res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
#res = db.query("INSERT INTO \"tests2\" VALUES ('€¿®µ¶¹', '€¿®µ¶¹')")
db.query("COMMIT")
db.release
db.save
res = db.query("SAVEPOINT #{db.transactions} ;")
res = db.query("INSERT INTO \"tests2\" VALUES('NAME4', 'SURNAME4')")
res = db.query("ROLLBACK TO SAVEPOINT #{db.transactions};")
db.release
db.auto_commit(true)
puts db.auto_commit?
res = db.query('SELECT * from tests2')
while row = res.fetch do
printf "%s \n", row
end
res.free
db.close
# The contents of this file are subject to the MonetDB Public License
# Version 1.1 (the "License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html
#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
# License for the specific language governing rights and limitations
# under the License.
#
# The Original Code is the MonetDB Database System.
#
# The Initial Developer of the Original Code is CWI.
# Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
# Copyright August 2008-2011 MonetDB B.V.
# All Rights Reserved.
require 'digest/md5'
require 'digest/sha1'
require 'digest/sha2'
class Hasher
# Constructor
# method = "SHA1" or "MD5"
# pwd = Password
def initialize(method, pwd)
if (method.upcase == "SHA1")
@hashfunc = Digest::SHA1.new
@hashname = method.upcase
elsif (method.upcase == "SHA256")
@hashfunc = Digest::SHA256.new
@hashname = method.upcase
elsif (method.upcase == "SHA384")
@hashfunc = Digest::SHA384.new
@hashname = method.upcase
elsif (method.upcase == "SHA512")
@hashfunc = Digest::SHA512.new
@hashname = method.upcase
else
# default to MD5
@hashfunc = Digest::MD5.new
@hashname = "MD5"
end
@pwd = pwd
end
def hashname
@hashname
end
# Compute hash code
def hashsum
return @hashfunc.hexdigest(@pwd)
end
end
# unit test suite for monetdb.
# connects to the 'ruby_test' database and runs test on the server capabilities and SQL language.
# Create first a database with the command:
# $ monetdb create ruby_test
# $ monetdb start ruby_start
#
# Tests examples have been taken from the python and java internfaces and mysql driver.
require 'MonetDB'
require 'test/unit'
require 'time'
require 'date'
class TC_MonetDBCapabilities < Test::Unit::TestCase
# ruby rand function does not support MIN..MAX bounds.
# This alias adds that feature.
alias original_rand rand
def rand(arg1=nil, arg2=nil)
if !arg1.kind_of?(Enumerable) && arg2 == nil
original_rand(arg1)
elsif arg1.kind_of? Enumerable
as_array = arg1.to_a
as_array[original_rand(as_array.length)]
elsif arg1 != nil
arg1 + original_rand(arg2)
end
end
# check the existance of a table
def table_exists?(table='test_ruby')
begin
res = @db.query("select * from #{table} where 1=0")
return true
rescue
return false
end
end
def drop_table(table='test_ruby')
res = @db.query("DROP TABLE #{table}")
end
def setup
@db = MonetDB.new
@db.connect(user = "monetdb", passwd = "monetdb", lang = "sql", host="localhost", port = 50000, db_name = "ruby_test", auth_type = "SHA1")
end
def teardown
@db.close
end
# CREATE TABLE test
def test_create_table(table='test_ruby', cols = [ "First_Name varchar(255)", "Second_Name varchar(255)"])
if table_exists?(table)
drop_table(table)
end
colsdef = ""
cols.each do |c| colsdef += c + ',' end
colsdef = colsdef.chop # remove last ',' character
res = @db.query('CREATE TABLE ' + table + ' (' + colsdef + ')')
end
# perform an inserstion of 'data' into 'table' and check the resulting
# length
def test_data_integrity(table='test_ruby', data=["Gabriele", "MODENA"])
test_create_table
values = ""
data.each do |d| values += '\'' + d.to_s + '\'' + ',' end
values = values.chop # remove last ',' character
insert = 'INSERT INTO ' + table + ' VALUES (' + values + ' )'
@db.query(insert)
res = @db.query("SELECT * FROM #{table}")
rows = res.fetch_all
assert_equal(res.num_rows, rows.size)
end
# test TRANSACTION, COMMIT, ROLLBACK and SAVEPOINT in auto_commit=off mode
def test_transactions(table="test_monetdb_transactions", columndefs=['col1 INT', 'col2 VARCHAR(255)'])
test_create_table(table, columndefs)
data = [1, 'aa']
values = ""
data.each do |d| values += '\'' + d.to_s + '\'' + ',' end
values = values.chop # remove last ',' character
insert = "INSERT INTO " + table + " VALUES " + " ( " + values + " )"
@db.query('START TRANSACTION')
@db.auto_commit(flag=false) # if @db.auto_commit?
@db.query(insert)
@db.query("COMMIT")
res = @db.query('SELECT * FROM ' + table)
rows_committed = res.fetch_all
res.free
# create a save point
@db.save
@db.query("SAVEPOINT #{@db.transactions} ;")
@db.query(insert)
# rollback to savepoint
@db.query("ROLLBACK TO SAVEPOINT #{@db.transactions};")
@db.release
res = @db.query('SELECT * FROM ' + table)
rows_rolled_back = res.fetch_all
res.free
assert_equal(rows_committed, rows_rolled_back)
# restore autocommit for remaining tests
@db.auto_commit(flag=true)
end
# tests on datatypes conversion
def test_char(table="test_monetdb_char", coldefs=["char_field CHAR(1)"])
test_create_table(table, coldefs)
char = 'a'
@db.query("INSERT INTO " + table + " VALUES ( '" + char +"' ) ")
res = @db.query("SELECT char_field FROM " + table + " where char_field = '" + char +"'")
stored_string = res.fetch_hash
assert_equal(char, stored_string['char_field'])
end
def test_smallint(table="test_monetdb_smallint", coldefs=["int_field SMALLINT"])
test_create_table(table, coldefs)
original_num = rand(-32768, 32767)
num = original_num.to_s
@db.query("INSERT INTO " + table + " VALUES ('" + num +"') ")
res = @db.query("SELECT int_field FROM " + table + " where int_field = '" + num +"'")
stored_string = res.fetch_hash
assert_equal(num.to_i, stored_string['int_field'].getInt)
end
def test_int(table="test_monetdb_int", coldefs=["int_field INT"])
test_create_table(table, coldefs)
original_num = rand((2 ** 31 -1))
num = original_num.to_s
@db.query("INSERT INTO " + table + " VALUES ('" + num +"') ")
res = @db.query("SELECT int_field FROM " + table + " where int_field = '" + num +"'")
stored_string = res.fetch_hash
assert_equal(original_num, stored_string['int_field'].getInt)
end
def test_bigint(table="test_monetdb_bigint", coldefs=["int_field BIGINT"])
test_create_table(table, coldefs)
original_num = rand((2 ** 63 -1))
num = original_num.to_s
@db.query("INSERT INTO " + table + " VALUES ('" + num +"') ")
res = @db.query("SELECT int_field FROM " + table + " where int_field = '" + num +"'")
stored_string = res.fetch_hash
assert_equal(original_num, stored_string['int_field'].getInt)
end
def test_real(table="test_monetdb_real", coldefs=["float_field REAL"])
test_create_table(table, coldefs)
original_num = 1.6065851e+20
num = original_num.to_s
@db.query("INSERT INTO " + table + " VALUES ('" + num +"') ")
res = @db.query("SELECT float_field FROM " + table + " where float_field = '" + num +"'")
stored_string = res.fetch_hash
assert_equal(original_num, stored_string['float_field'].getFloat)
end
def test_double(table="test_monetdb_double", coldefs=["float_field DOUBLE"])
test_create_table(table, coldefs)
original_num = 1.6065851e+22
num = original_num.to_s
@db.query("INSERT INTO " + table + " VALUES ('" + num +"') ")
res = @db.query("SELECT float_field FROM " + table + " where float_field = '" + num +"'")
stored_string = res.fetch_hash
assert_equal(original_num, stored_string['float_field'].getFloat)
end
def test_boolean(table="test_monetdb_boolean", coldefs=["bool_field BOOLEAN"] )