dohruby 0.2.1 → 0.3
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/CHANGELOG +8 -0
- data/bin/config.rb +61 -0
- data/bin/create_database.rb +13 -6
- data/bin/gendata.rb +37 -0
- data/bin/migrate.rb +66 -0
- data/bin/{rcov-preprocess-files.rb → rcov_preprocess_files.rb} +1 -1
- data/bin/run_tests.rb +15 -5
- data/bin/update_rdoc.rb +28 -0
- data/dohapp_home +0 -0
- data/lib/doh/app/activate_database.rb +5 -12
- data/lib/doh/app/activate_logger.rb +29 -13
- data/lib/doh/app/config.rb +18 -0
- data/lib/doh/app/home.rb +3 -8
- data/lib/doh/app/init_runnable.rb +39 -8
- data/lib/doh/app/init_script.rb +19 -0
- data/lib/doh/app/init_unit_test.rb +4 -1
- data/lib/doh/app_no_stdio.rb +1 -1
- data/lib/doh/boot/app.rb +2 -0
- data/lib/doh/boot/app_pwd.rb +2 -0
- data/lib/doh/boot/find_dohruby.rb +5 -0
- data/lib/doh/boot/find_dohruby_18.rb +37 -0
- data/lib/doh/boot/find_dohruby_19.rb +58 -0
- data/lib/doh/boot/init_runnable.rb +2 -0
- data/lib/doh/boot/options.rb +2 -0
- data/lib/doh/core/array.rb +10 -0
- data/lib/doh/core/bigdecimal.rb +15 -0
- data/lib/doh/core/date.rb +73 -0
- data/lib/doh/core/deep_dup.rb +12 -0
- data/lib/doh/core/hash.rb +21 -0
- data/lib/doh/core/object.rb +6 -0
- data/lib/doh/core/require_local.rb +5 -0
- data/lib/doh/core/socket.rb +25 -0
- data/lib/doh/core/string.rb +34 -4
- data/lib/doh/core.rb +4 -1
- data/lib/doh/data/basic.rb +24 -19
- data/lib/doh/data/bulk.rb +28 -88
- data/lib/doh/data/catalog.rb +44 -0
- data/lib/doh/data/human.rb +50 -42
- data/lib/doh/data/make_global.rb +3 -0
- data/lib/doh/data/require_datagen.rb +2 -1
- data/lib/doh/home.rb +16 -0
- data/lib/doh/logger/email_acceptor.rb +6 -3
- data/lib/doh/logger/event.rb +19 -6
- data/lib/doh/logger/formatter.rb +22 -16
- data/lib/doh/logger/interface.rb +13 -0
- data/lib/doh/logger/iostream_acceptor.rb +3 -2
- data/lib/doh/logger/null_interface.rb +1 -0
- data/lib/doh/logger/proxy.rb +53 -0
- data/lib/doh/logger/socket_acceptor.rb +53 -0
- data/lib/doh/logger/socket_viewer.rb +64 -0
- data/lib/doh/logger/standard_interface.rb +46 -17
- data/lib/doh/logger/util.rb +18 -0
- data/lib/doh/logger.rb +2 -1
- data/lib/doh/logger_configure.rb +1 -1
- data/lib/doh/merb/db_session.rb +136 -0
- data/lib/doh/merb/form_helpers.rb +16 -0
- data/lib/doh/merb/login.rb +27 -12
- data/lib/doh/merb/merb_dohsession.rb +4 -0
- data/lib/doh/merb/notify_on_exception.rb +1 -1
- data/lib/doh/merb/session.rb +7 -0
- data/lib/doh/merb/source_ip.rb +10 -0
- data/lib/doh/merb.rb +0 -1
- data/lib/doh/mysql/abstract_row.rb +81 -0
- data/lib/doh/mysql/cache_connector.rb +11 -8
- data/lib/doh/mysql/connector_instance.rb +32 -5
- data/lib/doh/mysql/connector_util.rb +1 -0
- data/lib/doh/mysql/convert.rb +18 -0
- data/lib/doh/mysql/database_creator.rb +18 -5
- data/lib/doh/mysql/db_date.rb +2 -2
- data/lib/doh/mysql/default_type_guesser.rb +21 -4
- data/lib/doh/mysql/error.rb +3 -2
- data/lib/doh/mysql/handle.rb +144 -18
- data/lib/doh/mysql/hash_row.rb +13 -0
- data/lib/doh/mysql/load_sql.rb +1 -0
- data/lib/doh/mysql/metadata_util.rb +60 -19
- data/lib/doh/mysql/migrate.rb +122 -0
- data/lib/doh/mysql/migrate_check.rb +139 -0
- data/lib/doh/mysql/parse.rb +2 -0
- data/lib/doh/mysql/readonly_row.rb +11 -48
- data/lib/doh/mysql/require_dbtypes.rb +8 -0
- data/lib/doh/mysql/smart_row.rb +156 -0
- data/lib/doh/mysql/to_sql.rb +12 -0
- data/lib/doh/mysql/typed_row_builder.rb +4 -3
- data/lib/doh/mysql/types.rb +33 -0
- data/lib/doh/mysql/unquoted.rb +8 -0
- data/lib/doh/mysql/version.rb +102 -0
- data/lib/doh/mysql/virtual.rb +17 -0
- data/lib/doh/mysql/writable_row.rb +58 -0
- data/lib/doh/mysql.rb +2 -1
- data/lib/doh/paypal/paypal.rb +20 -0
- data/lib/doh/paypal/pdt.rb +14 -0
- data/lib/doh/paypal.rb +1 -0
- data/lib/doh/rails/form_helpers.rb +53 -0
- data/lib/doh/rails/login.rb +143 -0
- data/lib/doh/test/error_acceptor.rb +1 -1
- data/lib/doh/test/run_tests.rb +48 -43
- data/lib/doh/test/setup_once.rb +15 -0
- data/lib/doh/test/test_result.rb +7 -0
- data/lib/doh/unit_test.rb +6 -0
- data/lib/doh/util/banking_workday.rb +16 -12
- data/lib/doh/util/class_basename.rb +10 -0
- data/lib/doh/util/current_date.rb +18 -41
- data/lib/doh/util/doh_socket.rb +56 -0
- data/lib/doh/util/email.rb +18 -0
- data/lib/doh/util/file_edit.rb +64 -0
- data/lib/doh/util/http_helper.rb +107 -0
- data/lib/doh/util/internal_ip.rb +1 -1
- data/lib/doh/util/jsval.rb +13 -0
- data/lib/doh/util/post_hash.rb +14 -0
- data/lib/doh/util/xml_util.rb +48 -0
- data/test/core/tc_array.rb +12 -0
- data/test/core/tc_date.rb +53 -0
- data/test/core/tc_deep_dup.rb +69 -0
- data/test/core/tc_hash.rb +28 -0
- data/test/core/tc_socket.rb +30 -0
- data/test/core/tc_string.rb +15 -22
- data/test/local_tests.rb +3 -0
- data/test/local_tests_including_slow.rb +4 -0
- data/test/logger/tc_acceptor.rb +23 -6
- data/test/logger/tc_event.rb +1 -1
- data/test/logger/tc_formatter.rb +3 -2
- data/test/logger/tc_socket_viewer_acceptor.rb +48 -0
- data/test/mysql/001_down.sql +1 -0
- data/test/mysql/001_up.sql +4 -0
- data/test/mysql/002_down.sql +1 -0
- data/test/mysql/002_up.sql +1 -0
- data/test/mysql/tc_connector_instance.rb +8 -8
- data/test/mysql/tc_convert.rb +45 -0
- data/test/mysql/tc_handle.rb +94 -2
- data/test/mysql/tc_metadata_util.rb +50 -0
- data/test/mysql/tc_migrate.rb +50 -0
- data/test/mysql/tc_parse.rb +3 -1
- data/test/mysql/tc_readonly_row.rb +14 -10
- data/test/mysql/tc_smart_row.rb +22 -0
- data/test/mysql/tc_to_sql.rb +20 -0
- data/test/mysql/tc_types.rb +32 -0
- data/test/mysql/tc_unquoted.rb +1 -0
- data/test/mysql/tc_writable_row.rb +22 -0
- data/test/ts_core.rb +4 -0
- data/test/ts_logger.rb +4 -0
- data/test/ts_mysql.rb +6 -0
- data/test/ts_util.rb +6 -0
- data/test/util/slow_doh_socket.rb +102 -0
- data/test/util/tc_banking_workday.rb +18 -0
- data/test/util/tc_file_edit.rb +54 -0
- data/test/util/tc_jsval.rb +12 -0
- data/test/util/tc_to_display.rb +14 -0
- data/test/util/tc_xml_util.rb +17 -0
- metadata +130 -39
- data/README +0 -4
- data/lib/doh/merb/post_hash.rb +0 -26
- data/lib/doh/mysql/db_null.rb +0 -24
- data/lib/doh/mysql/hash_util.rb +0 -56
- data/test/mysql/tc_hash_util.rb +0 -23
data/lib/doh/logger_configure.rb
CHANGED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'doh/mysql'
|
|
3
|
+
require 'doh/mysql/metadata_util'
|
|
4
|
+
|
|
5
|
+
module DohMerb
|
|
6
|
+
@@memory_impl = {}
|
|
7
|
+
def self.retrieve_session(session_id)
|
|
8
|
+
@@memory_impl[session_id]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Merb
|
|
13
|
+
module SessionMixin
|
|
14
|
+
def setup_session
|
|
15
|
+
before_value = cookies[_session_id_key]
|
|
16
|
+
request.session, cookies[_session_id_key] = Merb::DohDbSession.persist(cookies[_session_id_key])
|
|
17
|
+
@_fingerprint = Marshal.dump(request.session.data).hash
|
|
18
|
+
@_new_cookie = cookies[_session_id_key] != before_value
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def finalize_session
|
|
22
|
+
request.session.save if @_fingerprint != Marshal.dump(request.session.data).hash
|
|
23
|
+
set_cookie(_session_id_key, request.session.session_id, Time.now + _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def session_store_type
|
|
27
|
+
"dohsession"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class DohDbSession
|
|
32
|
+
attr_accessor :needs_new_cookie, :session_id, :data, :updated_at
|
|
33
|
+
|
|
34
|
+
def initialize(hash = {})
|
|
35
|
+
@data = hash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
# Generates a new session ID and creates a row for the new session in the database.
|
|
40
|
+
def generate
|
|
41
|
+
new_session = self.new({})
|
|
42
|
+
new_session.session_id = Merb::SessionMixin::rand_uuid
|
|
43
|
+
new_session
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Gets the existing session based on the <tt>session_id</tt> available in cookies.
|
|
47
|
+
# If none is found, generates a new session.
|
|
48
|
+
def persist(session_id)
|
|
49
|
+
ensure_session_table_exists
|
|
50
|
+
if !session_id.blank?
|
|
51
|
+
row = DohDb::select_optional_row("SELECT * FROM session WHERE session_id = #{session_id.to_sql}")
|
|
52
|
+
if row
|
|
53
|
+
session = self.new(unmarshal(row['data']))
|
|
54
|
+
session.updated_at = row['updated_at']
|
|
55
|
+
session.session_id = row['session_id']
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
unless session
|
|
59
|
+
session = generate
|
|
60
|
+
end
|
|
61
|
+
[session, session.session_id]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def ensure_session_table_exists
|
|
65
|
+
return if @session_table_exists
|
|
66
|
+
if !DohDb::table_exist?('session')
|
|
67
|
+
create_session_table
|
|
68
|
+
end
|
|
69
|
+
@session_table_exists = true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def create_session_table
|
|
73
|
+
DohDb::query("CREATE TABLE session (session_id CHAR(255), data TEXT, updated_at DATETIME)")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def marshal(data) Base64.encode64(Marshal.dump(data)) if data end
|
|
77
|
+
def unmarshal(data) Marshal.load(Base64.decode64(data)) if data end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Regenerate the Session ID
|
|
81
|
+
def regenerate
|
|
82
|
+
self.session_id = Merb::SessionMixin::rand_uuid
|
|
83
|
+
self.needs_new_cookie = true
|
|
84
|
+
self.save
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Recreates the cookie with the default expiration time
|
|
88
|
+
# Useful during log in for pushing back the expiration date
|
|
89
|
+
def refresh_expiration
|
|
90
|
+
self.needs_new_cookie = true
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# delete of session data
|
|
94
|
+
def delete(key = nil)
|
|
95
|
+
key ? data.delete(key) : data.clear
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def empty?
|
|
99
|
+
data.empty?
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def each(&b)
|
|
103
|
+
data.each(&b)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def each_with_index(&b)
|
|
107
|
+
data.each_with_index(&b)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def [](key)
|
|
111
|
+
data[key]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def []=(key, val)
|
|
115
|
+
data[key] = val
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def delete_old_sessions
|
|
119
|
+
if !@last_deleted || @last_deleted != Date.today
|
|
120
|
+
DohDb::query("DELETE FROM session WHERE updated_at < DATE_SUB(NOW(), interval 20 day)")
|
|
121
|
+
end
|
|
122
|
+
@last_deleted = Date.today
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def save
|
|
126
|
+
DohDbSession::ensure_session_table_exists
|
|
127
|
+
delete_old_sessions
|
|
128
|
+
row = DohDb::select_optional_row("SELECT updated_at FROM session WHERE session_id = #{session_id.to_sql}")
|
|
129
|
+
if row
|
|
130
|
+
DohDb::query("UPDATE session SET data = #{DohDbSession::marshal(data).to_sql}, updated_at = NOW() WHERE session_id = #{session_id.to_sql}")
|
|
131
|
+
else
|
|
132
|
+
DohDb::query("INSERT INTO session (session_id, data, updated_at) VALUES (#{session_id.to_sql}, #{DohDbSession::marshal(data).to_sql}, NOW())")
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module DohMerb
|
|
2
|
+
|
|
3
|
+
#kjmtodo modify to set default value based on model / field name
|
|
4
|
+
def doh_select(model, field, optionarray, opts = {})
|
|
5
|
+
result = ''
|
|
6
|
+
result += "<label>#{opts[:label]}</label>" if opts.key?(:label)
|
|
7
|
+
result += "<select name=\"#{model}[#{field}]\">\n"
|
|
8
|
+
options = optionarray.collect do |elem|
|
|
9
|
+
"<option value=\"#{elem[0]}\">#{elem[1]}</option>"
|
|
10
|
+
end
|
|
11
|
+
result += options.join("\n")
|
|
12
|
+
result += "</select>"
|
|
13
|
+
result
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
data/lib/doh/merb/login.rb
CHANGED
|
@@ -3,7 +3,7 @@ require 'digest'
|
|
|
3
3
|
|
|
4
4
|
module DohMerb
|
|
5
5
|
module Login
|
|
6
|
-
attr_accessor :username_fieldname, :password_fieldname, :login_table, :login_db_name, :password_db_name, :login_page
|
|
6
|
+
attr_accessor :username_fieldname, :password_fieldname, :login_table, :login_db_name, :password_db_name, :login_page, :index_page
|
|
7
7
|
|
|
8
8
|
#set the attr_accessors or override them
|
|
9
9
|
def username_fieldname
|
|
@@ -26,33 +26,43 @@ module Login
|
|
|
26
26
|
@login_page || 'login'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
def index_page
|
|
30
|
+
@index_page || 'index'
|
|
31
|
+
end
|
|
32
|
+
|
|
29
33
|
def password_db_name
|
|
30
34
|
@password_db_name || 'password'
|
|
31
35
|
end
|
|
32
36
|
|
|
33
37
|
def login_required
|
|
34
38
|
if !authenticated?
|
|
35
|
-
|
|
39
|
+
dohlog.debug "not authenticated, redirecting to #{login_page}"
|
|
36
40
|
session[:dohmerb_original_uri] = request.uri
|
|
37
|
-
|
|
41
|
+
dohlog.debug("storing original uri #{request.uri.inspect}")
|
|
38
42
|
redirect login_page
|
|
39
43
|
throw :halt
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
def authenticated?
|
|
44
|
-
|
|
45
|
-
authenticate_username_key(session[:dohmerb_login_username], session[:dohmerb_login_key])
|
|
48
|
+
dohlog.debug("authenticated? called -- session[:dohmerb_login_username] = #{session[:dohmerb_login_username]}, session[:dohmerb_login_key] = #{session[:dohmerb_login_key]}")
|
|
49
|
+
authenticate_username_key(session[:dohmerb_login_username], session[:dohmerb_login_key]) if !session[:dohmerb_login_username].to_s.strip.empty? && !session[:dohmerb_login_key].to_s.strip.empty?
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
# override this to have custom behavior
|
|
49
53
|
def authenticate_username_key(username, key)
|
|
50
54
|
begin
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
row = DohDb::select_optional_row("SELECT * FROM #{login_table} WHERE #{login_db_name} = #{username.to_sql}")
|
|
56
|
+
if row
|
|
57
|
+
if key == get_session_key(username, row[password_db_name])
|
|
58
|
+
self.instance_variable_set("@#{login_table}_row", row)
|
|
59
|
+
return true
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
rescue Exception => e
|
|
63
|
+
dohlog.warn("got error: #{e.inspect} (called from authenticate_username_key) -- are you missing the table: #{login_table.inspect}?")
|
|
55
64
|
end
|
|
65
|
+
return nil
|
|
56
66
|
end
|
|
57
67
|
|
|
58
68
|
def get_session_key(username, password)
|
|
@@ -69,10 +79,15 @@ module Login
|
|
|
69
79
|
session[:dohmerb_login_username] = params[username_fieldname]
|
|
70
80
|
session[:dohmerb_login_key] = get_session_key(params[username_fieldname], params[password_fieldname])
|
|
71
81
|
if authenticated?
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
if session[:dohmerb_original_uri]
|
|
83
|
+
dohlog.debug("redirecting to original uri: #{session[:dohmerb_original_uri].inspect}")
|
|
84
|
+
redirect session[:dohmerb_original_uri]
|
|
85
|
+
else
|
|
86
|
+
dohlog.debug("no original uri, redirecting to index")
|
|
87
|
+
redirect index_page
|
|
88
|
+
end
|
|
74
89
|
else
|
|
75
|
-
|
|
90
|
+
dohlog.debug("login_helper called, not authenticated -- redirecting to login page")
|
|
76
91
|
redirect login_page
|
|
77
92
|
end
|
|
78
93
|
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#this file is intended to be included from a merb applications config/init.rb file
|
|
2
|
+
#after requiring this file from the init.rb, you can then use
|
|
3
|
+
# c[:session_store] = 'dohsession'
|
|
4
|
+
# use_orm :dohsession
|
|
5
|
+
# -- at this point, you will have activated database sessions for merb
|
|
6
|
+
require 'doh/app/home'
|
|
7
|
+
$LOAD_PATH.unshift(File.join(Doh::home, "lib/doh/merb"))
|
data/lib/doh/merb.rb
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module DohDb
|
|
2
|
+
|
|
3
|
+
class AbstractRow
|
|
4
|
+
attr_reader :keys, :values
|
|
5
|
+
deep_dup :keys, :values
|
|
6
|
+
# commented this out because in ruby 1.9 this isn't defined anymore. shouldn't be used anymore in code that uses AbstractRow anyway, so hopefully will be ok
|
|
7
|
+
# undef id
|
|
8
|
+
|
|
9
|
+
def at(index)
|
|
10
|
+
@values.at(index)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get(key)
|
|
14
|
+
index = @keys.index(key)
|
|
15
|
+
if index
|
|
16
|
+
@values.at(index)
|
|
17
|
+
else
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
alias [] get
|
|
22
|
+
|
|
23
|
+
def key?(key)
|
|
24
|
+
!@keys.index(key).nil?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_a
|
|
28
|
+
retval = []
|
|
29
|
+
@keys.size.times {|index| retval.push([@keys[index], @values[index]])}
|
|
30
|
+
retval
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_h
|
|
34
|
+
retval = {}
|
|
35
|
+
@keys.each_with_index {|key, index| retval[key] = @values.at(index)}
|
|
36
|
+
retval
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def inspect
|
|
40
|
+
ary = []
|
|
41
|
+
@keys.size.times {|index| ary.push([@keys[index], @values[index]])}
|
|
42
|
+
ary.inspect
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def each_pair
|
|
46
|
+
@keys.size.times do |index|
|
|
47
|
+
yield(@keys.at(index), @values.at(index))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def size
|
|
52
|
+
@keys.size
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def empty_field?(key)
|
|
56
|
+
return true if !key?(key)
|
|
57
|
+
val = get(key)
|
|
58
|
+
return val.nil? || (val.respond_to?(:empty?) && val.empty?)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# this should probably be removed eventually, but it's here for now for backwards compatibility at least
|
|
62
|
+
def record_id
|
|
63
|
+
get('id')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
protected
|
|
67
|
+
def parse_initialize_args(*args)
|
|
68
|
+
if args.empty?
|
|
69
|
+
[[], []]
|
|
70
|
+
elsif args[0].is_a?(Array)
|
|
71
|
+
raise "first arg is array, second must be also" unless args[1].is_a?(Array)
|
|
72
|
+
raise "first two args are arrays, must be of the same size" unless args[0].size == args[1].size
|
|
73
|
+
args
|
|
74
|
+
else
|
|
75
|
+
hash = args[0]
|
|
76
|
+
[hash.keys, hash.values] + args[1..-1]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
require 'doh/logger'
|
|
2
2
|
require 'doh/mysql/handle'
|
|
3
|
-
require 'doh/mysql/
|
|
3
|
+
require 'doh/mysql/typed_row_builder'
|
|
4
4
|
|
|
5
5
|
module DohDb
|
|
6
6
|
|
|
7
7
|
class CacheConnector
|
|
8
|
-
attr_accessor :host, :username, :password, :database, :row_builder, :timeout
|
|
8
|
+
attr_accessor :host, :username, :password, :database, :row_builder, :timeout, :port
|
|
9
9
|
|
|
10
10
|
def initialize(host = nil, username = nil, password = nil, database = nil, row_builder = nil)
|
|
11
11
|
@host = host
|
|
12
12
|
@username = username
|
|
13
13
|
@password = password
|
|
14
14
|
@database = database
|
|
15
|
-
@timeout =
|
|
16
|
-
@
|
|
15
|
+
@timeout = 1800
|
|
16
|
+
@port = nil
|
|
17
|
+
@row_builder = row_builder || TypedRowBuilder.new
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def request_handle(database = nil)
|
|
@@ -21,6 +22,7 @@ class CacheConnector
|
|
|
21
22
|
close_handle("handle was unused for too long") if passed_timeout?
|
|
22
23
|
@handle = nil if @handle && @handle.closed?
|
|
23
24
|
end
|
|
25
|
+
@last_used = Time.now
|
|
24
26
|
@handle ||= get_new_handle(database)
|
|
25
27
|
end
|
|
26
28
|
|
|
@@ -31,7 +33,7 @@ class CacheConnector
|
|
|
31
33
|
private
|
|
32
34
|
def close_handle(msg)
|
|
33
35
|
return unless @handle
|
|
34
|
-
|
|
36
|
+
dohlog.debug("closing previous database connection - #{msg}")
|
|
35
37
|
@handle.close
|
|
36
38
|
@handle = nil
|
|
37
39
|
end
|
|
@@ -39,9 +41,10 @@ private
|
|
|
39
41
|
def get_new_handle(database = nil)
|
|
40
42
|
database ||= @database
|
|
41
43
|
dbmsg = database.to_s.strip.empty? ? 'no default database' : "database #{database}"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
dohlog.info("connecting to #@host port #@port as username #@username, #{dbmsg}")
|
|
45
|
+
mysqlh = Mysql.connect(@host, @username, @password, database, @port, nil, Mysql::CLIENT_MULTI_STATEMENTS)
|
|
46
|
+
mysqlh.query_with_result = false
|
|
47
|
+
Handle.new(mysqlh, @row_builder)
|
|
45
48
|
end
|
|
46
49
|
|
|
47
50
|
def passed_timeout?
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
module DohDb
|
|
2
|
-
@@connector_instance = nil
|
|
3
2
|
|
|
4
3
|
def self.set_connector_instance(conn)
|
|
5
4
|
@@connector_instance = conn
|
|
@@ -21,16 +20,28 @@ def self.update(statement)
|
|
|
21
20
|
request_handle.update(statement)
|
|
22
21
|
end
|
|
23
22
|
|
|
23
|
+
def self.update_row(statement)
|
|
24
|
+
request_handle.update_row(statement)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.update_hash(hash, table, primary_key_value, primary_key_name)
|
|
28
|
+
request_handle.update_hash(hash, table, primary_key_value, primary_key_name)
|
|
29
|
+
end
|
|
30
|
+
|
|
24
31
|
def self.insert(statement)
|
|
25
32
|
request_handle.insert(statement)
|
|
26
33
|
end
|
|
27
34
|
|
|
28
|
-
def self.
|
|
29
|
-
request_handle.
|
|
35
|
+
def self.insert_hash(hash, table, ignore = false)
|
|
36
|
+
request_handle.insert_hash(hash, table)
|
|
30
37
|
end
|
|
31
38
|
|
|
32
|
-
def self.
|
|
33
|
-
request_handle.
|
|
39
|
+
def self.replace_hash(hash, table)
|
|
40
|
+
request_handle.replace_hash(hash, table)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.select(statement, row_builder = nil)
|
|
44
|
+
request_handle.select(statement, row_builder)
|
|
34
45
|
end
|
|
35
46
|
|
|
36
47
|
def self.select_row(statement, row_builder = nil)
|
|
@@ -49,4 +60,20 @@ def self.select_optional_field(statement, row_builder = nil)
|
|
|
49
60
|
request_handle.select_optional_field(statement, row_builder)
|
|
50
61
|
end
|
|
51
62
|
|
|
63
|
+
def self.select_transpose(statement, row_builder = nil)
|
|
64
|
+
request_handle.select_transpose(statement, row_builder)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.select_values(statement, row_builder = nil)
|
|
68
|
+
request_handle.select_values(statement, row_builder)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def self.select_list(statement, row_builder = nil)
|
|
72
|
+
request_handle.select_list(statement, row_builder)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def self.multi_select(statements)
|
|
76
|
+
request_handle.multi_select(statements)
|
|
77
|
+
end
|
|
78
|
+
|
|
52
79
|
end
|
|
@@ -21,6 +21,7 @@ def self.reconfigure_connector(cfg, connector = nil)
|
|
|
21
21
|
connector.username = cfg['username'] if cfg.key?('username')
|
|
22
22
|
connector.password = cfg['password'] if cfg.key?('password')
|
|
23
23
|
connector.database = cfg['database'] if cfg.key?('database')
|
|
24
|
+
connector.port = cfg['port'] if cfg.key?('port')
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'doh/mysql/metadata_util'
|
|
2
|
+
require 'doh/mysql/error'
|
|
3
|
+
|
|
4
|
+
module DohDb
|
|
5
|
+
|
|
6
|
+
def self.convert(table, column, value)
|
|
7
|
+
info = column_info(table)[column]
|
|
8
|
+
# raise UnknownColumn, "#{table}.#{column}" if info.nil?
|
|
9
|
+
return value if info.nil?
|
|
10
|
+
if value.nil?
|
|
11
|
+
raise CannotBeNull, "#{table}.#{column}" if info['is_nullable'] == 'NO'
|
|
12
|
+
return nil
|
|
13
|
+
end
|
|
14
|
+
return nil if value.is_a?(String) && value.empty? && info['is_nullable'] == 'YES'
|
|
15
|
+
value
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require 'doh/core/dir'
|
|
2
2
|
require 'doh/mysql/handle'
|
|
3
3
|
require 'doh/mysql/load_sql'
|
|
4
|
-
require 'doh/mysql/
|
|
5
|
-
require '
|
|
4
|
+
require 'doh/mysql/version'
|
|
5
|
+
require 'doh/mysql/types'
|
|
6
6
|
|
|
7
7
|
module DohDb
|
|
8
8
|
|
|
@@ -10,6 +10,7 @@ class DatabaseCreator
|
|
|
10
10
|
def initialize(data_directory = nil, connector = nil)
|
|
11
11
|
@data_directory = data_directory || File.join(DohApp::home, 'database')
|
|
12
12
|
@connector = connector || DohDb::connector_instance
|
|
13
|
+
@include_scripts = true
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def create_database(dbname, drop_first = false)
|
|
@@ -18,6 +19,7 @@ class DatabaseCreator
|
|
|
18
19
|
|
|
19
20
|
def create_database_copy(dest_db, source_db, drop_first = false)
|
|
20
21
|
create_one_database(get_nodb_handle, dest_db, source_db, drop_first)
|
|
22
|
+
DohDb::link_database_types(dest_db, source_db)
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def create_all_databases(drop_first = false)
|
|
@@ -26,11 +28,17 @@ class DatabaseCreator
|
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def create_tables(database, drop_first, *table_and_view_names)
|
|
31
|
+
@connector.database = database
|
|
29
32
|
views, tables = table_and_view_names.flatten.sort.partition {|name| File.exist?(sql_filename(database, 'views', name))}
|
|
30
33
|
tables.each {|name| create_base_table(database, name, drop_first)}
|
|
31
34
|
views.each {|name| create_view(database, name, drop_first)}
|
|
32
35
|
end
|
|
33
36
|
|
|
37
|
+
def exclude_scripts
|
|
38
|
+
@include_scripts = false
|
|
39
|
+
self
|
|
40
|
+
end
|
|
41
|
+
|
|
34
42
|
private
|
|
35
43
|
def get_nodb_handle
|
|
36
44
|
@connector.reset
|
|
@@ -45,7 +53,7 @@ private
|
|
|
45
53
|
def find_files(source_db, subdir, ext = '.sql')
|
|
46
54
|
path = File.join(@data_directory, source_db, subdir)
|
|
47
55
|
return [] unless File.exist?(path)
|
|
48
|
-
Dir.entries(path).find_all {|entry| entry.
|
|
56
|
+
Dir.entries(path).find_all {|entry| entry.end_with?(ext)}.sort.collect {|elem| File.join(path, elem)}
|
|
49
57
|
end
|
|
50
58
|
|
|
51
59
|
def view_files(source_db)
|
|
@@ -69,17 +77,22 @@ private
|
|
|
69
77
|
end
|
|
70
78
|
|
|
71
79
|
def create_one_database(dbh, dest_db, source_db, drop_first)
|
|
72
|
-
|
|
80
|
+
dohlog.info("creating database " + dest_db + " from source files at " + File.join(@data_directory, source_db))
|
|
73
81
|
dbh.query("DROP DATABASE IF EXISTS " + dest_db) if drop_first
|
|
74
82
|
|
|
75
83
|
dbh.query("CREATE DATABASE " + dest_db)
|
|
76
84
|
dbh.query("USE " + dest_db)
|
|
85
|
+
dbh.query("CREATE TABLE version (version INT UNSIGNED NOT NULL) ENGINE=MyISAM")
|
|
86
|
+
dbver = DohDb::latest_database_version(source_db)
|
|
87
|
+
dbh.query("INSERT INTO version VALUES (#{dbver})")
|
|
88
|
+
|
|
77
89
|
@connector.database = dest_db
|
|
78
90
|
|
|
79
91
|
files = find_files(source_db, 'tables') + find_files(source_db, 'insert_sql') + view_files(source_db)
|
|
80
92
|
DohDb::load_sql_connector(files, @connector, dest_db)
|
|
93
|
+
return unless @include_scripts
|
|
81
94
|
find_files(source_db, 'insert_scripts', '.rb').each do |filename|
|
|
82
|
-
|
|
95
|
+
dohlog.info("loading file: #{filename}")
|
|
83
96
|
load(filename)
|
|
84
97
|
end
|
|
85
98
|
end
|
data/lib/doh/mysql/db_date.rb
CHANGED
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
require 'mysql'
|
|
2
2
|
require 'doh/mysql/parse'
|
|
3
|
+
require 'doh/util/to_display'
|
|
4
|
+
require 'doh/mysql/types'
|
|
3
5
|
|
|
4
6
|
module DohDb
|
|
5
7
|
|
|
6
8
|
class DefaultTypeGuesser
|
|
7
|
-
|
|
9
|
+
# for compatibility with older mysql gems
|
|
10
|
+
if !MysqlField.const_defined?('TYPE_NEWDECIMAL')
|
|
11
|
+
MysqlField::TYPE_NEWDECIMAL = 246
|
|
12
|
+
end
|
|
13
|
+
DECIMAL_TYPES = [MysqlField::TYPE_DECIMAL, MysqlField::TYPE_NEWDECIMAL]
|
|
14
|
+
INT_TYPES = [MysqlField::TYPE_TINY,MysqlField::TYPE_SHORT,MysqlField::TYPE_LONG,MysqlField::TYPE_LONGLONG,MysqlField::TYPE_INT24]
|
|
15
|
+
|
|
16
|
+
def self.guess_type(value, meta)
|
|
8
17
|
return nil if value.nil?
|
|
18
|
+
|
|
19
|
+
custom_type = DohDb::find_column_type(nil, meta.table, meta.name) || DohDb::find_column_type(nil, nil, meta.name)
|
|
20
|
+
return custom_type.build(meta.name, value) if custom_type
|
|
21
|
+
|
|
9
22
|
return DohDb::parse_bool(value) if (meta.type == MysqlField::TYPE_TINY) && (meta.length == 1) && (meta.max_length == 1)
|
|
10
23
|
return DohDb::parse_datetime(value) if meta.type == MysqlField::TYPE_DATETIME
|
|
11
24
|
return DohDb::parse_date(value) if meta.type == MysqlField::TYPE_DATE
|
|
12
|
-
return DohDb::parse_decimal(value) if meta.type
|
|
13
|
-
return DohDb::
|
|
14
|
-
|
|
25
|
+
return DohDb::parse_decimal(value) if DECIMAL_TYPES.include?(meta.type)
|
|
26
|
+
return DohDb::parse_int(value) if INT_TYPES.include?(meta.type)
|
|
27
|
+
if meta.type == MysqlField::TYPE_STRING || meta.type == MysqlField::TYPE_VAR_STRING
|
|
28
|
+
return PhoneDisplayString.new(value) if (value.size == 10) && (meta.name.lastn(5) == 'phone')
|
|
29
|
+
return SsnDisplayString.new(value) if (value.size == 9) && (meta.max_length == 9) && (meta.name.lastn(3) == 'ssn')
|
|
30
|
+
return PostalDisplayString.new(value) if [5,9].include?(value.size) && [5,9].include?(meta.max_length) && ((meta.name.lastn(6) == 'postal') || (meta.name.lastn(3) == 'zip'))
|
|
31
|
+
end
|
|
15
32
|
value
|
|
16
33
|
end
|
|
17
34
|
end
|