fossil 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/fossil.gemspec +7 -2
- data/lib/fos_schema/FOS_SCHEMA_3.8.22.r3.csv +8211 -0
- data/lib/fos_schema/FOS_SCHEMA_3.8.27.r1.csv +8696 -0
- data/lib/fos_schema/FOS_SCHEMA_3.9.0.csv +8746 -0
- data/lib/fos_schema/fos_schema_snapshot.rb +47 -0
- data/lib/fos_schema/fos_table_gen.rb +124 -0
- data/lib/number_helper.rb +214 -287
- data/lib/sequel/model_patch.rb +1 -1
- metadata +7 -2
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sequel'
|
3
|
+
require 'logger'
|
4
|
+
require 'fastercsv'
|
5
|
+
require File.dirname(__FILE__) +'/../sequel/pervasive'
|
6
|
+
|
7
|
+
Sequel::Model.plugin(:schema)
|
8
|
+
DB = Sequel.connect("odbc:/#{ARGV[0]}")#, :loggers => [ Logger.new( $stdout ) ] )
|
9
|
+
DB.extend(Sequel::Pervasive::DatabaseMethods)
|
10
|
+
|
11
|
+
class XFILE < Sequel::Model( :'x$file' )
|
12
|
+
#~ xf$name, xf$loc, xf$flags, xf$reserved
|
13
|
+
set_primary_key :'xf$id'
|
14
|
+
one_to_many :fields, :class => :XFIELD, :key => :'xe$file'
|
15
|
+
one_to_many :indices, :class => :XINDEX, :key => :'xi$file'
|
16
|
+
end
|
17
|
+
|
18
|
+
class XFIELD < Sequel::Model( :'x$field' )
|
19
|
+
#~ xe$file xe$name xe$datatype xe$offset xe$size xe$dec xe$flags
|
20
|
+
set_primary_key :'xe$id'
|
21
|
+
many_to_one :file, :class => :XFILE, :key => :'xe$file', :primary_key => :'xf$id'
|
22
|
+
def <=>( other )
|
23
|
+
self[:'xe$name'] <=> other[:'xe$name']
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class XINDEX < Sequel::Model( :'x$index' )
|
28
|
+
#~ xi$file xi$field xi$number xi$part xi$flags
|
29
|
+
set_primary_key [:'xi$file', :'xi$field', :'xi$part']
|
30
|
+
many_to_one :field, :class => :XFIELD, :key => :'xi$field', :primary_key => :'xe$id'
|
31
|
+
def <=>( other )
|
32
|
+
val = self[:'xi$number'] <=> other[:'xi$number']
|
33
|
+
val = self[:'xi$part'] <=> other[:'xi$part'] if val == 0
|
34
|
+
val
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
FasterCSV.open("FOS_SCHEMA_#{ARGV[1]}.csv", 'w') do |csv|
|
39
|
+
csv << 'table_name,table_flags,column_name,column_datatype,column_size,column_dec,column_flags'.split(',')
|
40
|
+
tables = XFILE.filter(~:'xf$flags' => 16).and(:'xf$loc'.like('%.btr')).or(:'xf$loc'.like('%.BTR')).order(:'xf$name').all
|
41
|
+
tables.each do |table|
|
42
|
+
fields = table.fields.sort
|
43
|
+
fields.each do |field|
|
44
|
+
csv << [ table[:'xf$name'],table[:'xf$flags'],field[:'xe$name'],field[:'xe$datatype'],field[:'xe$size'],field[:'xe$dec'],field[:'xe$flags'] ]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sequel'
|
3
|
+
require 'logger'
|
4
|
+
require File.dirname(__FILE__) +'/../sequel/pervasive'
|
5
|
+
|
6
|
+
Sequel::Model.plugin(:schema)
|
7
|
+
$db = Sequel.connect('odbc:/FOS')#, :loggers => [ Logger.new( $stdout ) ] )
|
8
|
+
$db.extend(Sequel::Pervasive::DatabaseMethods)
|
9
|
+
|
10
|
+
class XFILE < Sequel::Model( :'x$file' )
|
11
|
+
#~ xf$name, xf$loc, xf$flags, xf$reserved
|
12
|
+
set_primary_key :'xf$id'
|
13
|
+
one_to_many :fields, :class => :XFIELD, :key => :'xe$file'
|
14
|
+
one_to_many :indices, :class => :XINDEX, :key => :'xi$file'
|
15
|
+
end
|
16
|
+
|
17
|
+
class XFIELD < Sequel::Model( :'x$field' )
|
18
|
+
#~ xe$file xe$name xe$datatype xe$offset xe$size xe$dec xe$flags
|
19
|
+
set_primary_key :'xe$id'
|
20
|
+
many_to_one :file, :class => :XFILE, :key => :'xe$file', :primary_key => :'xf$id'
|
21
|
+
def <=>( other )
|
22
|
+
self[:'xe$name'] <=> other[:'xe$name']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class XINDEX < Sequel::Model( :'x$index' )
|
27
|
+
#~ xi$file xi$field xi$number xi$part xi$flags
|
28
|
+
set_primary_key [:'xi$file', :'xi$field', :'xi$part']
|
29
|
+
many_to_one :field, :class => :XFIELD, :key => :'xi$field', :primary_key => :'xe$id'
|
30
|
+
def <=>( other )
|
31
|
+
val = self[:'xi$number'] <=> other[:'xi$number']
|
32
|
+
val = self[:'xi$part'] <=> other[:'xi$part'] if val == 0
|
33
|
+
val
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class FOSClassGenerator
|
38
|
+
CLASS_TEXT = <<-STR
|
39
|
+
class CLASS_NAME < Sequel::Model(:'TABLE_NAME')\n
|
40
|
+
SEQUEL_INFO
|
41
|
+
end
|
42
|
+
STR
|
43
|
+
|
44
|
+
SEQUEL_TEXT = <<-STR
|
45
|
+
#### BEGIN GENERATED SECTION ####
|
46
|
+
\tset_primary_key [:'kid - user', :'kid - mult', :'kid - comm', :'kid - date', :'kid - time']
|
47
|
+
COLUMN_DEFINITIONS
|
48
|
+
#### END GENERATED SECTION ####
|
49
|
+
STR
|
50
|
+
|
51
|
+
def initialize( file )
|
52
|
+
@file = file
|
53
|
+
@table_name = file[:'xf$name'].downcase
|
54
|
+
@escaped_table_name = @table_name.gsub('\'', "\\\\\\\\'")
|
55
|
+
@class_name = make_pretty_table_name(@table_name)
|
56
|
+
@file_name = make_pretty_file_name(@table_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def write_class_file
|
60
|
+
file_name = File.join("..","..","models","#{@file_name}.rb")
|
61
|
+
puts "filename=#{file_name}"
|
62
|
+
file_str = File.exists?(file_name) ? File.read(file_name) : new_class_text
|
63
|
+
sequel_part = build_sequel_section
|
64
|
+
#~ puts sequel_part if @file_name == "aircraft"
|
65
|
+
if( !file_str.sub!(/#### BEGIN GENERATED SECTION ####[^.|.]*#### END GENERATED SECTION ####/, sequel_part.chop) )
|
66
|
+
puts "CANNOT SUBSTITUTE NEW TEXT INTO OLD FILE for #{@file_name}"
|
67
|
+
return
|
68
|
+
end
|
69
|
+
File.open(file_name,"w"){ |file| file.write(file_str) }
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def build_sequel_section
|
75
|
+
text = SEQUEL_TEXT.dup
|
76
|
+
column_info = @file.fields.sort.inject("") do |str, field|
|
77
|
+
field_name = field[:'xe$name'].downcase
|
78
|
+
str << "\n\tcolumn_alias :#{make_pretty_column_name(field_name)}, :'#{field_name.gsub("'", "\\\\\\\\\\\\\\\\'")}'"
|
79
|
+
end
|
80
|
+
text.sub!(/COLUMN_DEFINITIONS/,column_info)
|
81
|
+
text
|
82
|
+
end
|
83
|
+
|
84
|
+
def new_class_text
|
85
|
+
class_text = CLASS_TEXT.dup
|
86
|
+
class_text.sub!(/CLASS_NAME/,@class_name)
|
87
|
+
class_text.sub!(/TABLE_NAME/,@escaped_table_name)
|
88
|
+
class_text.sub!(/SEQUEL_INFO/,SEQUEL_TEXT.dup)
|
89
|
+
class_text
|
90
|
+
end
|
91
|
+
|
92
|
+
def make_pretty_table_name( ugly_name )
|
93
|
+
new_name = ugly_name.downcase.split( /[\s\/\'\-\&]/ ).collect { |v| v.capitalize }.join
|
94
|
+
new_name.chop! if new_name.split( '' ).last.downcase == "s"
|
95
|
+
new_name
|
96
|
+
end
|
97
|
+
|
98
|
+
def make_pretty_column_name( ugly_name )
|
99
|
+
better_name = ugly_name.gsub(' - ', ' ')
|
100
|
+
slightly_better_name = better_name.gsub('.', '')
|
101
|
+
even_better_name = slightly_better_name.gsub( /[\s\s]/, ' ' )
|
102
|
+
more_better_name = even_better_name.gsub('+', '_and_').gsub('<=', '_less_than_or_equal_to_').gsub('<', '_less_than_').gsub('>', '_more_than_').gsub('(text)', 'text').gsub('a/p', 'ap').gsub('a/c', 'ac')
|
103
|
+
super_good_name = more_better_name.downcase.gsub( /[\s\/\'\-\&]/, "_" )
|
104
|
+
excellent_name = super_good_name.gsub(/_+/,"_")
|
105
|
+
excellent_name
|
106
|
+
end
|
107
|
+
|
108
|
+
def make_pretty_file_name( ugly_name )
|
109
|
+
perfect_name = make_pretty_column_name(ugly_name)
|
110
|
+
perfect_name.chop! if perfect_name[-1,1].downcase == "s"
|
111
|
+
perfect_name.chop! if perfect_name[-1,1].downcase == "_"
|
112
|
+
perfect_name = 'quote' if perfect_name == 'quotes_original'
|
113
|
+
perfect_name = 'quote_leg' if perfect_name == 'quote_legs_original'
|
114
|
+
perfect_name
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
files = XFILE.filter(~:'xf$flags' => 16).and(:'xf$loc'.like('%.btr')).or(:'xf$loc'.like('%.BTR'))
|
120
|
+
files.each do |file|
|
121
|
+
p file[:'xf$name']
|
122
|
+
fos_class_gen = FOSClassGenerator.new(file)
|
123
|
+
fos_class_gen.write_class_file
|
124
|
+
end
|