Changeset 6772
- Timestamp:
- 02/16/07 17:29:30
- Files:
-
- trunk/README (modified) (1 diff)
- trunk/Rakefile (modified) (1 diff)
- trunk/example/Rakefile (modified) (1 diff)
- trunk/example/src/jerbil/example/EntityWithValidationErrors.java (added)
- trunk/example/src/jerbil/example/JerbilEntity.java (modified) (3 diffs)
- trunk/lib/jerbil/hibernate_task.rb (modified) (7 diffs)
- trunk/lib/jerbil/inflections.rb (added)
- trunk/lib/jerbil/inflector.rb (added)
- trunk/sql_reserved_words (added)
- trunk/sql_reserved_words/mysql5 (added)
- trunk/sql_reserved_words/oracle10g (added)
- trunk/test/test_build.rb (modified) (1 diff)
- trunk/test/test_java_helper.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/README
r6140 r6772 150 150 or implied. See the License for the specific language governing permissions and limitations under 151 151 the License. 152 153 == 3dparty code / MIT License 154 155 This product contains portions of Rails (activesupport/inflector.rb, 156 activesupport/inflections.rb) which are licensed as follows: 157 158 Copyright (c) 2004-2006 David Heinemeier Hansson 159 160 Permission is hereby granted, free of charge, to any person obtaining 161 a copy of this software and associated documentation files (the 162 "Software"), to deal in the Software without restriction, including 163 without limitation the rights to use, copy, modify, merge, publish, 164 distribute, sublicense, and/or sell copies of the Software, and to 165 permit persons to whom the Software is furnished to do so, subject to 166 the following conditions: 167 168 The above copyright notice and this permission notice shall be 169 included in all copies or substantial portions of the Software. 170 171 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 172 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 174 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 175 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 176 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 177 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Copyright (c) 2004-2006 David Heinemeier Hansson 178 trunk/Rakefile
r6138 r6772 7 7 CLEAN.include('pkg') 8 8 9 FILES = FileList['lib/**/*', 'test/*.rb', 'classloader/*', ' LICENSE', 'TODO', 'CHANGES', 'README']9 FILES = FileList['lib/**/*', 'test/*.rb', 'classloader/*', 'sql_reserved_words/*', 'LICENSE', 'TODO', 'CHANGES', 'README'] 10 10 FULLFILES = FILES.clone.include('buildsupport/**/*', 'example/**/*' ) 11 11 TESTFILES = FileList['test/test_java_helper.rb'] trunk/example/Rakefile
r6145 r6772 103 103 end 104 104 105 desc "validate schema success" 106 Jerbil::Hibernate::ExportSchemaTask.new(:validate_schema_success) do |t| 107 t.schemafile = DB_SCHEMA 108 t.entities_yml = ENTITIES_YML 109 t.validate :all 110 t.filter { |classname| classname =~ /^jerbil\.example\.JerbilEntity/ } 111 112 # not used, just for testing 113 t.inflections { |inflect| inflect.irregular( 'data' , 'data') } 114 end 115 116 desc "validate schema failure" 117 Jerbil::Hibernate::ExportSchemaTask.new(:validate_schema_failure) do |t| 118 t.schemafile = DB_SCHEMA 119 t.entities_yml = ENTITIES_YML 120 t.validate :all 121 t.filter { |classname| classname =~ /^jerbil\.example\.EntityWithValidationErrors/ } 122 end 123 105 124 Jerbil::Hibernate::ExportSchemaTask.new(:export_schema_filtered) do |t| 106 125 t.schemafile = DB_SCHEMA trunk/example/src/jerbil/example/JerbilEntity.java
r6174 r6772 3 3 import org.hibernate.annotations.Index; 4 4 5 5 6 import javax.persistence.Entity; 7 import javax.persistence.Column; 6 8 import javax.persistence.Id; 7 9 import javax.persistence.Table; … … 15 17 16 18 private Long id; 17 private String name; 19 private String name, lastName; 20 21 private boolean primary; 18 22 19 23 @Id … … 34 38 this.name = name; 35 39 } 40 41 // not activerecord conformant, but reserved 42 @Column(name = "is_primary" ) 43 public boolean isPrimary() { 44 return primary; 45 } 46 47 public void setPrimary(boolean b) { 48 primary = b; 49 } 50 51 @Column(name = "last_name") 52 public String getLastName() { 53 return lastName; 54 } 55 56 public void setLastName(String n) { 57 this.lastName = n; 58 } 36 59 } trunk/lib/jerbil/hibernate_task.rb
r6298 r6772 2 2 require 'rake/tasklib' 3 3 require 'jerbil/java_helper' 4 require 'jerbil/inflector' 4 5 require 'yaml' 5 6 require 'set' … … 11 12 # gather a list of entities which then gets serialized to a YAML file. 12 13 # ExportSchemaTask then reads this file and uses Hibernate's schema exporting 13 # features to generate SQL 14 # features to generate SQL. Optionally the schema can be validated, to check 15 # whether any column or table names are reserved keywords (validate :sql) or 16 # conform to ActiveRecord convention (validate :rails). 14 17 # 15 18 # == Example 16 19 # Jerbil::Hibernate::ExportSchemaTask.new(:export_schema) do |t| 17 20 # t.schemafile = "schema.sql" 18 # t.entities_yml = ENTITIES_YML 21 # t.entities_yml = ENTITIES_YML 22 # t.validate = :all 19 23 # end 20 24 class ExportSchemaTask < Rake::TaskLib … … 47 51 48 52 # Pretty printing of generated SQL (default: true) 49 attr_accessor :prettyprint 53 attr_accessor :prettyprint 50 54 51 55 def initialize(name=:export_schema) … … 54 58 @classfilter = nil 55 59 @prettyprint = true 60 @validate = [] 56 61 @schemafile = "schema.sql" 57 62 @entities_yml = "entities.yml" 58 63 @properties_yml = nil 59 64 @dialect = "org.hibernate.dialect.MySQL5Dialect" 65 @sql_reserved = nil 60 66 61 67 yield self if block_given? 62 68 define 63 end 69 end 64 70 65 71 def define # :nodoc: … … 77 83 78 84 cfg = get_config(entity_classes, properties, package) 85 86 validate_config(cfg) unless validate.empty? 79 87 sql = cfg.generateSchemaCreationScript(Rjb::import(dialect).new) 80 88 … … 104 112 def filter(*args, &block) 105 113 @classfilter = block 114 end 115 116 # Validate configuration (options: :all, :sql, :rails) 117 def validate(*what) 118 @validate.concat(what) 119 end 120 121 # Exposes the inflections instance so exceptions can be registered. 122 def inflections 123 yield Inflector::Inflections.instance if block_given? 106 124 end 107 125 … … 130 148 def format(sql) 131 149 Rjb::import('org.hibernate.pretty.DDLFormatter').new(sql).format 132 end 133 end 134 end 150 end 151 152 def reserved_words 153 if @sql_reserved.nil? 154 @sql_reserved = {} 155 Dir[File.join(File.dirname(__FILE__), "..", "..", "sql_reserved_words", "**")].each do |file| 156 @sql_reserved[File.basename(file)] = File.readlines(file).map{|s|s.chomp} 157 end 158 end 159 @sql_reserved 160 end 161 162 def check_reserved_word(word) 163 offending_dialects = [] 164 reserved_words.each do |dialect, wordlist| 165 offending_dialects << dialect.to_s if wordlist.include?(word.upcase) 166 end 167 offending_dialects 168 end 169 170 def validate?(what) 171 @validate.include?(:all) || @validate.include?(what) 172 end 173 174 def validate_config(cfg) 175 cfg.buildMappings 176 class_mappings = cfg.getClassMappings 177 178 invalid_tables = [] 179 invalid_columns = [] 180 invalid_words = [] 181 182 while class_mappings.hasNext 183 cmap = class_mappings.next 184 185 simple_name = cmap.getMappedClass.getSimpleName 186 table_name = cmap.getTable.getName 187 188 #only check table semantics for toplevel classes 189 if cmap.getRootClass.equals(cmap) 190 if validate?(:sql) 191 dialect_probs = check_reserved_word(table_name) 192 unless dialect_probs.empty? 193 $stderr << "[#{simple_name}] table name '#{table_name}' is a reserved keyword in dialects: #{dialect_probs.join(', ')}\n" if verbose 194 invalid_words << table_name 195 end 196 end 197 198 if validate?(:rails) 199 expected_table_name = Inflector::tableize(simple_name).sub(/^hibernate_/, '') 200 if expected_table_name != table_name && check_reserved_word(expected_table_name).empty? 201 $stderr << "[#{simple_name}] invalid table: '#{table_name}', should be '#{expected_table_name}'\n" if verbose 202 invalid_tables << table_name 203 end 204 end 205 end 206 207 # column checks 208 property_it = cmap.getPropertyIterator 209 while property_it.hasNext 210 prop = property_it.next 211 prop_name = prop.getName 212 213 column_it = prop.getColumnIterator 214 next unless column_it.hasNext 215 216 col_name = column_it.next.getName 217 218 if validate?(:sql) 219 dialect_probs = check_reserved_word(col_name) 220 unless dialect_probs.empty? 221 $stderr << "[#{simple_name}] column name '#{col_name}' in '#{table_name}' is a reserved keyword in dialects: #{dialect_probs.join(', ')}\n" if verbose 222 invalid_words << col_name 223 end 224 end 225 226 #ignore association types for now (TODO) 227 next if prop.getType.isAssociationType 228 229 if validate?(:rails) 230 expected_col_name = Inflector::underscore(prop_name) 231 232 if expected_col_name != col_name && check_reserved_word(expected_col_name).empty? 233 $stderr << "[#{simple_name}] invalid column: '#{table_name}.#{col_name}', should be '#{expected_col_name}'\n" if verbose 234 invalid_columns << col_name 235 end 236 end 237 end 238 end 239 240 raise "ExportSchemaTask: validation errors, not exporting" if !invalid_tables.empty? || !invalid_columns.empty? || !invalid_words.empty? 241 end #validate config 242 243 end #export schema task 244 end # Hibernate 135 245 end 136 246 trunk/test/test_build.rb
r6145 r6772 89 89 end 90 90 91 def test_validate_schema_success 92 run_rake_clean(:validate_schema_success) do |ok,res| 93 assert ok 94 assert File.exists?(DB_SCHEMA) 95 #make sure file is not empty 96 assert File.size(DB_SCHEMA) >= 200 97 end 98 end 99 100 def test_validate_schema_failure 101 run_rake_clean(:validate_schema_failure) do |ok,res| 102 assert !ok 103 end 104 end 105 91 106 92 107 def test_run_no_fork trunk/test/test_java_helper.rb
r6133 r6772 44 44 45 45 classnames = flist.to_classnames 46 assert_equal 5, classnames.length, classnames46 assert_equal 6, classnames.length, classnames 47 47 assert_equal 1, flist.resources.length, flist.resources 48 48
