dbdom 0.0.1
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.
- data/README +0 -0
- data/README.rdoc +3 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/bin/install-deps.sh +10 -0
- data/dbdom.gemspec +60 -0
- data/lib/advice.rb +35 -0
- data/lib/dbdom.rb +13 -0
- data/lib/jdbc.rb +68 -0
- data/lib/rexml.rb +109 -0
- data/lib/xerces.rb +110 -0
- data/test.sh +4 -0
- data/test/advice_test.rb +48 -0
- data/test/dbdom_test.rb +136 -0
- metadata +88 -0
data/README
ADDED
File without changes
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "dbdom"
|
8
|
+
gemspec.summary = "exposes a jdbc db via dom"
|
9
|
+
gemspec.description = "exposes a jdbc db via dom"
|
10
|
+
gemspec.email = "aaron.hamid@gmail.com"
|
11
|
+
gemspec.homepage = "http://github.com/ahamid/dbdom"
|
12
|
+
gemspec.authors = ["Aaron Hamid"]
|
13
|
+
gemspec.has_rdoc = false # not yet
|
14
|
+
gemspec.files.exclude '.gitignore'
|
15
|
+
# gemspec.files.exclude 'test.sh'
|
16
|
+
|
17
|
+
# I think this is redundant because jeweler requires rubygems already
|
18
|
+
# gemspec.add_dependency('rubygems')
|
19
|
+
|
20
|
+
gemspec.add_dependency('maven_gem')
|
21
|
+
end
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/install-deps.sh
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# the xerces impl requires the xerces jar
|
4
|
+
# although the dependency interfaces should already
|
5
|
+
# be in the JDK
|
6
|
+
|
7
|
+
jruby -S gem install maven_gem
|
8
|
+
jruby -S gem maven xml-apis xml-apis 1.3.04
|
9
|
+
jruby -S gem maven xml-resolver xml-resolver 1.2
|
10
|
+
jruby -S gem maven xerces xercesImpl 2.9.1
|
data/dbdom.gemspec
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{dbdom}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Aaron Hamid"]
|
12
|
+
s.date = %q{2010-03-29}
|
13
|
+
s.default_executable = %q{install-deps.sh}
|
14
|
+
s.description = %q{exposes a jdbc db via dom}
|
15
|
+
s.email = %q{aaron.hamid@gmail.com}
|
16
|
+
s.executables = ["install-deps.sh"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"README",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
"README",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"bin/install-deps.sh",
|
27
|
+
"dbdom.gemspec",
|
28
|
+
"lib/advice.rb",
|
29
|
+
"lib/dbdom.rb",
|
30
|
+
"lib/jdbc.rb",
|
31
|
+
"lib/rexml.rb",
|
32
|
+
"lib/xerces.rb",
|
33
|
+
"test.sh",
|
34
|
+
"test/advice_test.rb",
|
35
|
+
"test/dbdom_test.rb"
|
36
|
+
]
|
37
|
+
s.homepage = %q{http://github.com/ahamid/dbdom}
|
38
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubygems_version = %q{1.3.6}
|
41
|
+
s.summary = %q{exposes a jdbc db via dom}
|
42
|
+
s.test_files = [
|
43
|
+
"test/advice_test.rb",
|
44
|
+
"test/dbdom_test.rb"
|
45
|
+
]
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
|
+
s.specification_version = 3
|
50
|
+
|
51
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
52
|
+
s.add_runtime_dependency(%q<maven_gem>, [">= 0"])
|
53
|
+
else
|
54
|
+
s.add_dependency(%q<maven_gem>, [">= 0"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<maven_gem>, [">= 0"])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
data/lib/advice.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# simple advice support
|
2
|
+
# see: http://refactormycode.com/codes/656-method-hooks-in-ruby-any-cleaner
|
3
|
+
module Advice
|
4
|
+
def advise_before(sym, *methods)
|
5
|
+
advise({ :before => sym }, *methods)
|
6
|
+
end
|
7
|
+
|
8
|
+
def advise_after(sym, *methods)
|
9
|
+
advise({ :after => sym }, *methods)
|
10
|
+
end
|
11
|
+
|
12
|
+
def advise(h = {}, *methods)
|
13
|
+
methods.each do |meth|
|
14
|
+
# save original method
|
15
|
+
hook_method = RUBY_VERSION >= '1.9.0' ? :"__#{meth}__hooked__" : "__#{meth}__hooked__"
|
16
|
+
# create the copy of the hooked method
|
17
|
+
alias_method hook_method, meth
|
18
|
+
# declare the original private
|
19
|
+
private hook_method
|
20
|
+
|
21
|
+
# define our new replacement method
|
22
|
+
define_method meth do |*args|
|
23
|
+
if h.has_key?(:before)
|
24
|
+
method(h[:before]).call meth, args
|
25
|
+
end
|
26
|
+
# call the original method
|
27
|
+
val = send(:"__#{meth}__hooked__", *args)
|
28
|
+
if h.has_key?(:after)
|
29
|
+
method(h[:after]).call meth, args
|
30
|
+
end
|
31
|
+
val
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/dbdom.rb
ADDED
data/lib/jdbc.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module Java
|
4
|
+
module Jdbc
|
5
|
+
# this is apparently not necessary in Java 1.6+
|
6
|
+
# it implements some sort of automatic driver loading
|
7
|
+
def Jdbc.load_driver(driver_class)
|
8
|
+
Java::JavaClass.for_name(driver_class)
|
9
|
+
end
|
10
|
+
|
11
|
+
def Jdbc.get_connection(url, user, password)
|
12
|
+
return java.sql.DriverManager.getConnection(url, user, password)
|
13
|
+
end
|
14
|
+
|
15
|
+
def Jdbc.auto_close(object, &block)
|
16
|
+
begin
|
17
|
+
block.call object
|
18
|
+
ensure
|
19
|
+
object.close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def Jdbc.with_connection(context, &block)
|
24
|
+
load_driver(context[:driver_class]) if context.has_key?(:driver_class)
|
25
|
+
conn = get_connection(context[:url], context[:user], context[:password])
|
26
|
+
auto_close(conn, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def Jdbc.get_tables(conn)
|
30
|
+
rs = conn.getMetaData.getTables(nil, nil, nil, [ "TABLE" ].to_java(:String))
|
31
|
+
auto_close(rs) do |rs|
|
32
|
+
while rs.next do
|
33
|
+
yield rs.getString("TABLE_NAME")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def Jdbc.get_rows(conn, tablename)
|
39
|
+
auto_close(conn.createStatement) do |stmt|
|
40
|
+
rs = stmt.executeQuery("select * from " + tablename)
|
41
|
+
auto_close(rs) do |rs|
|
42
|
+
metadata = rs.getMetaData
|
43
|
+
column_names = []
|
44
|
+
1.upto(metadata.getColumnCount) do |i|
|
45
|
+
column_names << metadata.getColumnName(i)
|
46
|
+
end
|
47
|
+
while rs.next do
|
48
|
+
column_values = []
|
49
|
+
column_names.each_with_index do |name, i|
|
50
|
+
column_values << rs.getString(i + 1)
|
51
|
+
end
|
52
|
+
yield column_names, column_values
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# TODO: determine if it's possible to just alias Module class methods
|
59
|
+
#alias :with_statement :auto_close
|
60
|
+
#alias :with_resultset :auto_close
|
61
|
+
def Jdbc.with_statement(object, &block)
|
62
|
+
auto_close(object, &block)
|
63
|
+
end
|
64
|
+
def Jdbc.with_resultset(object, &block)
|
65
|
+
auto_close(object, &block)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/rexml.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
include REXML
|
3
|
+
|
4
|
+
require 'advice'
|
5
|
+
require 'jdbc'
|
6
|
+
|
7
|
+
module DbDom
|
8
|
+
module Rexml
|
9
|
+
|
10
|
+
class DbDom
|
11
|
+
def createDoc(settings)
|
12
|
+
DbDocument.new(nil, settings)
|
13
|
+
end
|
14
|
+
|
15
|
+
def xpath(node, expr)
|
16
|
+
XPath.match(node, expr);
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class DynamicElement < Element
|
21
|
+
extend Advice
|
22
|
+
|
23
|
+
# this is super-lame
|
24
|
+
# i can't find a way to intercept instance var access
|
25
|
+
# and the REXML Parent class does not provide an initialization hook
|
26
|
+
# so we basically have to wrap each and every method (well, at least
|
27
|
+
# the ones that interact with the @children var), in order to
|
28
|
+
# be able to invoke an initialization method
|
29
|
+
# either the design of the Parent class sucks, or I'm just missing
|
30
|
+
# some great idiomatic way to do this
|
31
|
+
EVERY_SINGLE_PARENT_METHOD = [ :add, :push, :<<, :unshift, :delete,
|
32
|
+
:each, :delete_if, :delete_at, :each_index,
|
33
|
+
:each_child, :[]=, :insert_before, :insert_after,
|
34
|
+
:to_a, :index, :size, :length, :children,
|
35
|
+
:replace_child, :deep_clone ]
|
36
|
+
|
37
|
+
advise_before :initialize_children, *Parent.instance_methods(false)
|
38
|
+
|
39
|
+
def initialize(name, parent, context)
|
40
|
+
super(name, parent, context)
|
41
|
+
@children_initialized = false
|
42
|
+
@initializing = false # hack to avoid re-entrancy
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize_children(method, *args)
|
46
|
+
return if @children_initialized || @initializing
|
47
|
+
@initializing = true
|
48
|
+
init_children
|
49
|
+
@children_initialized = true
|
50
|
+
@initializing = false
|
51
|
+
end
|
52
|
+
|
53
|
+
def init_children
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class DbElement < DynamicElement
|
58
|
+
def initialize(parent, context)
|
59
|
+
super("database", parent, context)
|
60
|
+
end
|
61
|
+
|
62
|
+
def init_children
|
63
|
+
Java::Jdbc.with_connection(context) do |conn|
|
64
|
+
@children = []
|
65
|
+
Java::Jdbc.get_tables(conn) do |name|
|
66
|
+
@children << TableElement.new(name, nil, context);
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class TableElement < DynamicElement
|
73
|
+
def initialize(tablename, parent, context)
|
74
|
+
super("table", parent, context)
|
75
|
+
@tablename = tablename;
|
76
|
+
attributes["name"] = tablename;
|
77
|
+
end
|
78
|
+
|
79
|
+
def init_children
|
80
|
+
Java::Jdbc.with_connection(context) do |conn|
|
81
|
+
rownum = 0
|
82
|
+
Java::Jdbc.get_rows(conn, @tablename) do |column_names, column_values|
|
83
|
+
@children << construct_row(column_names, column_values, rownum)
|
84
|
+
rownum += 1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def construct_row(column_names, column_values, rownum)
|
90
|
+
row = Element.new("row");
|
91
|
+
row.attributes["num"] = rownum.to_s
|
92
|
+
column_names.each_with_index do |name, i|
|
93
|
+
col = Element.new(name)
|
94
|
+
data = Text.new(column_values[i], false)
|
95
|
+
col << data
|
96
|
+
row << col
|
97
|
+
end
|
98
|
+
return row
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class DbDocument < Document
|
103
|
+
def initialize(source = nil, context = {})
|
104
|
+
super(source, context)
|
105
|
+
@children << DbElement.new(nil, context)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
data/lib/xerces.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xercesImpl'
|
3
|
+
require 'java'
|
4
|
+
|
5
|
+
import org.apache.xerces.dom.ElementImpl
|
6
|
+
import org.apache.xerces.dom.CoreDocumentImpl
|
7
|
+
|
8
|
+
module DbDom
|
9
|
+
module Xerces
|
10
|
+
|
11
|
+
class DbDom
|
12
|
+
def createDoc(settings)
|
13
|
+
DatabaseDocument.new(settings)
|
14
|
+
end
|
15
|
+
|
16
|
+
def xpath(node, expr)
|
17
|
+
xpath = javax.xml.xpath.XPathFactory.newInstance.newXPath
|
18
|
+
xpath.evaluate(expr, node, javax.xml.xpath.XPathConstants::NODESET)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class DatabaseElement < org.apache.xerces.dom.ElementImpl
|
23
|
+
def initialize(doc)
|
24
|
+
super(doc, "database")
|
25
|
+
needsSyncChildren(true)
|
26
|
+
@updating = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def synchronizeChildren
|
30
|
+
return if @updating # avoid re-entrancy
|
31
|
+
@updating = true
|
32
|
+
Java::Jdbc.with_connection(ownerDocument.settings) do |conn|
|
33
|
+
Java::Jdbc.get_tables(conn) do |name|
|
34
|
+
appendChild(TableElement.new(ownerDocument, name));
|
35
|
+
end
|
36
|
+
end
|
37
|
+
super
|
38
|
+
@updating = false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class TableElement < org.apache.xerces.dom.ElementImpl
|
43
|
+
def initialize(doc, name)
|
44
|
+
super(doc, "table")
|
45
|
+
needsSyncChildren(true)
|
46
|
+
setAttribute("name", name)
|
47
|
+
@name = name
|
48
|
+
@updating = false
|
49
|
+
end
|
50
|
+
|
51
|
+
def synchronizeChildren
|
52
|
+
return if @updating # avoid re-entrancy
|
53
|
+
@updating = true
|
54
|
+
Java::Jdbc.with_connection(ownerDocument.settings) do |conn|
|
55
|
+
rownum = 0
|
56
|
+
Java::Jdbc.get_rows(conn, @name) do |column_names, column_values|
|
57
|
+
appendChild(construct_row(column_names, column_values, rownum))
|
58
|
+
rownum += 1
|
59
|
+
end
|
60
|
+
end
|
61
|
+
super
|
62
|
+
@updating = false
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
# this implementation just grabs all rows
|
67
|
+
# don't iterate the resultset on demand or implement
|
68
|
+
# any optimizations based on specific Element navigation calls
|
69
|
+
def construct_row(column_names, column_values, rownum)
|
70
|
+
row = ownerDocument.createElement("row");
|
71
|
+
row.setAttribute("num", rownum.to_s)
|
72
|
+
column_names.each_with_index do |name, i|
|
73
|
+
col = ownerDocument.createElement(name)
|
74
|
+
data = ownerDocument.createTextNode(column_values[i])
|
75
|
+
col.appendChild(data)
|
76
|
+
row.appendChild(col)
|
77
|
+
end
|
78
|
+
return row
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class DatabaseDocument < org.apache.xerces.dom.CoreDocumentImpl
|
83
|
+
# http://jira.codehaus.org/browse/JRUBY-2457
|
84
|
+
def initialize(settings)
|
85
|
+
@settings = settings
|
86
|
+
super()
|
87
|
+
needsSyncChildren(true)
|
88
|
+
@docElement = DatabaseElement.new(self)
|
89
|
+
# we need to append the doc root
|
90
|
+
# (which makes sense but hadn't done it when I was just using DOM)
|
91
|
+
# xpath relies on this
|
92
|
+
appendChild(@docElement)
|
93
|
+
end
|
94
|
+
|
95
|
+
attr_reader :settings
|
96
|
+
|
97
|
+
# Note: for some reason calling this class with 'docElement'
|
98
|
+
# did not result in this method being invoked
|
99
|
+
# I moved the initialization to the constructor
|
100
|
+
# this method was implemented because synchronizeChildren didn't
|
101
|
+
# appear to be getting called in the first place
|
102
|
+
def getDocumentElement
|
103
|
+
#def synchronizeChildren
|
104
|
+
# puts "SYNCING"
|
105
|
+
@docElement
|
106
|
+
# super
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/test.sh
ADDED
data/test/advice_test.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'advice'
|
4
|
+
|
5
|
+
class BadClass
|
6
|
+
def initialize
|
7
|
+
@internal_field = "Hi! I'm not designed for extension!"
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_the_internal_field
|
11
|
+
puts "In super method"
|
12
|
+
@internal_field
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class SubClass < BadClass
|
17
|
+
attr_reader :before_called, :after_called, :internal_field
|
18
|
+
|
19
|
+
extend Advice
|
20
|
+
|
21
|
+
advise({ :before => :before_advice, :after => :after_advice }, :get_the_internal_field)
|
22
|
+
|
23
|
+
def before_advice(method, *args)
|
24
|
+
puts "I'm before!"
|
25
|
+
@internal_field = "Overridden"
|
26
|
+
@before_called = true
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_advice(method, *args)
|
30
|
+
puts "I'm after!"
|
31
|
+
@after_called = true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class AdviceTest < Test::Unit::TestCase
|
36
|
+
def test_advice
|
37
|
+
s = SubClass.new
|
38
|
+
f = s.get_the_internal_field
|
39
|
+
assert s.before_called
|
40
|
+
assert s.after_called
|
41
|
+
assert_equal "Overridden", f
|
42
|
+
assert_equal "Overridden", s.internal_field
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
require 'test/unit/ui/console/testrunner'
|
48
|
+
Test::Unit::UI::Console::TestRunner.run(AdviceTest)
|
data/test/dbdom_test.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rexml'
|
3
|
+
require 'xerces'
|
4
|
+
|
5
|
+
PROPERTIES = { :url => 'jdbc:derby:memory:TestDb;create=true' }
|
6
|
+
|
7
|
+
Java::Jdbc.with_connection(PROPERTIES) do |conn|
|
8
|
+
Java::Jdbc.auto_close(conn.createStatement) do |stmt|
|
9
|
+
stmt.execute("create table Boat(id integer, name varchar(20))")
|
10
|
+
stmt.execute("insert into Boat (id, name) values (1, 'andy')")
|
11
|
+
stmt.execute("insert into Boat (id, name) values (2, 'akiva')")
|
12
|
+
stmt.execute("insert into Boat (id, name) values (3, 'jorma')")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class JdbcTest < Test::Unit::TestCase
|
17
|
+
def test_jdbc
|
18
|
+
Java::Jdbc.with_connection(PROPERTIES) do |conn|
|
19
|
+
rs = conn.getMetaData.getTables(nil, nil, nil, [ "TABLE" ].to_java(:String))
|
20
|
+
Java::Jdbc.auto_close(rs) do |rs|
|
21
|
+
assert rs.next
|
22
|
+
assert_equal "boat", rs.getString("TABLE_NAME").downcase
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class RexmlDbDomTest < Test::Unit::TestCase
|
29
|
+
include DbDom::Rexml
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@dbdom = DbDom.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_create_dbdocument
|
36
|
+
doc = @dbdom.createDoc(PROPERTIES)
|
37
|
+
db = doc.root
|
38
|
+
assert_equal 1, db.size
|
39
|
+
table = db[0]
|
40
|
+
assert_equal "boat", table.attributes["name"].downcase
|
41
|
+
assert_equal 3, table.size
|
42
|
+
|
43
|
+
table.children.each_with_index do |row, i|
|
44
|
+
assert_equal i.to_s, row.attributes["num"]
|
45
|
+
assert_equal 2, row.size
|
46
|
+
col = row[0]
|
47
|
+
assert_equal "id", col.name.downcase
|
48
|
+
assert_equal 1, col.size
|
49
|
+
text = col[0]
|
50
|
+
# ???: dbdom_test.rb:44 warning: (...) interpreted as grouped expression
|
51
|
+
assert_equal (i + 1).to_s, text.value
|
52
|
+
col = row[1]
|
53
|
+
assert_equal "name", col.name.downcase
|
54
|
+
assert_equal 1, col.size
|
55
|
+
text = col[0]
|
56
|
+
assert_equal ["andy", "akiva", "jorma"][i], text.value
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_xpath
|
61
|
+
doc = @dbdom.createDoc(PROPERTIES)
|
62
|
+
#puts doc
|
63
|
+
results = @dbdom.xpath(doc, '//database');
|
64
|
+
assert_equal 1, results.size
|
65
|
+
# Rexml does not support predicates? :(
|
66
|
+
# http://arrogantgeek.blogspot.com/2008/01/why-ruby-sucks-1.html
|
67
|
+
#results = XPath.match(doc, "//table[@name='BOAT'/row/NAME");
|
68
|
+
results = @dbdom.xpath(doc, "//table/row/NAME/text()");
|
69
|
+
assert_equal 3, results.size
|
70
|
+
who = ""
|
71
|
+
results.each { |t| who << t.value << " " }
|
72
|
+
puts "On a boat: " + who
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class XercesDbDomTest < Test::Unit::TestCase
|
77
|
+
include DbDom::Xerces
|
78
|
+
|
79
|
+
def setup
|
80
|
+
@dbdom = DbDom.new
|
81
|
+
end
|
82
|
+
|
83
|
+
# damn, bite me
|
84
|
+
# dbdom_test.rb:88:in `const_missing': uninitialized constant Test::Unit::TestSuite::PASSTHROUGH_EXCEPTIONS (NameError)
|
85
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/testcase.rb:82:in `run'
|
86
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
|
87
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
|
88
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
|
89
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'
|
90
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:67:in `start_mediator'
|
91
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/ui/console/testrunner.rb:41:in `start'
|
92
|
+
# from /usr/local/bin/../Cellar/jruby/1.4.0/lib/ruby/1.8/test/unit/ui/testrunnerutilities.rb:29:in `run'
|
93
|
+
# http://stackoverflow.com/questions/1145318/getting-uninitialized-constant-error-when-trying-to-run-tests
|
94
|
+
def test_create_dbdocument
|
95
|
+
doc = @dbdom.createDoc(PROPERTIES)
|
96
|
+
db = doc.documentElement
|
97
|
+
assert_equal 1, db.childNodes.length
|
98
|
+
table = db.childNodes.item(0)
|
99
|
+
assert_equal "boat", table.getAttribute("name").downcase
|
100
|
+
assert_equal 3, table.childNodes.length
|
101
|
+
table.childNodes.length.times do |i|
|
102
|
+
row = table.childNodes.item(i)
|
103
|
+
assert_equal i.to_s, row.getAttribute("num")
|
104
|
+
assert_equal 2, row.childNodes.length
|
105
|
+
col = row.childNodes.item(0)
|
106
|
+
assert_equal "id", col.nodeName.downcase
|
107
|
+
assert_equal 1, col.childNodes.length
|
108
|
+
text = col.childNodes.item(0)
|
109
|
+
# ???: dbdom_test.rb:44 warning: (...) interpreted as grouped expression
|
110
|
+
assert_equal (i + 1).to_s, text.nodeValue
|
111
|
+
col = row.childNodes.item(1)
|
112
|
+
assert_equal "name", col.nodeName.downcase
|
113
|
+
assert_equal 1, col.childNodes.length
|
114
|
+
text = col.childNodes.item(0)
|
115
|
+
assert_equal ["andy", "akiva", "jorma"][i], text.nodeValue
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_xpath
|
120
|
+
doc = @dbdom.createDoc(PROPERTIES)
|
121
|
+
results = @dbdom.xpath(doc, '//database');
|
122
|
+
assert_equal 1, results.length
|
123
|
+
results = @dbdom.xpath(doc, "//table[@name='BOAT']/row/NAME/text()");
|
124
|
+
assert_equal 3, results.length
|
125
|
+
who = ""
|
126
|
+
results.length.times do |i|
|
127
|
+
who << results.item(i).nodeValue << " "
|
128
|
+
end
|
129
|
+
puts "On a boat: " + who
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
require 'test/unit/ui/console/testrunner'
|
134
|
+
Test::Unit::UI::Console::TestRunner.run(JdbcTest)
|
135
|
+
Test::Unit::UI::Console::TestRunner.run(RexmlDbDomTest)
|
136
|
+
Test::Unit::UI::Console::TestRunner.run(XercesDbDomTest)
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dbdom
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Aaron Hamid
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-29 00:00:00 -04:00
|
18
|
+
default_executable: install-deps.sh
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: maven_gem
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: exposes a jdbc db via dom
|
33
|
+
email: aaron.hamid@gmail.com
|
34
|
+
executables:
|
35
|
+
- install-deps.sh
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files:
|
39
|
+
- README
|
40
|
+
- README.rdoc
|
41
|
+
files:
|
42
|
+
- README
|
43
|
+
- README.rdoc
|
44
|
+
- Rakefile
|
45
|
+
- VERSION
|
46
|
+
- bin/install-deps.sh
|
47
|
+
- dbdom.gemspec
|
48
|
+
- lib/advice.rb
|
49
|
+
- lib/dbdom.rb
|
50
|
+
- lib/jdbc.rb
|
51
|
+
- lib/rexml.rb
|
52
|
+
- lib/xerces.rb
|
53
|
+
- test.sh
|
54
|
+
- test/advice_test.rb
|
55
|
+
- test/dbdom_test.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/ahamid/dbdom
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: exposes a jdbc db via dom
|
86
|
+
test_files:
|
87
|
+
- test/advice_test.rb
|
88
|
+
- test/dbdom_test.rb
|