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.
Files changed (154) hide show
  1. data/CHANGELOG +8 -0
  2. data/bin/config.rb +61 -0
  3. data/bin/create_database.rb +13 -6
  4. data/bin/gendata.rb +37 -0
  5. data/bin/migrate.rb +66 -0
  6. data/bin/{rcov-preprocess-files.rb → rcov_preprocess_files.rb} +1 -1
  7. data/bin/run_tests.rb +15 -5
  8. data/bin/update_rdoc.rb +28 -0
  9. data/dohapp_home +0 -0
  10. data/lib/doh/app/activate_database.rb +5 -12
  11. data/lib/doh/app/activate_logger.rb +29 -13
  12. data/lib/doh/app/config.rb +18 -0
  13. data/lib/doh/app/home.rb +3 -8
  14. data/lib/doh/app/init_runnable.rb +39 -8
  15. data/lib/doh/app/init_script.rb +19 -0
  16. data/lib/doh/app/init_unit_test.rb +4 -1
  17. data/lib/doh/app_no_stdio.rb +1 -1
  18. data/lib/doh/boot/app.rb +2 -0
  19. data/lib/doh/boot/app_pwd.rb +2 -0
  20. data/lib/doh/boot/find_dohruby.rb +5 -0
  21. data/lib/doh/boot/find_dohruby_18.rb +37 -0
  22. data/lib/doh/boot/find_dohruby_19.rb +58 -0
  23. data/lib/doh/boot/init_runnable.rb +2 -0
  24. data/lib/doh/boot/options.rb +2 -0
  25. data/lib/doh/core/array.rb +10 -0
  26. data/lib/doh/core/bigdecimal.rb +15 -0
  27. data/lib/doh/core/date.rb +73 -0
  28. data/lib/doh/core/deep_dup.rb +12 -0
  29. data/lib/doh/core/hash.rb +21 -0
  30. data/lib/doh/core/object.rb +6 -0
  31. data/lib/doh/core/require_local.rb +5 -0
  32. data/lib/doh/core/socket.rb +25 -0
  33. data/lib/doh/core/string.rb +34 -4
  34. data/lib/doh/core.rb +4 -1
  35. data/lib/doh/data/basic.rb +24 -19
  36. data/lib/doh/data/bulk.rb +28 -88
  37. data/lib/doh/data/catalog.rb +44 -0
  38. data/lib/doh/data/human.rb +50 -42
  39. data/lib/doh/data/make_global.rb +3 -0
  40. data/lib/doh/data/require_datagen.rb +2 -1
  41. data/lib/doh/home.rb +16 -0
  42. data/lib/doh/logger/email_acceptor.rb +6 -3
  43. data/lib/doh/logger/event.rb +19 -6
  44. data/lib/doh/logger/formatter.rb +22 -16
  45. data/lib/doh/logger/interface.rb +13 -0
  46. data/lib/doh/logger/iostream_acceptor.rb +3 -2
  47. data/lib/doh/logger/null_interface.rb +1 -0
  48. data/lib/doh/logger/proxy.rb +53 -0
  49. data/lib/doh/logger/socket_acceptor.rb +53 -0
  50. data/lib/doh/logger/socket_viewer.rb +64 -0
  51. data/lib/doh/logger/standard_interface.rb +46 -17
  52. data/lib/doh/logger/util.rb +18 -0
  53. data/lib/doh/logger.rb +2 -1
  54. data/lib/doh/logger_configure.rb +1 -1
  55. data/lib/doh/merb/db_session.rb +136 -0
  56. data/lib/doh/merb/form_helpers.rb +16 -0
  57. data/lib/doh/merb/login.rb +27 -12
  58. data/lib/doh/merb/merb_dohsession.rb +4 -0
  59. data/lib/doh/merb/notify_on_exception.rb +1 -1
  60. data/lib/doh/merb/session.rb +7 -0
  61. data/lib/doh/merb/source_ip.rb +10 -0
  62. data/lib/doh/merb.rb +0 -1
  63. data/lib/doh/mysql/abstract_row.rb +81 -0
  64. data/lib/doh/mysql/cache_connector.rb +11 -8
  65. data/lib/doh/mysql/connector_instance.rb +32 -5
  66. data/lib/doh/mysql/connector_util.rb +1 -0
  67. data/lib/doh/mysql/convert.rb +18 -0
  68. data/lib/doh/mysql/database_creator.rb +18 -5
  69. data/lib/doh/mysql/db_date.rb +2 -2
  70. data/lib/doh/mysql/default_type_guesser.rb +21 -4
  71. data/lib/doh/mysql/error.rb +3 -2
  72. data/lib/doh/mysql/handle.rb +144 -18
  73. data/lib/doh/mysql/hash_row.rb +13 -0
  74. data/lib/doh/mysql/load_sql.rb +1 -0
  75. data/lib/doh/mysql/metadata_util.rb +60 -19
  76. data/lib/doh/mysql/migrate.rb +122 -0
  77. data/lib/doh/mysql/migrate_check.rb +139 -0
  78. data/lib/doh/mysql/parse.rb +2 -0
  79. data/lib/doh/mysql/readonly_row.rb +11 -48
  80. data/lib/doh/mysql/require_dbtypes.rb +8 -0
  81. data/lib/doh/mysql/smart_row.rb +156 -0
  82. data/lib/doh/mysql/to_sql.rb +12 -0
  83. data/lib/doh/mysql/typed_row_builder.rb +4 -3
  84. data/lib/doh/mysql/types.rb +33 -0
  85. data/lib/doh/mysql/unquoted.rb +8 -0
  86. data/lib/doh/mysql/version.rb +102 -0
  87. data/lib/doh/mysql/virtual.rb +17 -0
  88. data/lib/doh/mysql/writable_row.rb +58 -0
  89. data/lib/doh/mysql.rb +2 -1
  90. data/lib/doh/paypal/paypal.rb +20 -0
  91. data/lib/doh/paypal/pdt.rb +14 -0
  92. data/lib/doh/paypal.rb +1 -0
  93. data/lib/doh/rails/form_helpers.rb +53 -0
  94. data/lib/doh/rails/login.rb +143 -0
  95. data/lib/doh/test/error_acceptor.rb +1 -1
  96. data/lib/doh/test/run_tests.rb +48 -43
  97. data/lib/doh/test/setup_once.rb +15 -0
  98. data/lib/doh/test/test_result.rb +7 -0
  99. data/lib/doh/unit_test.rb +6 -0
  100. data/lib/doh/util/banking_workday.rb +16 -12
  101. data/lib/doh/util/class_basename.rb +10 -0
  102. data/lib/doh/util/current_date.rb +18 -41
  103. data/lib/doh/util/doh_socket.rb +56 -0
  104. data/lib/doh/util/email.rb +18 -0
  105. data/lib/doh/util/file_edit.rb +64 -0
  106. data/lib/doh/util/http_helper.rb +107 -0
  107. data/lib/doh/util/internal_ip.rb +1 -1
  108. data/lib/doh/util/jsval.rb +13 -0
  109. data/lib/doh/util/post_hash.rb +14 -0
  110. data/lib/doh/util/xml_util.rb +48 -0
  111. data/test/core/tc_array.rb +12 -0
  112. data/test/core/tc_date.rb +53 -0
  113. data/test/core/tc_deep_dup.rb +69 -0
  114. data/test/core/tc_hash.rb +28 -0
  115. data/test/core/tc_socket.rb +30 -0
  116. data/test/core/tc_string.rb +15 -22
  117. data/test/local_tests.rb +3 -0
  118. data/test/local_tests_including_slow.rb +4 -0
  119. data/test/logger/tc_acceptor.rb +23 -6
  120. data/test/logger/tc_event.rb +1 -1
  121. data/test/logger/tc_formatter.rb +3 -2
  122. data/test/logger/tc_socket_viewer_acceptor.rb +48 -0
  123. data/test/mysql/001_down.sql +1 -0
  124. data/test/mysql/001_up.sql +4 -0
  125. data/test/mysql/002_down.sql +1 -0
  126. data/test/mysql/002_up.sql +1 -0
  127. data/test/mysql/tc_connector_instance.rb +8 -8
  128. data/test/mysql/tc_convert.rb +45 -0
  129. data/test/mysql/tc_handle.rb +94 -2
  130. data/test/mysql/tc_metadata_util.rb +50 -0
  131. data/test/mysql/tc_migrate.rb +50 -0
  132. data/test/mysql/tc_parse.rb +3 -1
  133. data/test/mysql/tc_readonly_row.rb +14 -10
  134. data/test/mysql/tc_smart_row.rb +22 -0
  135. data/test/mysql/tc_to_sql.rb +20 -0
  136. data/test/mysql/tc_types.rb +32 -0
  137. data/test/mysql/tc_unquoted.rb +1 -0
  138. data/test/mysql/tc_writable_row.rb +22 -0
  139. data/test/ts_core.rb +4 -0
  140. data/test/ts_logger.rb +4 -0
  141. data/test/ts_mysql.rb +6 -0
  142. data/test/ts_util.rb +6 -0
  143. data/test/util/slow_doh_socket.rb +102 -0
  144. data/test/util/tc_banking_workday.rb +18 -0
  145. data/test/util/tc_file_edit.rb +54 -0
  146. data/test/util/tc_jsval.rb +12 -0
  147. data/test/util/tc_to_display.rb +14 -0
  148. data/test/util/tc_xml_util.rb +17 -0
  149. metadata +130 -39
  150. data/README +0 -4
  151. data/lib/doh/merb/post_hash.rb +0 -26
  152. data/lib/doh/mysql/db_null.rb +0 -24
  153. data/lib/doh/mysql/hash_util.rb +0 -56
  154. data/test/mysql/tc_hash_util.rb +0 -23
@@ -1,4 +1,4 @@
1
1
  require 'doh/logger/standard_interface'
2
2
  require 'doh/logger/direct_scheduler'
3
3
  require 'doh/logger/iostream_acceptor'
4
- require 'doh/logger/interface'
4
+ require 'doh/logger/proxy'
@@ -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
@@ -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
- Doh::log.debug "not authenticated, redirecting to #{login_page}"
39
+ dohlog.debug "not authenticated, redirecting to #{login_page}"
36
40
  session[:dohmerb_original_uri] = request.uri
37
- Doh::log.debug("storing original uri #{request.uri.inspect}")
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
- Doh::log.debug("authenticated? called -- session[:dohmerb_login_username] = #{session[:dohmerb_login_username]}, session[:dohmerb_login_key] = #{session[:dohmerb_login_key]}")
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
- password = DohDb::select_field("SELECT #{password_db_name} FROM #{login_table} WHERE #{login_db_name} = #{username.to_sql}")
52
- key == get_session_key(username, password)
53
- rescue
54
- return nil
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
- Doh::log.debug("redirecting to original uri: #{session[:dohmerb_original_uri].inspect}")
73
- redirect session[:dohmerb_original_uri]
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
- Doh::log.debug("login_helper called, not authenticated -- redirecting to login page")
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,4 @@
1
+ Merb.register_session_type("dohsession",
2
+ "doh/merb/db_session",
3
+ "Using DohMapper database sessions")
4
+
@@ -4,7 +4,7 @@ def notify_on_exception
4
4
  begin
5
5
  yield
6
6
  rescue Exception => e
7
- Doh::log.error('Got unhandled exception', e)
7
+ dohlog.error('Got unhandled exception', e)
8
8
  render :inline => 'System error occured, we\'re working on it.'
9
9
  end
10
10
  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"))
@@ -0,0 +1,10 @@
1
+ require 'doh/util/source_ip'
2
+
3
+ module DohMerb
4
+ def set_source_ip
5
+ dohlog.debug("setting source_ip to: #{request.remote_ip.inspect}")
6
+ Doh::set_source_ip(request.remote_ip)
7
+ end
8
+
9
+
10
+ end
data/lib/doh/merb.rb CHANGED
@@ -1,2 +1 @@
1
1
  require 'doh/merb/notify_on_exception'
2
- require 'doh/merb/post_hash'
@@ -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/raw_row_builder'
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 = 14400
16
- @row_builder = row_builder || RawRowBuilder
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
- Doh::log.debug("DohDb::CacheConnector - closing previous database connection - #{msg}")
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
- Doh::log.info("DohDb::CacheConnector - connecting to #@host as username #@username, #{dbmsg}")
43
- @last_used = Time.now
44
- Handle.new(Mysql.connect(@host, @username, @password, database), @row_builder)
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.select(statement, row_builder = nil)
29
- request_handle.select(statement, row_builder)
35
+ def self.insert_hash(hash, table, ignore = false)
36
+ request_handle.insert_hash(hash, table)
30
37
  end
31
38
 
32
- def self.update_row(statement)
33
- request_handle.update_row(statement)
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/connector_instance'
5
- require 'yaml'
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.ends_with(ext)}.sort.collect {|elem| File.join(path, elem)}
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
- Doh::log.info("DohDb::DatabaseCreator - creating source database " + source_db + " inside " + dest_db)
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
- Doh::log.info("loading file: #{filename}")
95
+ dohlog.info("loading file: #{filename}")
83
96
  load(filename)
84
97
  end
85
98
  end
@@ -21,8 +21,8 @@ def self.today
21
21
  end
22
22
 
23
23
  def self.now
24
- dt = DateTime.now
25
- DateTimeNow.new(dt.year, dt.month, dt.mday, dt.hour, dt.min, dt.sec)
24
+ dt = DateTime.zow
25
+ DateTimeNow.new(dt.year, dt.month, dt.mday, dt.hour, dt.min, dt.sec, dt.zone)
26
26
  end
27
27
 
28
28
  end
@@ -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
- def guess_type(value, meta)
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 == MysqlField::TYPE_NEWDECIMAL
13
- return DohDb::parse_decimal(value) if meta.type == MysqlField::TYPE_DECIMAL
14
- return DohDb::parse_int(value) if (meta.flags & MysqlField::NUM_FLAG) == MysqlField::NUM_FLAG
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
@@ -1,6 +1,7 @@
1
1
  module DohDb
2
2
 
3
- class QueryResultError < StandardError
4
- end
3
+ class UnexpectedQueryResult < StandardError; end
4
+ class UnknownColumn < StandardError; end
5
+ class CannotBeNull < StandardError; end
5
6
 
6
7
  end