dm-metamapper 0.0.3 → 0.0.4

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/.autospec ADDED
@@ -0,0 +1,6 @@
1
+ Autotest.add_hook :reset do |at|
2
+ at.clear_mappings
3
+ at.add_exception(/\.git/)
4
+ at.add_mapping(%r{^spec/.*_spec}) {|name,_| at.files_matching(/#{name}/)}
5
+ at.add_mapping(//) {|_,_| at.files_matching %r{spec/.*_spec}}
6
+ end
data/.gitignore CHANGED
@@ -3,3 +3,5 @@
3
3
  .bundle/*
4
4
  .rvmrc
5
5
  *.gem
6
+ *.gemspec
7
+ output
data/Gemfile CHANGED
@@ -10,6 +10,7 @@ group :test do
10
10
  gem "data_objects"
11
11
  gem "do_sqlite3", do_gems_version
12
12
  gem "do_mysql", do_gems_version
13
+ gem "ZenTest"
13
14
  end
14
15
 
15
16
  group :deploy do
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.0.4
data/example/Makefile CHANGED
@@ -1,4 +1,4 @@
1
1
  all:
2
2
  echo "generating code"
3
- cd ..; bundle exec ruby -r example/example.rb -e "DataMapper::MetaMapper.generate(:cpp)"
3
+ cd ..; bundle exec ruby -r example/example.rb -e "DataMapper::MetaMapper.generate(:cpp, :output_dir => './output')"
4
4
  g++ ../output/dmmm_utils.cpp ../output/dmmm_dbface.cpp example.cpp -I ../output -I /usr/include/mysql -I /usr/local/include/mysql++ -I /usr/local/mysql/include/mysql -lmysqlpp -lmysqlclient /usr/lib/libboost_thread-mt.so -L/usr/lib -L/usr/local/lib -Wall -o example
data/example/example.rb CHANGED
@@ -4,6 +4,7 @@ require "bundler"
4
4
  Bundler.setup(:default, :test)
5
5
  require "dm-core"
6
6
  require "lib/dm-metamapper.rb"
7
+ require "dm-metamapper/generators/cpp"
7
8
 
8
9
  #DataMapper.setup(:default, "sqlite3::memory:")
9
10
  DataMapper.setup(:default, "mysql://root@localhost/dmmm")
@@ -12,8 +13,6 @@ class User
12
13
  include DataMapper::Resource
13
14
  extend DataMapper::MetaMapper::Extension
14
15
 
15
- generates :cpp
16
-
17
16
  has n, :dogs
18
17
 
19
18
  property :id, Serial
@@ -26,8 +25,6 @@ class Dog
26
25
  include DataMapper::Resource
27
26
  extend DataMapper::MetaMapper::Extension
28
27
 
29
- generates :cpp
30
-
31
28
  belongs_to :user
32
29
  has n, :little_fleas
33
30
 
@@ -41,8 +38,6 @@ class LittleFlea
41
38
  include DataMapper::Resource
42
39
  extend DataMapper::MetaMapper::Extension
43
40
 
44
- generates :cpp
45
-
46
41
  belongs_to :dog
47
42
 
48
43
  property :id, Serial
@@ -0,0 +1,21 @@
1
+ module DataMapper
2
+ module MetaMapper
3
+ class Config < Hash
4
+ def initialize
5
+ super
6
+ self.merge! DataMapper::MetaMapper._default_opts
7
+ end
8
+
9
+ alias_method :use, :merge!
10
+
11
+ def method_missing(meth, *args)
12
+ if keys.include?(meth.to_sym)
13
+ self[meth.to_sym]
14
+ else
15
+ raise NoMethodError, "undefined method `#{meth}' for #{self.class}:#{self.class.class}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -1,12 +1,14 @@
1
1
  module DataMapper
2
2
  module MetaMapper
3
3
  module Extension
4
- def generates(*layouts)
5
- @_generation_formats = Array(layouts)
4
+ def doesnt_generate(*layouts)
5
+ @_skipped_generation_formats = Array(layouts)
6
6
  end
7
+ alias_method :dont_generate, :doesnt_generate
8
+ alias_method :skip_generation, :doesnt_generate
7
9
 
8
10
  def generates?(format)
9
- @_generation_formats.include?(format)
11
+ !@_skipped_generation_formats.include?(format)
10
12
  end
11
13
 
12
14
  def generate(format)
@@ -19,16 +21,11 @@ module DataMapper
19
21
  }
20
22
  end
21
23
 
22
- def _get_binding
23
- binding
24
- end
25
-
26
24
  def self.extended(base)
27
25
  DataMapper::MetaMapper.register(base)
28
- base.instance_variable_set(:@_generation_formats, [])
29
- class <<base; attr_reader :_generation_formats end
26
+ base.instance_variable_set(:@_skipped_generation_formats, [])
27
+ class <<base; attr_reader :_skipped_generation_formats end
30
28
  end
31
-
32
29
  end
33
30
  end
34
31
  end
@@ -1,33 +1,15 @@
1
1
  module DataMapper
2
2
  module MetaMapper
3
3
  class Generator
4
- class GeneratedFile
5
- def initialize(&blk)
6
- instance_eval(&blk) if block_given?
7
- end
8
-
9
- attr_reader :template, :file_name_prefix, :file_name_suffix
10
-
11
- def template_name(template)
12
- @template = template
13
- end
14
-
15
- def prefix(str)
16
- @file_name_prefix = str
17
- end
18
-
19
- def suffix(str)
20
- @file_name_suffix = str
21
- end
22
- end
4
+ class NoTemplateError < StandardError; end
23
5
 
24
6
  @subclasses = []
25
7
 
26
8
  class << self
27
9
  attr_reader :subclasses,
28
- :generated_model_files,
29
- :generated_global_files,
30
- :proxy_blk
10
+ :generated_files,
11
+ :config,
12
+ :setup_model_blk
31
13
 
32
14
  def [](generator)
33
15
  @subclasses.find {|klass| klass.generator_name == generator}
@@ -38,77 +20,72 @@ module DataMapper
38
20
  @generator_name = name
39
21
  end
40
22
 
41
- private
42
-
43
- def generates_file(&blk)
44
- @generated_model_files ||= []
45
- @generated_model_files << GeneratedFile.new(&blk)
23
+ def run(model, opts)
24
+ @model = model
25
+ @config.use :output_dir => opts[:output_dir] if opts[:output_dir]
26
+ new(model).run
46
27
  end
47
28
 
48
- def generates_global_file(&blk)
49
- @generated_global_files ||= []
50
- @generated_global_files << GeneratedFile.new(&blk)
29
+ private
30
+
31
+ def generates_file(type, name, opts={})
32
+ opts.merge! :type => type, :generator => self
33
+ @generated_files << Template.new(name, opts)
51
34
  end
52
35
 
53
- def proxy(&blk)
54
- @proxy_blk = blk
36
+ def setup_model(&blk)
37
+ @setup_model_blk = blk
55
38
  end
56
39
 
57
40
  def inherited(klass)
58
41
  @subclasses ||= []
59
42
  @subclasses << klass
60
- klass.instance_variable_set(:@generator_name, @generator_name)
43
+ klass.instance_variable_set(:@generator_name, klass.name.split("::").last.snake_case.to_sym)
44
+ klass.instance_variable_set(:@setup_model_blk, Proc.new{})
45
+ klass.instance_variable_set(:@config, Config.new)
46
+ klass.instance_variable_set(:@generated_files, TemplateCollection.new)
61
47
  end
62
48
  end
63
- end
64
- end
65
- end
66
49
 
67
- class DataMapper::MetaMapper::Proxy; end
68
-
69
- class CPPGenerator < DataMapper::MetaMapper::Generator
70
- generator_name :cpp
71
-
72
- generates_global_file{ template_name "dmmm_identifiers.hpp.erb" }
73
- generates_global_file{ template_name "dmmm_comparators.hpp.erb" }
74
- generates_global_file{ template_name "dmmm_fields.hpp.erb" }
75
- generates_global_file{ template_name "dmmm_utils.hpp.erb" }
76
- generates_global_file{ template_name "dmmm_utils.cpp.erb" }
77
- generates_global_file{ template_name "dmmm_dbface.cpp.erb" }
78
- generates_global_file{ template_name "dmmm_dbface.h.erb" }
79
- generates_global_file{ template_name "dmmm_id.hpp.erb" }
80
-
81
- proxy do
82
- puts "Generating files for model " + self.name.to_s
83
- key_to_parent = {}
84
- relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r|
85
- key_to_parent[r[1].child_key.first.name.to_s] = r[1].parent_model_name.to_const_string.sub(/::/,'_')
86
- puts "#{r[1].child_key.first.name.to_s} -> #{key_to_parent[r[1].child_key.first.name.to_s]}"
87
- end
50
+ # model can be nil or DataMapper::Model
51
+ def initialize(model)
52
+ @model = model
88
53
 
89
- properties.each do |e|
90
- cpp_name = if e.serial?
91
- "Field<I_#{e.model.name.sub(/::/,'_')}>"
92
- elsif !key_to_parent[e.name.to_s].nil?
93
- "Field<I_#{key_to_parent[e.name.to_s]}>"
94
- else
95
- "F_#{e.primitive}"
54
+ instance_eval(&self.class.setup_model_blk) if model
55
+
56
+ @templates = if model
57
+ self.class.generated_files.models
58
+ else
59
+ self.class.generated_files.global
60
+ end
96
61
  end
97
62
 
98
- e.instance_variable_set(:@cpp_name, cpp_name)
99
- end
100
- end
63
+ attr_reader :model
101
64
 
102
- generates_file do
103
- suffix ".hpp"
104
- prefix "O_"
105
- template_name "instance.hpp.erb"
106
- end
65
+ def run
66
+ @templates.each {|template| generate template }
67
+ end
68
+
69
+ private
70
+
71
+ def models
72
+ DataMapper::MetaMapper.models
73
+ end
74
+
75
+ def generate(template)
76
+ if !File.exists? template.full_path
77
+ raise NoTemplateError, "Template does not exist at path #{template.full_path}"
78
+ end
79
+
80
+ compiled = ERB.new(File.read(template.full_path)).result(binding)
81
+ path = respond_to?(:output_path) ? output_path(model, template) : template.output_name
82
+ if !File.exists?(path) || File.read(path) != compiled
83
+ File.open(path, 'w') {|f| f << compiled}
84
+ end
85
+
86
+ end
87
+ end
107
88
 
108
- generates_file do
109
- suffix".hpp"
110
- prefix "T_"
111
- template_name "class.hpp.erb"
112
89
  end
113
90
  end
114
91
 
@@ -0,0 +1,68 @@
1
+ module DataMapper
2
+ module MetaMapper
3
+ module Generators
4
+ class CPP < DataMapper::MetaMapper::Generator
5
+ config[:template_dir] = File.expand_path('../../../templates/cpp', __FILE__)
6
+
7
+ generates_file :global, "dmmm_identifiers.hpp"
8
+ generates_file :global, "dmmm_comparators.hpp"
9
+ generates_file :global, "dmmm_fields.hpp"
10
+ generates_file :global, "dmmm_utils.hpp"
11
+ generates_file :global, "dmmm_utils.cpp"
12
+ generates_file :global, "dmmm_dbface.cpp"
13
+ generates_file :global, "dmmm_dbface.h"
14
+ generates_file :global, "dmmm_id.hpp"
15
+
16
+ generates_file :model, "O_%model%.hpp", :template => "instance.hpp"
17
+ generates_file :model, "T_%model%.hpp", :template => "class.hpp"
18
+
19
+ setup_model do
20
+ key_to_parent = many_to_one.inject({}) do |hash, (r,m)|
21
+ hash[m.child_key.first.name] = decolonize(m.parent_model_name.to_const_string)
22
+ hash
23
+ end
24
+ model.properties.each do |prop|
25
+ cpp_name = if prop.serial?
26
+ "Field<I_#{decolonize(model.name)}>"
27
+ elsif key_to_parent[prop.name]
28
+ "Field<I_#{key_to_parent[prop.name]}>"
29
+ else
30
+ "F_#{decolonize(prop.primitive.to_s)}"
31
+ end
32
+
33
+ (class << prop; self; end).instance_eval{ attr_accessor :cpp_name }
34
+ prop.cpp_name = cpp_name
35
+ end
36
+ end
37
+
38
+ def output_path(model, template)
39
+ name = model ? template.name.sub("%model%", decolonize(model.name)) : template.name
40
+ File.join(self.class.config.output_dir, name)
41
+ end
42
+
43
+ private
44
+
45
+ def decolonize(str)
46
+ str.sub(/::/,'_')
47
+ end
48
+
49
+ def many_to_one
50
+ return unless model
51
+ @many_to_one ||= model.relationships.select {|r,m|
52
+ m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'
53
+ }
54
+ #in case of ruby < 1.9
55
+ if Array === @many_to_one
56
+ temp = @many_to_one
57
+ @many_to_one = {}
58
+ temp.each{|t| @many_to_one[t[0]] = t[1]}
59
+ end
60
+
61
+ @many_to_one
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+
@@ -1,59 +1,31 @@
1
1
  module DataMapper
2
2
  module MetaMapper
3
+ @_default_opts = {
4
+ :template_dir => Dir.pwd,
5
+ :output_dir => Dir.pwd
6
+ }
7
+
3
8
  class << self
4
- attr_reader :models
9
+ attr_reader :models, :_default_opts
10
+
11
+ def use(opts)
12
+ @_default_opts.merge! opts
13
+ end
5
14
 
6
15
  def register(klass)
7
16
  @models ||= []
8
17
  @models << klass unless models.member?(klass)
9
18
  end
10
19
 
11
- def generate(format, context=nil)
20
+ def generate(format, opts = {})
21
+ context = opts.delete(:context)
12
22
  generator = Generator[format]
23
+ generator.run(context, opts)
13
24
 
14
- if context
15
- context.instance_eval(&generator.proxy_blk) if generator.proxy_blk
16
- type, _binding = :generated_model_files, context._get_binding
17
- else
18
- type, _binding = :generated_global_files, binding
19
- end
20
-
21
- generator.send(type).each do |generated_file|
22
- temp_filename = [
23
- File.dirname(__FILE__),
24
- "../templates",
25
- generator.generator_name,
26
- generated_file.template
27
- ].join('/')
28
-
29
- result_base_name = context ? context.name.to_s.sub(/::/,'_') : generated_file.template.sub(/\.erb$/,'')
30
-
31
- result_filename = File.join(
32
- File.dirname(__FILE__), "../../output", [
33
- generated_file.file_name_prefix,
34
- result_base_name,
35
- generated_file.file_name_suffix
36
- ].join
37
- )
38
-
39
- if File.exists?(temp_filename)
40
- STDOUT.puts "writing file " + result_filename
41
- template = ERB.new(File.read(temp_filename))
42
- result = template.result(_binding)
43
- File.open(result_filename, 'w') { |f| f << result }
44
- else
45
- STDERR.puts "ERROR: " + temp_filename + " does not exist"
46
- end
47
- end
48
-
49
- if !context
50
- models.select {|model|
51
- model.generates?(format)
52
- }.each {|model|
53
- model.generate(format)
54
- }
55
- end
56
-
25
+ models.each {|model|
26
+ opts[:context] = model
27
+ generate(format, opts)
28
+ } if !context
57
29
  end
58
30
  end
59
31
  end
@@ -0,0 +1,53 @@
1
+ module DataMapper
2
+ module MetaMapper
3
+ class NoGeneratorError < ArgumentError; end
4
+ class InvalidTypeError < StandardError; end
5
+
6
+ class TemplateCollection < Array
7
+ def models
8
+ self.select {|t| t.type == :model}
9
+ end
10
+
11
+ def global
12
+ self.select {|t| t.type == :global}
13
+ end
14
+ end
15
+
16
+ class Template
17
+ VALID_TYPES = [:global, :model]
18
+
19
+ def initialize(name, opts={})
20
+ @name = name.to_s
21
+ @generator = parse_generator(opts.delete(:generator))
22
+ @type = parse_type(opts.delete(:type))
23
+ @template = (opts.delete(:template) || @name).to_s + ".erb"
24
+ end
25
+
26
+ attr_reader :name, :type
27
+
28
+ def output_path
29
+ File.join(@generator.config.output_dir, @name)
30
+ end
31
+
32
+ def full_path
33
+ File.join(@generator.config.template_dir, @template)
34
+ end
35
+
36
+ private
37
+
38
+ def parse_type(type)
39
+ unless type && VALID_TYPES.include?(type.to_sym)
40
+ raise InvalidTypeError, "type `#{type}' is not a recognized template " +
41
+ "type. Valid types: #{VALID_TYPES.inspect}]"
42
+ end
43
+
44
+ type
45
+ end
46
+
47
+ def parse_generator(generator)
48
+ generator || raise(NoGeneratorError, "opts did not contain :generator")
49
+ end
50
+ end
51
+ end
52
+ end
53
+
data/lib/dm-metamapper.rb CHANGED
@@ -2,7 +2,9 @@ $:.push File.dirname(__FILE__)
2
2
 
3
3
  require 'dm-core'
4
4
  require 'dm-metamapper/property'
5
+ require 'dm-metamapper/config'
5
6
  require 'dm-metamapper/metamapper'
6
7
  require 'dm-metamapper/extension'
8
+ require 'dm-metamapper/template'
7
9
  require 'dm-metamapper/generator'
8
10
 
@@ -1,4 +1,4 @@
1
- <% class_name = self.name.sub(/::/,'_') %>
1
+ <% class_name = decolonize(model.name) %>
2
2
  <% all_caps_name = class_name.upcase %>
3
3
  #ifndef T_<%= all_caps_name %>
4
4
  #define T_<%= all_caps_name %>
@@ -15,49 +15,47 @@ public:
15
15
 
16
16
  T_<%= class_name %>()
17
17
  {
18
- _tables.push_back("<%= storage_name %>");
18
+ _tables.push_back("<%= model.storage_name %>");
19
19
  }
20
20
  T_<%= class_name %>(const Condition& c)
21
21
  : _constraint(c)
22
22
  {
23
- _tables.push_back("<%= storage_name %>");
23
+ _tables.push_back("<%= model.storage_name %>");
24
24
  }
25
- <% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
26
- <% parent = r[1].parent_model_name.sub(/::/,'_') %>
25
+ <% many_to_one.each do |r| %>
26
+ <% parent = decolonize(r[1].parent_model_name) %>
27
27
  T_<%= class_name %>(const T_<%= parent %>& parent)
28
28
  {
29
- _tables.push_back("<%= storage_name %>");
29
+ _tables.push_back("<%= model.storage_name %>");
30
30
  _tables.insert(_tables.end(),
31
31
  parent._tables.begin(), parent._tables.end());
32
32
 
33
- _constraint._cond = "(<%= storage_name + "." + r[1].child_key.first.name.to_s %> = " + parent._tables[0] + ".<%= r[1].parent_key.first.name.to_s %>)";
33
+ _constraint._cond = "(<%= model.storage_name + "." + r[1].child_key.first.name.to_s %> = " + parent._tables[0] + ".<%= r[1].parent_key.first.name.to_s %>)";
34
34
  if (!parent._constraint.nil())
35
35
  _constraint._cond += " AND " + parent._constraint._cond;
36
36
  }
37
-
38
37
  <% end %>
39
38
 
40
- <% generated_properties.each do |property| %>
39
+ <% model.generated_properties.each do |property| %>
41
40
  struct E_<%= property.name %>{
42
41
  E_<%= property.name %>()
43
42
  {
44
- _field = "<%= storage_name %>.<%= property.name.to_s %>";
43
+ _field = "<%= model.storage_name %>.<%= property.name.to_s %>";
45
44
  }
46
45
  std::string _field;
47
46
  typedef T_<%= class_name %>::Condition ConditionType;
48
- typedef <%= property.instance_variable_get(:@cpp_name) %>::Base ComparerType;
47
+ typedef <%= property.cpp_name %>::Base ComparerType;
49
48
  };
50
49
 
51
50
  E_<%= property.name %> _<%= property.name %>(){
52
51
  return E_<%= property.name %>();
53
52
  }
54
-
55
53
  <% end %>
56
54
 
57
55
  void getFields(std::vector<std::string>& rFields)
58
56
  {
59
57
  rFields.clear();
60
- <% generated_properties.each do |property| %>
58
+ <% model.generated_properties.each do |property| %>
61
59
  rFields.push_back("<%= property.name %>");
62
60
  <% end %>
63
61
  }
@@ -74,9 +72,9 @@ public:
74
72
  additional, res);
75
73
  r.resize(res.size());
76
74
  for(size_t i = 0; i < res.size(); ++i){
77
- <% generated_properties.each do |property| %>
75
+ <% model.generated_properties.each do |property| %>
78
76
  r[i]._f_<%= property.name %>._base =
79
- UTILS::fromString<<%= property.instance_variable_get(:@cpp_name) %>::Base>(res[i]["<%= property.name %>"]);
77
+ UTILS::fromString<<%= property.cpp_name %>::Base>(res[i]["<%= property.name %>"]);
80
78
  <% end %>
81
79
  }
82
80
  }
@@ -104,7 +102,7 @@ public:
104
102
  }
105
103
 
106
104
  std::pair<O_<%= class_name %>, bool> select(const I_<%= class_name %>& id){
107
- return first(E_<%= serial.name %>() == id);
105
+ return first(E_<%= model.serial.name %>() == id);
108
106
  }
109
107
 
110
108
  std::pair<O_<%= class_name %>, bool> first(const Condition& c)
@@ -6,7 +6,7 @@
6
6
  namespace DMMM {
7
7
 
8
8
  <% models.each do |model| %>
9
- <% model_name = model.name.sub(/::/,'_') %>
9
+ <% model_name = decolonize(model.name) %>
10
10
  class DummyO_<%= model_name %>;
11
11
  typedef UTILS::Id<DummyO_<%= model_name %>> I_<%= model_name %>;
12
12
  <% end %>
@@ -1,4 +1,4 @@
1
- <% class_name = self.name.sub(/::/,'_') %>
1
+ <% class_name = decolonize(model.name) %>
2
2
  <% all_caps_name = class_name.upcase %>
3
3
  #ifndef O_<%= all_caps_name %>
4
4
  #define O_<%= all_caps_name %>
@@ -10,8 +10,8 @@
10
10
  #include "dmmm_identifiers.hpp"
11
11
  #include "dmmm_fields.hpp"
12
12
  #include "dmmm_comparators.hpp"
13
- <% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |relative| %>
14
- #include "T_<%= relative[1].parent_model.to_s.sub(/::/,'_') %>.hpp"
13
+ <% many_to_one.each do |relative| %>
14
+ #include "T_<%= decolonize(relative[1].parent_model.to_s) %>.hpp"
15
15
  <% end %>
16
16
 
17
17
  <%# self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::OneToMany::Relationship'}.each do |relative| %>
@@ -22,8 +22,8 @@ class O_<%= class_name %>{
22
22
  public:
23
23
 
24
24
  O_<%= class_name %>() {}
25
- <% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
26
- <% parent = r[1].parent_model_name.sub(/::/,'_') %>
25
+ <% many_to_one.each do |r| %>
26
+ <% parent = decolonize(r[1].parent_model_name) %>
27
27
  O_<%= class_name %>(const O_<%= parent %>& parent)
28
28
  : _f_<%= r[1].child_key.first.name.to_s %>(parent._<%= r[1].parent_key.first.name.to_s %>())
29
29
  {}
@@ -32,53 +32,50 @@ public:
32
32
  {}
33
33
  <% end %>
34
34
 
35
- <% generated_properties.each do |property| %>
36
- const <%= property.instance_variable_get(:@cpp_name) %>::Base& _<%= property.name %>() const {
35
+ <% model.generated_properties.each do |property| %>
36
+ const <%= property.cpp_name %>::Base& _<%= property.name %>() const {
37
37
  return _f_<%= property.name %>._base;
38
38
  }
39
- <%= property.instance_variable_get(:@cpp_name) %>::Base& _<%= property.name %>() {
39
+ <%= property.cpp_name %>::Base& _<%= property.name %>() {
40
40
  _f_<%= property.name %>._dirty = true;
41
41
  return _f_<%= property.name %>._base;
42
42
  }
43
-
44
43
  <% end %>
45
44
 
46
- <% if serial %>
45
+ <% if model.serial %>
47
46
  bool update(){
48
47
  std::map<std::string, std::string> field2Val;
49
- <% generated_properties.each do |property| %>
48
+ <% model.generated_properties.each do |property| %>
50
49
  if (_f_<%= property.name %>._dirty)
51
50
  field2Val["<%= property.name %>"] =
52
51
  UTILS::toString(_f_<%= property.name %>._base);
53
52
  <% end %>
54
53
  std::string where =
55
- "<%= serial.name %>=" + UTILS::toString(_f_<%= serial.name %>._base);
56
- return DBFace::instance()->update("<%= storage_name %>",
54
+ "<%= model.serial.name %>=" + UTILS::toString(_f_<%= model.serial.name %>._base);
55
+ return DBFace::instance()->update("<%= model.storage_name %>",
57
56
  field2Val, where);
58
57
  }
59
-
60
58
  <% end %>
61
59
 
62
-
63
60
  bool insert(){
64
61
  std::map<std::string, std::string> field2Val;
65
- <% generated_properties.each do |property| %>
62
+ <% model.generated_properties.each do |property| %>
66
63
  if (_f_<%= property.name %>._dirty)
67
64
  field2Val["<%= property.name %>"] =
68
65
  UTILS::toString(_f_<%= property.name %>._base);
69
66
  <% end %>
70
- <% if serial %>
67
+ <% if model.serial %>
71
68
  if (DBFace::instance()->
72
- insert("<%= storage_name %>", field2Val,
73
- _f_<%= serial.name %>._base.serialization()))
69
+ insert("<%= model.storage_name %>", field2Val,
70
+ _f_<%= model.serial.name %>._base.serialization()))
74
71
  <% else %>
75
72
  size_t id;
76
73
  if (DBFace::instance()->
77
- insert("<%= storage_name %>", field2Val,
74
+ insert("<%= model.storage_name %>", field2Val,
78
75
  id))
79
76
  <% end %>
80
77
  {
81
- <% generated_properties.each do |property| %>
78
+ <% model.generated_properties.each do |property| %>
82
79
  _f_<%= property.name %>._dirty = false;
83
80
  <% end %>
84
81
  return true;
@@ -88,21 +85,19 @@ public:
88
85
 
89
86
  }
90
87
 
91
- <% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
92
- <% parent = r[1].parent_model_name.sub(/::/,'_') %>
88
+ <% many_to_one.each do |r| %>
89
+ <% parent = decolonize(r[1].parent_model_name) %>
93
90
  std::pair<O_<%= parent %>, bool> <%= r[0] %>(){
94
91
  T_<%= parent %> T(T_<%= parent %>::E_<%= r[1].parent_key.first.name.to_s %>() == _<%= r[1].child_key.first.name.to_s %>());
95
92
  return T.first();
96
93
  }
97
94
  <% end %>
98
95
 
99
-
100
96
  private:
101
- <% generated_properties.each do |property| %>
102
- <%= property.instance_variable_get(:@cpp_name) %> _f_<%= property.name %>;
97
+ <% model.generated_properties.each do |property| %>
98
+ <%= property.cpp_name %> _f_<%= property.name %>;
103
99
  <% end %>
104
100
 
105
-
106
101
  friend class T_<%= class_name %>;
107
102
  };
108
103
 
@@ -0,0 +1,62 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ class MyGenerator < DMMM::Generator;end
4
+
5
+ class LolModel
6
+ include DataMapper::Resource
7
+
8
+ property :id, Serial
9
+ property :name, String
10
+ end
11
+
12
+ describe "Generator" do
13
+ describe "General" do
14
+ it "is configurable" do
15
+ MyGenerator.config.should == DMMM.instance_variable_get(:@_default_opts)
16
+ end
17
+
18
+ it "stores a block to extend models" do
19
+ blk = proc { @__foo__ = "lol" }
20
+ MyGenerator.send(:setup_model, &blk)
21
+ MyGenerator.setup_model_blk.should == blk
22
+ end
23
+ end
24
+
25
+ describe "Templates" do
26
+ it "has a template store" do
27
+ DMMM::TemplateCollection.should === MyGenerator.generated_files
28
+ end
29
+
30
+ it "stores template info" do
31
+ MyGenerator.send(:generates_file, :model, "foo")
32
+ MyGenerator.generated_files.size.should == 1
33
+ MyGenerator.generated_files.first.name.should == "foo"
34
+ end
35
+ end
36
+
37
+ describe ".new" do
38
+ before :each do
39
+ MyGenerator.instance_variable_set :@generated_files, DMMM::TemplateCollection.new
40
+ model_files = ["foo", "bar", "baz", "bleh"]
41
+
42
+ model_files.each do |f|
43
+ MyGenerator.send :generates_file, :model, f
44
+ end
45
+ end
46
+
47
+ it "requires model info" do
48
+ lambda {MyGenerator.new}.should raise_error(ArgumentError)
49
+ end
50
+
51
+ it "has model templates when called with model" do
52
+ @generator = MyGenerator.new(LolModel)
53
+ @generator.instance_variable_get(:@templates).should == MyGenerator.generated_files.models
54
+ end
55
+
56
+ it "has global templates when called without model" do
57
+ @generator = MyGenerator.new nil
58
+ @generator.instance_variable_get(:@templates).should == MyGenerator.generated_files.global
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,29 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ class LolGenerator < DMMM::Generator; end
4
+
5
+ describe "Template" do
6
+ describe "invalid" do
7
+ it "requires a name" do
8
+ lambda {DMMM::Template.new}.should raise_error(ArgumentError)
9
+ end
10
+
11
+ it "requires a generator" do
12
+ lambda {DMMM::Template.new(:foo)}.should raise_error(DMMM::NoGeneratorError)
13
+ end
14
+
15
+ it "requires a valid type" do
16
+ lambda {DMMM::Template.new(:few, generator: LolGenerator)}.
17
+ should raise_error(DMMM::InvalidTypeError)
18
+ end
19
+ end
20
+
21
+ describe "valid" do
22
+ before :all do
23
+ @template = DMMM::Template.new :foo,
24
+ generator: LolGenerator,
25
+ type: :global
26
+ end
27
+ end
28
+ end
29
+
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format profile
4
+ --backtrace
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
- $:.push(File.join(File.dirname(__FILE__), "../lib"))
1
+ $:.push File.expand_path('../lib', __FILE__)
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler'
@@ -6,3 +6,5 @@ Bundler.setup(:default, :test)
6
6
  require 'spec'
7
7
 
8
8
  require 'dm-metamapper'
9
+
10
+ DMMM = DataMapper::MetaMapper
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 3
9
- version: 0.0.3
8
+ - 4
9
+ version: 0.0.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jonah Honeyman
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-09 00:00:00 +03:00
18
+ date: 2010-06-15 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -28,21 +28,24 @@ extensions: []
28
28
  extra_rdoc_files:
29
29
  - README.md
30
30
  files:
31
+ - .autospec
31
32
  - .gitignore
32
33
  - Gemfile
33
34
  - README.md
34
35
  - Rakefile
35
36
  - VERSION
36
- - dm-metamapper.gemspec
37
37
  - example/.gitignore
38
38
  - example/Makefile
39
39
  - example/example.cpp
40
40
  - example/example.rb
41
41
  - lib/dm-metamapper.rb
42
+ - lib/dm-metamapper/config.rb
42
43
  - lib/dm-metamapper/extension.rb
43
44
  - lib/dm-metamapper/generator.rb
45
+ - lib/dm-metamapper/generators/cpp.rb
44
46
  - lib/dm-metamapper/metamapper.rb
45
47
  - lib/dm-metamapper/property.rb
48
+ - lib/dm-metamapper/template.rb
46
49
  - lib/templates/cpp/class.hpp.erb
47
50
  - lib/templates/cpp/dmmm_comparators.hpp.erb
48
51
  - lib/templates/cpp/dmmm_dbface.cpp.erb
@@ -53,7 +56,9 @@ files:
53
56
  - lib/templates/cpp/dmmm_utils.cpp.erb
54
57
  - lib/templates/cpp/dmmm_utils.hpp.erb
55
58
  - lib/templates/cpp/instance.hpp.erb
56
- - output/.gitignore
59
+ - spec/dm-metamapper/generator_spec.rb
60
+ - spec/dm-metamapper/template_spec.rb
61
+ - spec/spec.opts
57
62
  - spec/spec_helper.rb
58
63
  has_rdoc: true
59
64
  homepage: http://github.com/jonuts/dm-metamapper
@@ -87,3 +92,5 @@ specification_version: 3
87
92
  summary: Code generating C++ ORM
88
93
  test_files:
89
94
  - spec/spec_helper.rb
95
+ - spec/dm-metamapper/generator_spec.rb
96
+ - spec/dm-metamapper/template_spec.rb
@@ -1,66 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{dm-metamapper}
8
- s.version = "0.0.3"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Jonah Honeyman", "Omer Tamuz"]
12
- s.date = %q{2010-06-09}
13
- s.description = %q{C++ API for databases created with DM. Hard typing, compile time checked queries.}
14
- s.email = %q{jonah@honeyman.org}
15
- s.extra_rdoc_files = [
16
- "README.md"
17
- ]
18
- s.files = [
19
- ".gitignore",
20
- "Gemfile",
21
- "README.md",
22
- "Rakefile",
23
- "VERSION",
24
- "dm-metamapper.gemspec",
25
- "example/.gitignore",
26
- "example/Makefile",
27
- "example/example.cpp",
28
- "example/example.rb",
29
- "lib/dm-metamapper.rb",
30
- "lib/dm-metamapper/extension.rb",
31
- "lib/dm-metamapper/generator.rb",
32
- "lib/dm-metamapper/metamapper.rb",
33
- "lib/dm-metamapper/property.rb",
34
- "lib/templates/cpp/class.hpp.erb",
35
- "lib/templates/cpp/dmmm_comparators.hpp.erb",
36
- "lib/templates/cpp/dmmm_dbface.cpp.erb",
37
- "lib/templates/cpp/dmmm_dbface.h.erb",
38
- "lib/templates/cpp/dmmm_fields.hpp.erb",
39
- "lib/templates/cpp/dmmm_id.hpp.erb",
40
- "lib/templates/cpp/dmmm_identifiers.hpp.erb",
41
- "lib/templates/cpp/dmmm_utils.cpp.erb",
42
- "lib/templates/cpp/dmmm_utils.hpp.erb",
43
- "lib/templates/cpp/instance.hpp.erb",
44
- "output/.gitignore",
45
- "spec/spec_helper.rb"
46
- ]
47
- s.homepage = %q{http://github.com/jonuts/dm-metamapper}
48
- s.rdoc_options = ["--charset=UTF-8"]
49
- s.require_paths = ["lib"]
50
- s.rubygems_version = %q{1.3.6}
51
- s.summary = %q{Code generating C++ ORM}
52
- s.test_files = [
53
- "spec/spec_helper.rb"
54
- ]
55
-
56
- if s.respond_to? :specification_version then
57
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
- s.specification_version = 3
59
-
60
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
- else
62
- end
63
- else
64
- end
65
- end
66
-
data/output/.gitignore DELETED
@@ -1 +0,0 @@
1
- *