jungle_path 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +22 -0
- data/README.md +5 -0
- data/jungle_path.gemspec +43 -0
- data/lib/jungle_path/api/helpers/auth.rb +45 -0
- data/lib/jungle_path/api/helpers/auth_local_user.rb +284 -0
- data/lib/jungle_path/api/helpers/auth_old.rb +232 -0
- data/lib/jungle_path/api/helpers/data_cache.rb +20 -0
- data/lib/jungle_path/api/helpers/defaults.rb +83 -0
- data/lib/jungle_path/api/helpers/logging.rb +36 -0
- data/lib/jungle_path/api/helpers/query_filters.rb +15 -0
- data/lib/jungle_path/api/helpers/rescues.rb +15 -0
- data/lib/jungle_path/api/helpers/result.rb +16 -0
- data/lib/jungle_path/api/helpers/standard_apis.rb +280 -0
- data/lib/jungle_path/api/helpers.rb +16 -0
- data/lib/jungle_path/api/template.erb +35 -0
- data/lib/jungle_path/api.rb +5 -0
- data/lib/jungle_path/app/a.gitignore +1 -0
- data/lib/jungle_path/app/api/server_base.rb +95 -0
- data/lib/jungle_path/app/api/server_custom.rb +121 -0
- data/lib/jungle_path/app/api/server_gen.rb +11 -0
- data/lib/jungle_path/app/auth/authorization.rb +96 -0
- data/lib/jungle_path/app/config/a.gitignore +1 -0
- data/lib/jungle_path/app/config/config.rb +240 -0
- data/lib/jungle_path/app/config/override.rb +3 -0
- data/lib/jungle_path/app/config.ru +28 -0
- data/lib/jungle_path/app/logs/log_files_go_here +0 -0
- data/lib/jungle_path/app/run.sh +4 -0
- data/lib/jungle_path/app/schemas/schema.rb +21 -0
- data/lib/jungle_path/app/schemas/schema_all_in_one.rb +181 -0
- data/lib/jungle_path/app.rb +8 -0
- data/lib/jungle_path/authentication/auth_provider/default.rb +83 -0
- data/lib/jungle_path/authentication/auth_provider.rb +7 -0
- data/lib/jungle_path/authentication/data_provider/default.rb +144 -0
- data/lib/jungle_path/authentication/data_provider.rb +7 -0
- data/lib/jungle_path/authentication/helpers.rb +19 -0
- data/lib/jungle_path/authentication/identity.rb +30 -0
- data/lib/jungle_path/authentication/password_hash.rb +124 -0
- data/lib/jungle_path/authentication.rb +9 -0
- data/lib/jungle_path/authorization/filter.rb +106 -0
- data/lib/jungle_path/authorization/paths.rb +71 -0
- data/lib/jungle_path/authorization.rb +5 -0
- data/lib/jungle_path/cache.rb +36 -0
- data/lib/jungle_path/config.rb +65 -0
- data/lib/jungle_path/controller/authentication.rb +129 -0
- data/lib/jungle_path/controller/base.rb +193 -0
- data/lib/jungle_path/controller/helpers.rb +47 -0
- data/lib/jungle_path/controller/template.erb +14 -0
- data/lib/jungle_path/controller.rb +7 -0
- data/lib/jungle_path/db_access/import/db_dir.rb +74 -0
- data/lib/jungle_path/db_access/import/delete.rb +30 -0
- data/lib/jungle_path/db_access/import/insert.rb +168 -0
- data/lib/jungle_path/db_access/import/schema.rb +34 -0
- data/lib/jungle_path/db_access/import/select.rb +68 -0
- data/lib/jungle_path/db_access/import.rb +15 -0
- data/lib/jungle_path/db_access/io/chunked_file_reader.rb +62 -0
- data/lib/jungle_path/db_access/io/config.rb +19 -0
- data/lib/jungle_path/db_access/io/copy.rb +73 -0
- data/lib/jungle_path/db_access/io/db.rb +82 -0
- data/lib/jungle_path/db_access/io/delete.rb +23 -0
- data/lib/jungle_path/db_access/io/init_db.rb +39 -0
- data/lib/jungle_path/db_access/io/insert.rb +24 -0
- data/lib/jungle_path/db_access/io/schema.rb +21 -0
- data/lib/jungle_path/db_access/io/select.rb +44 -0
- data/lib/jungle_path/db_access/io/update.rb +36 -0
- data/lib/jungle_path/db_access/io.rb +104 -0
- data/lib/jungle_path/db_model/column.rb +186 -0
- data/lib/jungle_path/db_model/params.rb +60 -0
- data/lib/jungle_path/db_model/schema.rb +100 -0
- data/lib/jungle_path/db_model/string.rb +9 -0
- data/lib/jungle_path/db_model/table.rb +307 -0
- data/lib/jungle_path/db_model.rb +34 -0
- data/lib/jungle_path/exceptions.rb +10 -0
- data/lib/jungle_path/gen/api.rb +52 -0
- data/lib/jungle_path/gen/controller.rb +0 -0
- data/lib/jungle_path/gen/db.rb +0 -0
- data/lib/jungle_path/gen/schema.rb +47 -0
- data/lib/jungle_path/gen/schema_tree/filter.rb +33 -0
- data/lib/jungle_path/gen/schema_tree/match_columns.rb +54 -0
- data/lib/jungle_path/gen/schema_tree/match_table_data.rb +22 -0
- data/lib/jungle_path/gen/schema_tree/match_tables.rb +70 -0
- data/lib/jungle_path/gen/schema_tree/node.rb +39 -0
- data/lib/jungle_path/gen/schema_tree.rb +105 -0
- data/lib/jungle_path/gen.rb +9 -0
- data/lib/jungle_path/json/base.rb +29 -0
- data/lib/jungle_path/json/time.rb +8 -0
- data/lib/jungle_path/json.rb +6 -0
- data/lib/jungle_path/logging.rb +23 -0
- data/lib/jungle_path/query/alias_info.rb +16 -0
- data/lib/jungle_path/query/engine.rb +878 -0
- data/lib/jungle_path/query/entity.rb +141 -0
- data/lib/jungle_path/query/field.rb +28 -0
- data/lib/jungle_path/query/field_primary_key.rb +27 -0
- data/lib/jungle_path/query/filter.rb +34 -0
- data/lib/jungle_path/query/float_value.rb +16 -0
- data/lib/jungle_path/query/from.rb +33 -0
- data/lib/jungle_path/query/int_value.rb +16 -0
- data/lib/jungle_path/query/limit.rb +19 -0
- data/lib/jungle_path/query/nested_hash_sorter.rb +94 -0
- data/lib/jungle_path/query/operator.rb +17 -0
- data/lib/jungle_path/query/query.rb +23 -0
- data/lib/jungle_path/query/sort_field.rb +34 -0
- data/lib/jungle_path/query/sql_string.rb +145 -0
- data/lib/jungle_path/query/string_value.rb +16 -0
- data/lib/jungle_path/query.rb +19 -0
- data/lib/jungle_path/rack/basic_credentials.rb +70 -0
- data/lib/jungle_path/rack/json_body_parser.rb +41 -0
- data/lib/jungle_path/rack.rb +6 -0
- data/lib/jungle_path/schema/auth.rb +83 -0
- data/lib/jungle_path/schema/base.rb +6 -0
- data/lib/jungle_path/schema/db.rb +10 -0
- data/lib/jungle_path/schema/version.rb +19 -0
- data/lib/jungle_path/schema.rb +8 -0
- data/lib/jungle_path/sql/auth_local_user.rb +5 -0
- data/lib/jungle_path/sql/general.rb +10 -0
- data/lib/jungle_path/sql/helpers.rb +11 -0
- data/lib/jungle_path/sql/key.rb +107 -0
- data/lib/jungle_path/sql/query_filter.rb +5 -0
- data/lib/jungle_path/sql/role.rb +5 -0
- data/lib/jungle_path/sql/user.rb +35 -0
- data/lib/jungle_path/sql/user_role.rb +5 -0
- data/lib/jungle_path/sql.rb +12 -0
- data/lib/jungle_path.rb +13 -0
- data/test.rb +33 -0
- data/test2.rb +15 -0
- metadata +200 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module JunglePath
|
2
|
+
module DBAccess
|
3
|
+
module IO
|
4
|
+
require 'jungle_path/db_access/io/init_db'
|
5
|
+
|
6
|
+
class Insert
|
7
|
+
include JunglePath::DBAccess::IO::InitDB
|
8
|
+
|
9
|
+
def _model(model)
|
10
|
+
insert = handle_json_columns(model, model._has_value_hash)
|
11
|
+
puts "inserting: #{insert}."
|
12
|
+
#@db[model._table_name] << insert
|
13
|
+
result = @db[model._table_name].insert(insert)
|
14
|
+
if model._primary_key_columns.count == 1
|
15
|
+
model._values[model._primary_key_columns.keys.first] = result
|
16
|
+
end
|
17
|
+
model._secure = false #allow 'secure' columns to be included in hash.
|
18
|
+
model = model.class.new(model.to_hash, false) # create a new model instance with all values marked as unmodified.
|
19
|
+
model
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module JunglePath
|
2
|
+
require 'jungle_path/db_model/schema'
|
3
|
+
|
4
|
+
module DBAccess
|
5
|
+
module IO
|
6
|
+
require 'jungle_path/db_access/io/init_db'
|
7
|
+
|
8
|
+
class Schema
|
9
|
+
include JunglePath::DBAccess::IO::InitDB
|
10
|
+
|
11
|
+
def drop_table(table_class)
|
12
|
+
JunglePath::DBModel::Schema.new(@db).drop_table table_class
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_table(table_class)
|
16
|
+
JunglePath::DBModel::Schema.new(@db).create_table table_class
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module JunglePath
|
2
|
+
module DBAccess
|
3
|
+
module IO
|
4
|
+
require 'jungle_path/db_access/io/init_db'
|
5
|
+
|
6
|
+
class Select
|
7
|
+
include JunglePath::DBAccess::IO::InitDB
|
8
|
+
|
9
|
+
def _model(model)
|
10
|
+
# select based on a model's primary key.
|
11
|
+
ds = @db[model._table_name].where(model._primary_key)
|
12
|
+
#puts ds.sql
|
13
|
+
hash = ds.first
|
14
|
+
return nil unless hash
|
15
|
+
new_model = model.class.new(hash, false) # false since row (initial values) from db is considered unmodified.
|
16
|
+
end
|
17
|
+
|
18
|
+
def _model_by_any(model)
|
19
|
+
ds = @db[model._table_name].where(handle_json_columns(model, model._modified_hash))
|
20
|
+
#puts ds.sql
|
21
|
+
hash = ds.first
|
22
|
+
#puts "hash: #{hash}. Nil? #{hash == nil}."
|
23
|
+
return nil unless hash
|
24
|
+
new_model = model.class.new(hash, false) # false since row (initial values) from db is considered unmodified.
|
25
|
+
end
|
26
|
+
|
27
|
+
def _models(model, *order_by)
|
28
|
+
# select all of a given model.
|
29
|
+
ds = @db[model._table_name]
|
30
|
+
ds = ds.where(handle_json_columns(model, model._has_value_hash)) if model._has_value_hash.length > 0
|
31
|
+
ds = ds.order(*order_by) if order_by.length > 0
|
32
|
+
ds = ds.order(model._primary_key_columns.keys) unless order_by.length > 0
|
33
|
+
#puts ds.sql
|
34
|
+
rows = ds.all
|
35
|
+
models = []
|
36
|
+
rows.each do |row|
|
37
|
+
models << model.class.new(row, false)
|
38
|
+
end
|
39
|
+
models
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module JunglePath
|
2
|
+
module DBAccess
|
3
|
+
module IO
|
4
|
+
require 'jungle_path/db_access/io/init_db'
|
5
|
+
|
6
|
+
class Update
|
7
|
+
include JunglePath::DBAccess::IO::InitDB
|
8
|
+
|
9
|
+
def _model(model)
|
10
|
+
update = handle_json_columns(model, model._modified_hash)
|
11
|
+
count = update_by_primary_key model, update
|
12
|
+
return {update_count: count}
|
13
|
+
end
|
14
|
+
|
15
|
+
def _models(model_filter, model_values, confirm=false)
|
16
|
+
ds = @db[model_filter._table_name].where(handle_json_columns(model_filter, model_filter._has_value_hash))
|
17
|
+
#puts ds.sql
|
18
|
+
#puts "set values: #{model_values._has_value_hash}."
|
19
|
+
count = 0
|
20
|
+
count = ds.update(handle_json_columns(model_values, model_values._has_value_hash)) if confirm
|
21
|
+
return {update_count: count}
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def update_by_primary_key model, update
|
27
|
+
@db.transaction do
|
28
|
+
ds = @db[model._table_name].where(model._primary_key).for_update
|
29
|
+
#puts ds.sql
|
30
|
+
ds.update update
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
|
3
|
+
module JunglePath
|
4
|
+
module DBAccess
|
5
|
+
module IO
|
6
|
+
require 'jungle_path/db_access/io/chunked_file_reader'
|
7
|
+
require 'jungle_path/db_access/io/config'
|
8
|
+
require 'jungle_path/db_access/io/copy'
|
9
|
+
require 'jungle_path/db_access/io/db'
|
10
|
+
require 'jungle_path/db_access/io/delete'
|
11
|
+
require 'jungle_path/db_access/io/init_db'
|
12
|
+
require 'jungle_path/db_access/io/insert'
|
13
|
+
require 'jungle_path/db_access/io/schema'
|
14
|
+
require 'jungle_path/db_access/io/select'
|
15
|
+
require 'jungle_path/db_access/io/update'
|
16
|
+
|
17
|
+
def self.connection_from_config(config)
|
18
|
+
connection(
|
19
|
+
database_type: config.type,
|
20
|
+
user_name: config.user_name,
|
21
|
+
database_name: config.name,
|
22
|
+
host: config.host,
|
23
|
+
extensions: config.extensions,
|
24
|
+
password: config.password,
|
25
|
+
port: config.port,
|
26
|
+
options: config.options
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.connection_from_config_unknown_database(config)
|
31
|
+
if config.type == 'postgres'
|
32
|
+
connection_from_config_use_postgres_db(config)
|
33
|
+
elsif config.type == 'tinytds'
|
34
|
+
connection_from_config_use_ms_sql_server_db(config)
|
35
|
+
else
|
36
|
+
throw "Unknown database type: #{config.type}."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.connection_from_config_use_ms_sql_server_db(config)
|
41
|
+
db = connection(
|
42
|
+
database_type: config.type,
|
43
|
+
user_name: config.user_name,
|
44
|
+
database_name: 'master',
|
45
|
+
host: config.host,
|
46
|
+
extensions: config.extensions,
|
47
|
+
password: config.password,
|
48
|
+
port: config.port,
|
49
|
+
options: config.options
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.connection_from_config_use_postgres_db(config)
|
54
|
+
db = connection(
|
55
|
+
database_type: config.type,
|
56
|
+
user_name: config.user_name,
|
57
|
+
database_name: 'postgres',
|
58
|
+
host: config.host,
|
59
|
+
extensions: config.extensions,
|
60
|
+
password: config.password,
|
61
|
+
port: config.port,
|
62
|
+
options: config.options
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.clone_config(config)
|
67
|
+
JunglePath::DBAccess::IO::Config.new(
|
68
|
+
name: config.name,
|
69
|
+
type: config.type,
|
70
|
+
user_name: config.user_name,
|
71
|
+
password: config.password,
|
72
|
+
host: config.host,
|
73
|
+
extensions: config.extensions,
|
74
|
+
port: config.port,
|
75
|
+
options: config.options
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.connection(database_type:, user_name:, database_name:, host: "localhost", extensions: [], password: nil, port: nil, options: nil)
|
80
|
+
Sequel.default_timezone = :utc
|
81
|
+
colon_port = ":#{port}" if port
|
82
|
+
options = {} unless options
|
83
|
+
if password
|
84
|
+
puts "Using db connection with explicit password!"
|
85
|
+
connection_string = "#{database_type}://#{user_name}:#{password}@#{host}#{colon_port}/#{database_name}"
|
86
|
+
puts "connection_string: #{connection_string}."
|
87
|
+
db = Sequel.connect(connection_string, options)
|
88
|
+
puts "connected."
|
89
|
+
else
|
90
|
+
puts "no explicit pw."
|
91
|
+
connection_string = "#{database_type}://#{user_name}@#{host}#{colon_port}/#{database_name}"
|
92
|
+
puts "connection_string: #{connection_string}."
|
93
|
+
db = Sequel.connect(connection_string, options)
|
94
|
+
puts "connected."
|
95
|
+
end
|
96
|
+
extensions.each do |extension|
|
97
|
+
puts "Adding Sequel extension: #{extension}."
|
98
|
+
db.extension extension
|
99
|
+
end
|
100
|
+
db
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module JunglePath
|
4
|
+
module DBModel
|
5
|
+
class Column
|
6
|
+
attr_reader :name, :type, :base_type, :foreign_key_table_name, :sequence, :tags, :override_type
|
7
|
+
def initialize(sequence, name, type, primary_key=false, foreign_key=false, foreign_key_table_name=nil, not_null=false, unique=false, secure=false, alternate_key=false, calculated=false, desc=nil, index=nil, unique_index=nil, default_value=nil, tags=nil, override_type=nil)
|
8
|
+
@sequence = sequence
|
9
|
+
@name = name
|
10
|
+
@type = type
|
11
|
+
@override_type = override_type
|
12
|
+
@base_type = get_base_type(@type)
|
13
|
+
@primary_key = primary_key
|
14
|
+
@foreign_key = foreign_key
|
15
|
+
@foreign_key_table_name = foreign_key_table_name
|
16
|
+
@not_null = not_null
|
17
|
+
@unique = unique
|
18
|
+
@secure = secure
|
19
|
+
@alternate_key = alternate_key
|
20
|
+
@calculated = calculated
|
21
|
+
@desc = desc
|
22
|
+
@index = index
|
23
|
+
@unique_index = unique_index
|
24
|
+
@default_value = default_value
|
25
|
+
@tags = tags
|
26
|
+
@is_audit_column = audit_column_names.include? name
|
27
|
+
end
|
28
|
+
|
29
|
+
def primary_key?
|
30
|
+
@primary_key
|
31
|
+
end
|
32
|
+
|
33
|
+
def alternate_key?
|
34
|
+
@alternate_key
|
35
|
+
end
|
36
|
+
|
37
|
+
def foreign_key?
|
38
|
+
@foreign_key
|
39
|
+
end
|
40
|
+
|
41
|
+
def not_null?
|
42
|
+
@not_null
|
43
|
+
end
|
44
|
+
|
45
|
+
def calculated?
|
46
|
+
@calculated
|
47
|
+
end
|
48
|
+
|
49
|
+
def calculated=(value)
|
50
|
+
@calculated = value
|
51
|
+
end
|
52
|
+
|
53
|
+
def unique?
|
54
|
+
@unique
|
55
|
+
end
|
56
|
+
|
57
|
+
def secure?
|
58
|
+
@secure
|
59
|
+
end
|
60
|
+
|
61
|
+
def audit_column_names
|
62
|
+
[:created_at, :updated_at, :created_by_key_id, :created_by_user_id, :updated_by_key_id, :updated_by_user_id].to_set
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_audit_column?
|
66
|
+
@is_audit_column
|
67
|
+
end
|
68
|
+
|
69
|
+
def ruby_type
|
70
|
+
return Integer if @type == :foreign_key
|
71
|
+
return Integer if @type == :primary_key
|
72
|
+
return String if @type == :string
|
73
|
+
return Integer if @type == :integer
|
74
|
+
return DateTime if @type == :timestamp
|
75
|
+
return DateTime if @type == :timestamp_local
|
76
|
+
return TrueClass if @type == :boolean
|
77
|
+
return Date if @type == :date
|
78
|
+
return String if @type == :json
|
79
|
+
return String if @type == :jsonb
|
80
|
+
return Float if @type == :float
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
|
84
|
+
def desc
|
85
|
+
@desc
|
86
|
+
end
|
87
|
+
|
88
|
+
def index
|
89
|
+
@index
|
90
|
+
end
|
91
|
+
|
92
|
+
def unique_index
|
93
|
+
@unique_index
|
94
|
+
end
|
95
|
+
|
96
|
+
def default_value
|
97
|
+
@default_value
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.get_column_def_columns(column_definition, sequence)
|
101
|
+
return audit_key(sequence) if column_definition.length == 1 and column_definition[0] == :audit_key
|
102
|
+
return audit_user(sequence) if column_definition.length == 1 and column_definition[0] == :audit_user
|
103
|
+
return killable(sequence) if column_definition.length == 1 and column_definition[0] == :killable
|
104
|
+
return verification(sequence) if column_definition.length == 1 and column_definition[0] == :verification
|
105
|
+
return audit_data(sequence) if column_definition.length == 1 and column_definition[0] == :audit_data
|
106
|
+
normal(column_definition, (sequence))
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def get_base_type(type)
|
112
|
+
base_type = type
|
113
|
+
if type == :primary_key or type == :foreign_key
|
114
|
+
base_type = :integer
|
115
|
+
end
|
116
|
+
base_type = override_type if override_type
|
117
|
+
base_type
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.normal(array, sequence)
|
121
|
+
name = array[0]
|
122
|
+
type = array[1]
|
123
|
+
#type = :integer if array.include? :primary_key
|
124
|
+
#type = :integer if array.include? :foreign_key
|
125
|
+
primary_key = array.include? :primary_key
|
126
|
+
foreign_key = array.include? :foreign_key
|
127
|
+
foreign_key_table_name = array[array.index(:foreign_key) + 1] if foreign_key
|
128
|
+
not_null = ((array.include? :not_null) or primary_key)
|
129
|
+
unique = array.include? :unique
|
130
|
+
|
131
|
+
contains_unique_index = array.include? :unique_index
|
132
|
+
unique_index = array[array.index(:unique_index) + 1] if contains_unique_index
|
133
|
+
|
134
|
+
contains_index = array.include? :index
|
135
|
+
index = array[array.index(:index) + 1] if contains_index
|
136
|
+
|
137
|
+
secure = array.include? :secure
|
138
|
+
alternate_key = array.include? :alternate_key
|
139
|
+
calculated = array.include? :calculated
|
140
|
+
desc = array[array.index(:desc) + 1] if array.include? :desc
|
141
|
+
override_type = array[array.index(:override_type) + 1] if array.include? :override_type
|
142
|
+
default_index = array.index(:default)
|
143
|
+
default_value = array[default_index + 1] if default_index and default_index > 0
|
144
|
+
tags = array[array.index(:tags) + 1] if array.include? :tags
|
145
|
+
|
146
|
+
columns = [Column.new(sequence, name, type, primary_key, foreign_key, foreign_key_table_name, not_null, unique, secure, alternate_key, calculated, desc, index, unique_index, default_value, tags, override_type)]
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.audit_key(sequence)
|
150
|
+
columns = [
|
151
|
+
normal([:created_at, :timestamp], sequence)[0],
|
152
|
+
normal([:created_by_key_id, :foreign_key, :key], sequence+1)[0],
|
153
|
+
normal([:updated_at, :timestamp], sequence+2)[0],
|
154
|
+
normal([:updated_by_key_id, :foreign_key, :key], sequence+3)[0]]
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.audit_user(sequence)
|
158
|
+
columns = [
|
159
|
+
normal([:created_at, :timestamp], sequence)[0],
|
160
|
+
normal([:created_by_user_id, :foreign_key, :user], sequence+1)[0],
|
161
|
+
normal([:updated_at, :timestamp], sequence+2)[0],
|
162
|
+
normal([:updated_by_user_id, :foreign_key, :user], sequence+3)[0]]
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.killable(sequence)
|
166
|
+
columns = [
|
167
|
+
normal([:active, :boolean], sequence)[0],
|
168
|
+
normal([:effective_date, :date], sequence+1)[0],
|
169
|
+
normal([:kill_date, :date], sequence+2)[0],
|
170
|
+
normal([:kill_by_key_id, :foreign_key, :key], sequence+3)[0],
|
171
|
+
normal([:kill_reason, :string], sequence+4)[0]]
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.verification(sequence)
|
175
|
+
columns = [
|
176
|
+
normal([:verification, :json, :tags, [:verification, :approval]], sequence)[0]]
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.audit_data(sequence)
|
180
|
+
columns = [
|
181
|
+
normal([:audit_data, :json], sequence)[0]]
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module JunglePath
|
2
|
+
module DBModel
|
3
|
+
module Params
|
4
|
+
def self.transform(params, columns)
|
5
|
+
# sinatra params come as string keys with string values.
|
6
|
+
# Convert values to various types based on Schema column definitions.
|
7
|
+
# Convert keys to symbols.
|
8
|
+
p = params.to_hash
|
9
|
+
p = symbolize(p)
|
10
|
+
p = convert_to_type(p, columns)
|
11
|
+
p
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.symbolize(params)
|
15
|
+
p = params.to_hash
|
16
|
+
Hash[p.map {|k, v| [k.to_sym, v] }]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.convert_to_type(params, columns)
|
20
|
+
#params must be hash of symbols (as keys) and values
|
21
|
+
p = {}
|
22
|
+
params = params.to_hash
|
23
|
+
params.each do |k, v|
|
24
|
+
column = columns[k]
|
25
|
+
if column and v
|
26
|
+
#puts "column, type: #{k} #{column.type}."
|
27
|
+
if column.type == :integer or column.base_type == :integer
|
28
|
+
p[k] = v.to_i
|
29
|
+
elsif column.type == :timestamp and v.class == String
|
30
|
+
p[k] = Time.parse(v).utc
|
31
|
+
elsif column.type == :timestamp_local and v.class == String # experimental, probably won't use...
|
32
|
+
p[k] = Time.parse(v)
|
33
|
+
elsif column.type == :date and v.class == String
|
34
|
+
p[k] = Date.parse(v).to_time
|
35
|
+
elsif column.type == :date and v.class == Date
|
36
|
+
p[k] = v.to_time
|
37
|
+
elsif column.type == :boolean
|
38
|
+
p[k] = to_bool(v)
|
39
|
+
elsif (column.type == :string or column.base_type == :string) and v.class == String and v.strip.empty?
|
40
|
+
# treat empty/whitespace only strings as nil.
|
41
|
+
p[k] = nil
|
42
|
+
else
|
43
|
+
p[k] = v
|
44
|
+
end
|
45
|
+
else
|
46
|
+
p[k] = v
|
47
|
+
end
|
48
|
+
end
|
49
|
+
p
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.to_bool(value)
|
53
|
+
return false if value == nil
|
54
|
+
return true if value == true || value =~ (/(true|t|yes|y|on|1)$/i)
|
55
|
+
return false if value == false || value.empty? || value =~ (/(false|f|no|n|off|0)$/i)
|
56
|
+
raise ArgumentError.new("invalid value for Boolean: \"#{value}\"")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module JunglePath
|
2
|
+
module DBModel
|
3
|
+
class Schema
|
4
|
+
def initialize db
|
5
|
+
# db should be a "Sequel" db object that is connected to some database.
|
6
|
+
@db = db
|
7
|
+
end
|
8
|
+
|
9
|
+
def get_sequel_method type
|
10
|
+
return 'foreign_key' if type == :foreign_key
|
11
|
+
return 'primary_key' if type == :primary_key
|
12
|
+
return 'String' if type == :string
|
13
|
+
return 'Integer' if type == :integer
|
14
|
+
return 'DateTime' if type == :timestamp
|
15
|
+
return 'DateTime' if type == :timestamp_local
|
16
|
+
return 'TrueClass' if type == :boolean
|
17
|
+
return 'Date' if type == :date
|
18
|
+
return 'json' if type == :json
|
19
|
+
return 'jsonb' if type == :jsonb
|
20
|
+
return 'Float' if type == :float
|
21
|
+
return type
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_postgresql_override_type type
|
25
|
+
return 'text' if type == :string
|
26
|
+
return 'integer' if type == :integer
|
27
|
+
return 'bigint' if type == :bigint
|
28
|
+
return 'timestamp' if type == :timestamp
|
29
|
+
return 'timestamp' if type == :timestamp_local
|
30
|
+
return 'boolean' if type == :boolean
|
31
|
+
return 'date' if type == :date
|
32
|
+
return 'json' if type == :json
|
33
|
+
return 'jsonb' if type == :jsonb
|
34
|
+
return 'double' if type == :float
|
35
|
+
return type.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_table table_class
|
39
|
+
# translate column type keys into Sequel methods used by Sequel (DB.create_table).
|
40
|
+
|
41
|
+
# call the Sequel DB.create_table method with a block:
|
42
|
+
#puts "\ttable_name: #{table_class.table_name}"
|
43
|
+
schema = self
|
44
|
+
@db.create_table? table_class.table_name do
|
45
|
+
made_pk = false
|
46
|
+
table_class.columns.each_value do |column|
|
47
|
+
puts "\tcolumn: #{column.name} #{schema.get_sequel_method(column.type)} #{column.foreign_key_table_name}."
|
48
|
+
method = schema.get_sequel_method(column.type)
|
49
|
+
args_hash = {}
|
50
|
+
if column.foreign_key? and column.not_null?
|
51
|
+
#args = [column.name, column.foreign_key_table_name, :null=>false]
|
52
|
+
args = [column.name, column.foreign_key_table_name]
|
53
|
+
args_hash[:null] = false
|
54
|
+
elsif column.foreign_key?
|
55
|
+
args = [column.name, column.foreign_key_table_name]
|
56
|
+
elsif column.primary_key?
|
57
|
+
args = [column.name]
|
58
|
+
#made_pk = true
|
59
|
+
else
|
60
|
+
args = [column.name]
|
61
|
+
end
|
62
|
+
args_hash[:unique] = true if column.unique?
|
63
|
+
args_hash[:null] = false if column.not_null?
|
64
|
+
args_hash[:type] = schema.get_postgresql_override_type(column.override_type) unless column.override_type == nil
|
65
|
+
args_hash[:default] = column.default_value unless column.default_value == nil
|
66
|
+
args << args_hash
|
67
|
+
#puts "\t\tmethod: #{method}. args:#{args}.\n"
|
68
|
+
made_pk = true if column.type == :primary_key # only happens when pk is single column.
|
69
|
+
puts "column: #{column.name}, override_type: #{column.override_type}, override_type.class: #{column.override_type.class}, method: #{method}, args: #{args}."
|
70
|
+
send(method, *args)
|
71
|
+
|
72
|
+
#index:
|
73
|
+
if column.index
|
74
|
+
send('index', column.index)
|
75
|
+
end
|
76
|
+
|
77
|
+
#unique index:
|
78
|
+
if column.unique_index
|
79
|
+
send('unique', column.unique_index)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if not made_pk
|
84
|
+
#puts "creating primary_key for table #{table_class.name}. keys: #{table_class.primary_key_columns.keys}."
|
85
|
+
send('primary_key', table_class.primary_key_columns.keys, :name=>"#{table_class.table_name}_pk".to_sym)
|
86
|
+
end
|
87
|
+
#puts "end of block"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_table! table_class
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def drop_table table_class
|
96
|
+
@db.drop_table? table_class.table_name
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|