dm-metamapper 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +16 -0
- data/README.md +0 -0
- data/VERSION +1 -0
- data/example/.gitignore +1 -0
- data/example/Makefile +4 -0
- data/example/example.cpp +74 -0
- data/example/example.rb +51 -0
- data/lib/dm-metamapper/extension.rb +35 -0
- data/lib/dm-metamapper/generator.rb +113 -0
- data/lib/dm-metamapper/metamapper.rb +60 -0
- data/lib/dm-metamapper/property.rb +6 -0
- data/lib/dm-metamapper.rb +8 -0
- data/lib/templates/cpp/class.hpp.erb +134 -0
- data/lib/templates/cpp/dmmm_comparators.hpp.erb +74 -0
- data/lib/templates/cpp/dmmm_dbface.cpp.erb +176 -0
- data/lib/templates/cpp/dmmm_dbface.h.erb +47 -0
- data/lib/templates/cpp/dmmm_fields.hpp.erb +28 -0
- data/lib/templates/cpp/dmmm_id.hpp.erb +78 -0
- data/lib/templates/cpp/dmmm_identifiers.hpp.erb +15 -0
- data/lib/templates/cpp/dmmm_utils.cpp.erb +11 -0
- data/lib/templates/cpp/dmmm_utils.hpp.erb +40 -0
- data/lib/templates/cpp/instance.hpp.erb +102 -0
- data/output/.gitignore +1 -0
- data/spec/spec_helper.rb +8 -0
- metadata +87 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem "dm-core", :git => "git://github.com/datamapper/dm-core"
|
4
|
+
|
5
|
+
group :test do
|
6
|
+
gem "rspec"
|
7
|
+
gem "dm-sqlite-adapter", :git => "git://github.com/datamapper/dm-sqlite-adapter"
|
8
|
+
gem "dm-mysql-adapter", :git => "git://github.com/datamapper/dm-mysql-adapter"
|
9
|
+
gem "dm-migrations", :git => "git://github.com/datamapper/dm-migrations"
|
10
|
+
end
|
11
|
+
|
12
|
+
group :deploy do
|
13
|
+
gem "jeweler"
|
14
|
+
end
|
15
|
+
|
16
|
+
# vim: set ft=ruby:
|
data/README.md
ADDED
File without changes
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/example/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
example
|
data/example/Makefile
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
all:
|
2
|
+
echo "generating code"
|
3
|
+
cd ..; bundle exec ruby -r example/example.rb -e "DataMapper::MetaMapper.generate(:cpp)"
|
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.cpp
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#include <vector>
|
2
|
+
#include "dmmm_dbface.h"
|
3
|
+
#include "T_User.hpp"
|
4
|
+
#include "T_Dog.hpp"
|
5
|
+
#include "T_LittleFlea.hpp"
|
6
|
+
|
7
|
+
using namespace std;
|
8
|
+
using namespace DMMM;
|
9
|
+
|
10
|
+
int main(int argc, char* argv[])
|
11
|
+
{
|
12
|
+
string host("localhost");
|
13
|
+
string user("root");
|
14
|
+
string database("dmmm");
|
15
|
+
string password("");
|
16
|
+
DBFace dbFace(database, host, user, password);
|
17
|
+
|
18
|
+
T_Dog d;
|
19
|
+
T_User u;
|
20
|
+
d.erase();
|
21
|
+
u.erase();
|
22
|
+
|
23
|
+
O_User u1;
|
24
|
+
u1._name() = "omer";
|
25
|
+
u1._balance() = 5.3;
|
26
|
+
u1._weight() = 10;
|
27
|
+
u1.insert();
|
28
|
+
|
29
|
+
O_Dog d1;
|
30
|
+
d1._user_id() = u1._id();
|
31
|
+
d1._name() = "spot";
|
32
|
+
d1._stinks() = true;
|
33
|
+
d1.insert();
|
34
|
+
|
35
|
+
d1 = d.select(d1._id()).first;
|
36
|
+
|
37
|
+
O_Dog d2(u1);
|
38
|
+
d2._name() = "rover";
|
39
|
+
d2._stinks() = false;
|
40
|
+
d2.insert();
|
41
|
+
|
42
|
+
O_User u2;
|
43
|
+
u2._name() = "jonah";
|
44
|
+
u2.insert();
|
45
|
+
|
46
|
+
O_Dog d3(u2._id());
|
47
|
+
d3._name() = "rover";
|
48
|
+
d3._stinks() = false;
|
49
|
+
d3.insert();
|
50
|
+
|
51
|
+
O_LittleFlea f1(d3);
|
52
|
+
f1.insert();
|
53
|
+
|
54
|
+
vector<O_Dog> dogs;
|
55
|
+
d.select((d._stinks() == false) && (d._name() %= "\%over"), dogs);
|
56
|
+
for(size_t i = 0; i < dogs.size(); ++i){
|
57
|
+
dogs[i]._name() = string("good_") + dogs[i]._name();
|
58
|
+
dogs[i].update();
|
59
|
+
cout << dogs[i]._name()
|
60
|
+
<< " belongs to " << dogs[i].user().first._name()
|
61
|
+
<< endl;
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
T_Dog dconst(T_User(u._name() == "omer"));
|
66
|
+
dogs.clear();
|
67
|
+
dconst.select(d._stinks() == true, dogs);
|
68
|
+
cout << dogs.size() << " dogs meet criterion" << endl;
|
69
|
+
dconst.erase();
|
70
|
+
|
71
|
+
d.erase(d._user_id() == u2._id());
|
72
|
+
|
73
|
+
return 0;
|
74
|
+
}
|
data/example/example.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler"
|
4
|
+
Bundler.setup(:default, :test)
|
5
|
+
require "dm-core"
|
6
|
+
require "lib/dm-metamapper.rb"
|
7
|
+
require "dm-migrations"
|
8
|
+
|
9
|
+
#DataMapper.setup(:default, "sqlite3::memory:")
|
10
|
+
DataMapper.setup(:default, "mysql://root@localhost/dmmm")
|
11
|
+
|
12
|
+
class User
|
13
|
+
include DataMapper::Resource
|
14
|
+
extend DataMapper::MetaMapper::Extension
|
15
|
+
|
16
|
+
generates :cpp
|
17
|
+
|
18
|
+
has n, :dogs
|
19
|
+
|
20
|
+
property :id, Serial
|
21
|
+
property :name, String
|
22
|
+
property :balance, Float
|
23
|
+
property :weight, Integer
|
24
|
+
end
|
25
|
+
|
26
|
+
class Dog
|
27
|
+
include DataMapper::Resource
|
28
|
+
extend DataMapper::MetaMapper::Extension
|
29
|
+
|
30
|
+
generates :cpp
|
31
|
+
|
32
|
+
belongs_to :user
|
33
|
+
has n, :little_fleas
|
34
|
+
|
35
|
+
property :id, Serial
|
36
|
+
property :user_id, Integer
|
37
|
+
property :name, String
|
38
|
+
property :stinks, Boolean
|
39
|
+
end
|
40
|
+
|
41
|
+
class LittleFlea
|
42
|
+
include DataMapper::Resource
|
43
|
+
extend DataMapper::MetaMapper::Extension
|
44
|
+
|
45
|
+
generates :cpp
|
46
|
+
|
47
|
+
belongs_to :dog
|
48
|
+
|
49
|
+
property :id, Serial
|
50
|
+
property :dog_id, Integer
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module MetaMapper
|
3
|
+
module Extension
|
4
|
+
def generates(*layouts)
|
5
|
+
@_generation_formats = Array(layouts)
|
6
|
+
end
|
7
|
+
|
8
|
+
def generates?(format)
|
9
|
+
@_generation_formats.include?(format)
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate(format)
|
13
|
+
DataMapper::MetaMapper.generate(format, self)
|
14
|
+
end
|
15
|
+
|
16
|
+
def generated_properties
|
17
|
+
@_generated_properties ||= properties.select {|prop|
|
18
|
+
!prop.options[:skip_generation]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def _get_binding
|
23
|
+
binding
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.extended(base)
|
27
|
+
DataMapper::MetaMapper.register(base)
|
28
|
+
base.instance_variable_set(:@_generation_formats, [])
|
29
|
+
class <<base; attr_reader :_generation_formats end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module MetaMapper
|
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
|
23
|
+
|
24
|
+
@subclasses = []
|
25
|
+
|
26
|
+
class << self
|
27
|
+
attr_reader :subclasses,
|
28
|
+
:generated_model_files,
|
29
|
+
:generated_global_files,
|
30
|
+
:proxy_blk
|
31
|
+
|
32
|
+
def [](generator)
|
33
|
+
@subclasses.find {|klass| klass.generator_name == generator}
|
34
|
+
end
|
35
|
+
|
36
|
+
def generator_name(name=nil)
|
37
|
+
return @generator_name unless name
|
38
|
+
@generator_name = name
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def generates_file(&blk)
|
44
|
+
@generated_model_files ||= []
|
45
|
+
@generated_model_files << GeneratedFile.new(&blk)
|
46
|
+
end
|
47
|
+
|
48
|
+
def generates_global_file(&blk)
|
49
|
+
@generated_global_files ||= []
|
50
|
+
@generated_global_files << GeneratedFile.new(&blk)
|
51
|
+
end
|
52
|
+
|
53
|
+
def proxy(&blk)
|
54
|
+
@proxy_blk = blk
|
55
|
+
end
|
56
|
+
|
57
|
+
def inherited(klass)
|
58
|
+
@subclasses ||= []
|
59
|
+
@subclasses << klass
|
60
|
+
klass.instance_variable_set(:@generator_name, @generator_name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
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
|
+
key_to_parent = {}
|
83
|
+
relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r|
|
84
|
+
key_to_parent[r[1].child_key.first.name.to_s] = r[0].to_const_string
|
85
|
+
puts "#{r[1].child_key.first.name.to_s} -> #{r[0].to_const_string}"
|
86
|
+
end
|
87
|
+
|
88
|
+
properties.each do |e|
|
89
|
+
cpp_name = if e.serial?
|
90
|
+
"Field<I_#{e.model.name}>"
|
91
|
+
elsif !key_to_parent[e.name.to_s].nil?
|
92
|
+
"Field<I_#{key_to_parent[e.name.to_s]}>"
|
93
|
+
else
|
94
|
+
"F_#{e.class.primitive}"
|
95
|
+
end
|
96
|
+
|
97
|
+
e.instance_variable_set(:@cpp_name, cpp_name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
generates_file do
|
102
|
+
suffix ".hpp"
|
103
|
+
prefix "O_"
|
104
|
+
template_name "instance.hpp.erb"
|
105
|
+
end
|
106
|
+
|
107
|
+
generates_file do
|
108
|
+
suffix".hpp"
|
109
|
+
prefix "T_"
|
110
|
+
template_name "class.hpp.erb"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module MetaMapper
|
3
|
+
class << self
|
4
|
+
attr_reader :models
|
5
|
+
|
6
|
+
def register(klass)
|
7
|
+
(@models ||= []) << klass
|
8
|
+
end
|
9
|
+
|
10
|
+
def generate(format, context=nil)
|
11
|
+
generator = Generator[format]
|
12
|
+
|
13
|
+
if context
|
14
|
+
context.instance_eval(&generator.proxy_blk) if generator.proxy_blk
|
15
|
+
type, _binding = :generated_model_files, context._get_binding
|
16
|
+
else
|
17
|
+
type, _binding = :generated_global_files, binding
|
18
|
+
end
|
19
|
+
|
20
|
+
generator.send(type).each do |generated_file|
|
21
|
+
temp_filename = [
|
22
|
+
File.dirname(__FILE__),
|
23
|
+
"../templates",
|
24
|
+
generator.generator_name,
|
25
|
+
generated_file.template
|
26
|
+
].join('/')
|
27
|
+
|
28
|
+
result_base_name = context ? context.name.to_s : generated_file.template.sub(/\.erb$/,'')
|
29
|
+
|
30
|
+
result_filename = File.join(
|
31
|
+
File.dirname(__FILE__), "../../output", [
|
32
|
+
generated_file.file_name_prefix,
|
33
|
+
result_base_name,
|
34
|
+
generated_file.file_name_suffix
|
35
|
+
].join
|
36
|
+
)
|
37
|
+
|
38
|
+
if File.exists?(temp_filename)
|
39
|
+
STDOUT.puts "writing file " + result_filename
|
40
|
+
template = ERB.new(File.read(temp_filename))
|
41
|
+
result = template.result(_binding)
|
42
|
+
File.open(result_filename, 'w') { |f| f << result }
|
43
|
+
else
|
44
|
+
STDERR.puts "ERROR: " + temp_filename + " does not exist"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if !context
|
49
|
+
models.select {|model|
|
50
|
+
model.generates?(format)
|
51
|
+
}.each {|model|
|
52
|
+
model.generate(format)
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
<% class_name = self.name %>
|
2
|
+
<% all_caps_name = class_name.upcase %>
|
3
|
+
#ifndef T_<%= all_caps_name %>
|
4
|
+
#define T_<%= all_caps_name %>
|
5
|
+
#include "O_<%= class_name %>.hpp"
|
6
|
+
namespace DMMM {
|
7
|
+
|
8
|
+
class T_<%= class_name %>{
|
9
|
+
public:
|
10
|
+
|
11
|
+
struct Condition{
|
12
|
+
bool nil() const { return _cond.size() == 0; }
|
13
|
+
std::string _cond;
|
14
|
+
};
|
15
|
+
|
16
|
+
T_<%= class_name %>()
|
17
|
+
{
|
18
|
+
_tables.push_back("<%= storage_name %>");
|
19
|
+
}
|
20
|
+
T_<%= class_name %>(const Condition& c)
|
21
|
+
: _constraint(c)
|
22
|
+
{
|
23
|
+
_tables.push_back("<%= storage_name %>");
|
24
|
+
}
|
25
|
+
<% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
|
26
|
+
<% parent = r[0].to_const_string %>
|
27
|
+
T_<%= class_name %>(const T_<%= parent %>& parent)
|
28
|
+
{
|
29
|
+
_tables.push_back("<%= storage_name %>");
|
30
|
+
_tables.insert(_tables.end(),
|
31
|
+
parent._tables.begin(), parent._tables.end());
|
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 %>)";
|
34
|
+
if (!parent._constraint.nil())
|
35
|
+
_constraint._cond += " AND " + parent._constraint._cond;
|
36
|
+
}
|
37
|
+
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% generated_properties.each do |property| %>
|
41
|
+
struct E_<%= property.name %>{
|
42
|
+
E_<%= property.name %>()
|
43
|
+
{
|
44
|
+
_field = "<%= storage_name %>.<%= property.name.to_s %>";
|
45
|
+
}
|
46
|
+
std::string _field;
|
47
|
+
typedef T_<%= class_name %>::Condition ConditionType;
|
48
|
+
typedef <%= property.instance_variable_get(:@cpp_name) %>::Base ComparerType;
|
49
|
+
};
|
50
|
+
|
51
|
+
E_<%= property.name %> _<%= property.name %>(){
|
52
|
+
return E_<%= property.name %>();
|
53
|
+
}
|
54
|
+
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
void getFields(std::vector<std::string>& rFields)
|
58
|
+
{
|
59
|
+
rFields.clear();
|
60
|
+
<% generated_properties.each do |property| %>
|
61
|
+
rFields.push_back("<%= property.name %>");
|
62
|
+
<% end %>
|
63
|
+
}
|
64
|
+
|
65
|
+
void select(const Condition& c,
|
66
|
+
const std::string& additional,
|
67
|
+
std::vector<O_<%= class_name %>>& r)
|
68
|
+
{
|
69
|
+
Condition c1 = _constraint.nil() ? c : _constraint && c;
|
70
|
+
std::vector<std::string> fields;
|
71
|
+
getFields(fields);
|
72
|
+
QueryRes res;
|
73
|
+
DBFace::instance()->select(_tables, fields, c1._cond,
|
74
|
+
additional, res);
|
75
|
+
r.resize(res.size());
|
76
|
+
for(size_t i = 0; i < res.size(); ++i){
|
77
|
+
<% generated_properties.each do |property| %>
|
78
|
+
r[i]._f_<%= property.name %>._base =
|
79
|
+
fromString<<%= property.instance_variable_get(:@cpp_name) %>::Base>(res[i]["<%= property.name %>"]);
|
80
|
+
<% end %>
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
void erase(const Condition& c)
|
85
|
+
{
|
86
|
+
Condition c1 = _constraint.nil() ? c : _constraint && c;
|
87
|
+
DBFace::instance()->erase(_tables, c1._cond);
|
88
|
+
}
|
89
|
+
void erase()
|
90
|
+
{
|
91
|
+
DBFace::instance()->erase(_tables, _constraint._cond);
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
void select(const Condition& c,
|
96
|
+
std::vector<O_<%= class_name %>>& r)
|
97
|
+
{
|
98
|
+
Condition c1 = _constraint.nil() ? c : _constraint && c;
|
99
|
+
select(c1, "", r);
|
100
|
+
}
|
101
|
+
void select(std::vector<O_<%= class_name %>>& r)
|
102
|
+
{
|
103
|
+
select(_constraint, "", r);
|
104
|
+
}
|
105
|
+
|
106
|
+
std::pair<O_<%= class_name %>, bool> select(const I_<%= class_name %>& id){
|
107
|
+
return first(E_<%= serial.name %>() == id);
|
108
|
+
}
|
109
|
+
|
110
|
+
std::pair<O_<%= class_name %>, bool> first(const Condition& c)
|
111
|
+
{
|
112
|
+
Condition c1 = _constraint.nil() ? c : _constraint && c;
|
113
|
+
std::vector<O_<%= class_name %>> r;
|
114
|
+
select(c, "limit 1", r);
|
115
|
+
if(r.size() > 0)
|
116
|
+
return std::make_pair(r[0], true);
|
117
|
+
else
|
118
|
+
return std::make_pair(O_<%= class_name %>(), false);
|
119
|
+
}
|
120
|
+
|
121
|
+
std::pair<O_<%= class_name %>, bool> first(){
|
122
|
+
return first(_constraint);
|
123
|
+
}
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
Condition _constraint;
|
130
|
+
std::vector<std::string> _tables;
|
131
|
+
};
|
132
|
+
|
133
|
+
} //namespace DMMM
|
134
|
+
#endif //T_<%= all_caps_name %>
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#ifndef DMMM_COMPARATORS_H
|
2
|
+
#define DMMM_COMPARATORS_H
|
3
|
+
|
4
|
+
#include <string>
|
5
|
+
#include <sstream>
|
6
|
+
|
7
|
+
namespace DMMM {
|
8
|
+
template<class E>
|
9
|
+
typename E::ConditionType operator== (E e, const typename E::ComparerType& x){
|
10
|
+
typename E::ConditionType c;
|
11
|
+
c._cond = e._field + " = '" + toString(x) + "'";
|
12
|
+
return c;
|
13
|
+
}
|
14
|
+
|
15
|
+
template<class E>
|
16
|
+
typename E::ConditionType operator< (E e, const typename E::ComparerType& x){
|
17
|
+
typename E::ConditionType c;
|
18
|
+
c._cond = e._field + " < '" + toString(x) + "'";
|
19
|
+
return c;
|
20
|
+
}
|
21
|
+
|
22
|
+
template<class E>
|
23
|
+
typename E::ConditionType operator<= (E e, const typename E::ComparerType& x){
|
24
|
+
typename E::ConditionType c;
|
25
|
+
c._cond = e._field + " <= '" + toString(x) + "'";
|
26
|
+
return c;
|
27
|
+
}
|
28
|
+
|
29
|
+
template<class E>
|
30
|
+
typename E::ConditionType operator> (E e, const typename E::ComparerType& x){
|
31
|
+
typename E::ConditionType c;
|
32
|
+
c._cond = e._field + " > '" + toString(x) + "'";
|
33
|
+
return c;
|
34
|
+
}
|
35
|
+
|
36
|
+
template<class E>
|
37
|
+
typename E::ConditionType operator>= (E e, const typename E::ComparerType& x){
|
38
|
+
typename E::ConditionType c;
|
39
|
+
c._cond = e._field + " >= '" + toString(x) + "'";
|
40
|
+
return c;
|
41
|
+
}
|
42
|
+
|
43
|
+
template<class E>
|
44
|
+
typename E::ConditionType operator!= (E e, const typename E::ComparerType& x){
|
45
|
+
typename E::ConditionType c;
|
46
|
+
c._cond = e._field + " != '" + toString(x) + "'";
|
47
|
+
return c;
|
48
|
+
}
|
49
|
+
|
50
|
+
template<class E>
|
51
|
+
typename E::ConditionType operator%= (E e, const typename E::ComparerType& x){
|
52
|
+
typename E::ConditionType c;
|
53
|
+
c._cond = e._field + " LIKE '" + toString(x) + "'";
|
54
|
+
return c;
|
55
|
+
}
|
56
|
+
|
57
|
+
template<class C>
|
58
|
+
C operator&& (const C& c1, const C& c2){
|
59
|
+
C c;
|
60
|
+
c._cond = "(" + c1._cond + ") AND (" + c2._cond + ")";
|
61
|
+
return c;
|
62
|
+
}
|
63
|
+
|
64
|
+
template<class C>
|
65
|
+
C operator|| (const C& c1, const C& c2){
|
66
|
+
C c;
|
67
|
+
c._cond = "(" + c1._cond + ") OR (" + c2._cond + ")";
|
68
|
+
return c;
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
} //namespace DMMM
|
73
|
+
|
74
|
+
#endif //DMMM_COMPARATORS_H
|
@@ -0,0 +1,176 @@
|
|
1
|
+
#include "dmmm_dbface.h"
|
2
|
+
#include "dmmm_utils.hpp"
|
3
|
+
using namespace mysqlpp;
|
4
|
+
using namespace std;
|
5
|
+
using namespace DMMM;
|
6
|
+
|
7
|
+
DBFace* DBFace::_this = NULL;
|
8
|
+
|
9
|
+
DBFace::DBFace(const string& database, const string& host,
|
10
|
+
const string& user, const string& password)
|
11
|
+
{
|
12
|
+
_this = this;
|
13
|
+
if (!_connection.connect(database.c_str(), host.c_str(),
|
14
|
+
user.c_str(), password.c_str())){
|
15
|
+
cerr << "Could not connect to DB";
|
16
|
+
exit(-1);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
bool
|
21
|
+
DBFace::select(const std::vector<std::string>& tables,
|
22
|
+
const std::vector<string>& columns,
|
23
|
+
const std::string& where,
|
24
|
+
const std::string& additional,
|
25
|
+
QueryRes& rRes)
|
26
|
+
{
|
27
|
+
boost::mutex::scoped_lock lock(_mutex);
|
28
|
+
|
29
|
+
Query q = _connection.query();
|
30
|
+
|
31
|
+
q << "SELECT ";
|
32
|
+
for (size_t i = 0; i < columns.size(); ++i){
|
33
|
+
if (i > 0)
|
34
|
+
q << ",";
|
35
|
+
q << tables[0] << "." << columns[i];
|
36
|
+
}
|
37
|
+
q << " FROM " << tables[0];
|
38
|
+
for (size_t i = 1; i < tables.size(); ++i)
|
39
|
+
q << ", " + tables[i];
|
40
|
+
if (where.size())
|
41
|
+
q << " WHERE " << where;
|
42
|
+
if (additional.size())
|
43
|
+
q << " " << additional;
|
44
|
+
cout << q << endl;
|
45
|
+
StoreQueryResult mysqlRes;
|
46
|
+
try{
|
47
|
+
mysqlRes = q.store();
|
48
|
+
}
|
49
|
+
catch (const mysqlpp::Exception& er) {
|
50
|
+
cerr << "Query failed: " << q << endl << er.what();
|
51
|
+
return false;
|
52
|
+
}
|
53
|
+
|
54
|
+
for (size_t i = 0; i < mysqlRes.num_rows(); ++i){
|
55
|
+
rRes.resize(rRes.size() + 1);
|
56
|
+
for (size_t j = 0; j < columns.size(); ++j)
|
57
|
+
rRes.back()[columns[j]] = toString(mysqlRes[i][columns[j].c_str()]);
|
58
|
+
}
|
59
|
+
return true;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
bool
|
64
|
+
DBFace::erase(const std::vector<std::string>& tables,
|
65
|
+
const std::string& where)
|
66
|
+
{
|
67
|
+
Query q = _connection.query();
|
68
|
+
q << "DELETE FROM " << tables[0];
|
69
|
+
if (tables.size() > 1)
|
70
|
+
q << " USING " + tables[0] + " ";
|
71
|
+
for (size_t i = 1; i < tables.size(); ++i)
|
72
|
+
q << " INNER JOIN " + tables[i];
|
73
|
+
if (where.size())
|
74
|
+
q << " WHERE " << where;
|
75
|
+
cout << q << endl;
|
76
|
+
return executeQuery(q);
|
77
|
+
|
78
|
+
}
|
79
|
+
|
80
|
+
|
81
|
+
bool
|
82
|
+
DBFace::executeQuery(Query& q)
|
83
|
+
{
|
84
|
+
boost::mutex::scoped_lock lock(_mutex);
|
85
|
+
try{
|
86
|
+
q.execute();
|
87
|
+
}
|
88
|
+
catch (const mysqlpp::Exception& er) {
|
89
|
+
cerr << "Query failed: " << q << endl << er.what();
|
90
|
+
return false;
|
91
|
+
}
|
92
|
+
return true;
|
93
|
+
}
|
94
|
+
|
95
|
+
bool
|
96
|
+
DBFace::getLastInsertId(Query& rQuery, size_t& rId)
|
97
|
+
{
|
98
|
+
try{
|
99
|
+
rId = rQuery.insert_id();
|
100
|
+
cout << "got last insert ID: " << rId << endl;
|
101
|
+
}
|
102
|
+
catch (const mysqlpp::Exception& er) {
|
103
|
+
return false;
|
104
|
+
}
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
bool
|
109
|
+
DBFace::insert(const string& table,
|
110
|
+
const map<string, string>& field2Val,
|
111
|
+
size_t& rInsertId)
|
112
|
+
{
|
113
|
+
if (field2Val.size() == 0)
|
114
|
+
return true;
|
115
|
+
|
116
|
+
Query q = _connection.query();
|
117
|
+
q << "INSERT INTO " << table << " (";
|
118
|
+
for (map<string, string>::const_iterator it = field2Val.begin();
|
119
|
+
it != field2Val.end(); ++it)
|
120
|
+
{
|
121
|
+
if (it != field2Val.begin())
|
122
|
+
q << ",";
|
123
|
+
q << it->first;
|
124
|
+
}
|
125
|
+
q << ")VALUES(";
|
126
|
+
for (map<string, string>::const_iterator it = field2Val.begin();
|
127
|
+
it != field2Val.end(); ++it)
|
128
|
+
{
|
129
|
+
if (it != field2Val.begin())
|
130
|
+
q << ",";
|
131
|
+
q << quote << it->second;
|
132
|
+
}
|
133
|
+
q << ")";
|
134
|
+
cout << q << endl;
|
135
|
+
bool ok = executeQuery(q);
|
136
|
+
ok = ok && getLastInsertId(q, rInsertId);
|
137
|
+
return ok;
|
138
|
+
}
|
139
|
+
|
140
|
+
bool
|
141
|
+
DBFace::update(const string& table,
|
142
|
+
const map<string, string>& field2Val,
|
143
|
+
const string& where)
|
144
|
+
{
|
145
|
+
Query q = _connection.query();
|
146
|
+
|
147
|
+
q << "UPDATE " << table << " SET ";
|
148
|
+
for (map<string, string>::const_iterator it = field2Val.begin();
|
149
|
+
it != field2Val.end(); ++it)
|
150
|
+
{
|
151
|
+
if (it != field2Val.begin())
|
152
|
+
q << ",";
|
153
|
+
q << it->first << "=" << quote << it->second;
|
154
|
+
}
|
155
|
+
if (where.size())
|
156
|
+
q << " WHERE " << where;
|
157
|
+
cout << q << endl;
|
158
|
+
return executeQuery(q);
|
159
|
+
}
|
160
|
+
|
161
|
+
string
|
162
|
+
DBFace::now()
|
163
|
+
{
|
164
|
+
Query q = _connection.query();
|
165
|
+
|
166
|
+
q << "SELECT NOW()";
|
167
|
+
StoreQueryResult mysqlRes;
|
168
|
+
try{
|
169
|
+
mysqlRes = q.store();
|
170
|
+
}
|
171
|
+
catch (const mysqlpp::Exception& er) {
|
172
|
+
cerr << "Query failed: " << q << endl << er.what();
|
173
|
+
return string();
|
174
|
+
}
|
175
|
+
return toString(mysqlRes[0]["now()"]);
|
176
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#ifndef DMMM_DBFACE_H
|
2
|
+
#define DMMM_DBFACE_H
|
3
|
+
|
4
|
+
#include <map>
|
5
|
+
#include <mysql++.h>
|
6
|
+
#include <boost/thread/mutex.hpp>
|
7
|
+
|
8
|
+
namespace DMMM {
|
9
|
+
|
10
|
+
typedef std::vector<std::map<std::string, std::string> > QueryRes;
|
11
|
+
|
12
|
+
class DBFace{
|
13
|
+
public:
|
14
|
+
static DBFace* instance() { return _this; }
|
15
|
+
|
16
|
+
DBFace(const std::string& database, const std::string& host,
|
17
|
+
const std::string& user, const std::string& password);
|
18
|
+
|
19
|
+
bool insert(const std::string& table,
|
20
|
+
const std::map<std::string, std::string>& field2Val,
|
21
|
+
size_t& rInsertId);
|
22
|
+
bool update(const std::string& table,
|
23
|
+
const std::map<std::string, std::string>& field2Val,
|
24
|
+
const std::string& where);
|
25
|
+
bool select(const std::vector<std::string>& table,
|
26
|
+
const std::vector<std::string>& columns,
|
27
|
+
const std::string& where,
|
28
|
+
const std::string& additional,
|
29
|
+
QueryRes& rRes);
|
30
|
+
bool erase(const std::vector<std::string>& table,
|
31
|
+
const std::string& where);
|
32
|
+
|
33
|
+
std::string now();
|
34
|
+
|
35
|
+
private:
|
36
|
+
bool getLastInsertId(mysqlpp::Query& rQuery, size_t& rId);
|
37
|
+
bool executeQuery(mysqlpp::Query& rQuery);
|
38
|
+
|
39
|
+
private:
|
40
|
+
mysqlpp::Connection _connection;
|
41
|
+
mutable boost::mutex _mutex;
|
42
|
+
static DBFace* _this;
|
43
|
+
};
|
44
|
+
|
45
|
+
} //namespace DMMM
|
46
|
+
|
47
|
+
#endif //DB_H
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#ifndef DMMM_FIELDS_H
|
2
|
+
#define DMMM_FIELDS_H
|
3
|
+
|
4
|
+
#include <string>
|
5
|
+
|
6
|
+
#include <sstream>
|
7
|
+
|
8
|
+
#include "dmmm_utils.hpp"
|
9
|
+
|
10
|
+
namespace DMMM {
|
11
|
+
|
12
|
+
template<class T>
|
13
|
+
struct Field{
|
14
|
+
Field<T>() :_dirty(false) {}
|
15
|
+
Field<T>(const T& t) :_dirty(true), _base(t) {}
|
16
|
+
typedef T Base;
|
17
|
+
bool _dirty;
|
18
|
+
T _base;
|
19
|
+
}; //class Field
|
20
|
+
|
21
|
+
typedef Field<int> F_Integer;
|
22
|
+
typedef Field<double> F_Float;
|
23
|
+
typedef Field<std::string> F_String;
|
24
|
+
typedef Field<bool> F_TrueClass;
|
25
|
+
|
26
|
+
} //namespace DMMM
|
27
|
+
|
28
|
+
#endif //DMMM_FIELDS_H
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#ifndef _DMMM_ID_HPP
|
2
|
+
#define _DMMM_ID_HPP
|
3
|
+
|
4
|
+
#include <iosfwd>
|
5
|
+
#include <string>
|
6
|
+
#include <sstream>
|
7
|
+
|
8
|
+
namespace DMMM{
|
9
|
+
template<class T>
|
10
|
+
class Id {
|
11
|
+
|
12
|
+
public:
|
13
|
+
explicit Id(size_t id) : _id(id) {}
|
14
|
+
Id() {}
|
15
|
+
|
16
|
+
inline Id operator++() {
|
17
|
+
++_id; return *this;
|
18
|
+
}
|
19
|
+
|
20
|
+
inline Id operator++(int) {
|
21
|
+
Id val=*this;
|
22
|
+
++*this;
|
23
|
+
return val;
|
24
|
+
}
|
25
|
+
|
26
|
+
inline bool operator==(const Id& that) const {
|
27
|
+
return _id == that._id;
|
28
|
+
}
|
29
|
+
inline bool operator< (const Id& that) const {
|
30
|
+
return _id < that._id;
|
31
|
+
}
|
32
|
+
inline bool operator<=(const Id& that) const {
|
33
|
+
return _id <= that._id;
|
34
|
+
}
|
35
|
+
inline bool operator> (const Id& that) const {
|
36
|
+
return _id > that._id;
|
37
|
+
}
|
38
|
+
inline bool operator>= (const Id& that) const {
|
39
|
+
return _id >= that._id;
|
40
|
+
}
|
41
|
+
inline bool operator!=(const Id& that) const {
|
42
|
+
return ! (*this == that);
|
43
|
+
}
|
44
|
+
|
45
|
+
std::string to_s() const {
|
46
|
+
std::ostringstream oss;
|
47
|
+
oss << _id;
|
48
|
+
return oss.str();
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
inline size_t& serialization() { return _id; }
|
53
|
+
|
54
|
+
private:
|
55
|
+
size_t _id;
|
56
|
+
|
57
|
+
};
|
58
|
+
|
59
|
+
|
60
|
+
} //namespace DMMM
|
61
|
+
|
62
|
+
template<class T>
|
63
|
+
std::ostream&
|
64
|
+
operator<< (std::ostream& os, const DMMM::Id<T>& id)
|
65
|
+
{
|
66
|
+
os << id.to_s();
|
67
|
+
return os;
|
68
|
+
}
|
69
|
+
|
70
|
+
template<class T>
|
71
|
+
std::istream&
|
72
|
+
operator>> (std::istream& is, DMMM::Id<T>& id)
|
73
|
+
{
|
74
|
+
is >> id.serialization();
|
75
|
+
return is;
|
76
|
+
}
|
77
|
+
|
78
|
+
#endif //_DMMM_ID_HPP
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#ifndef DMMM_IDENTIFIERS_HPP
|
2
|
+
#define DMMM_IDENTIFIERS_HPP
|
3
|
+
|
4
|
+
#include "dmmm_id.hpp"
|
5
|
+
|
6
|
+
namespace DMMM {
|
7
|
+
|
8
|
+
<% models.each do |model| %>
|
9
|
+
class DummyO_<%= model.name %>;
|
10
|
+
typedef Id<DummyO_<%= model.name %>> I_<%= model.name %>;
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
|
14
|
+
} //namespace DMMM
|
15
|
+
#endif //DMMM_IDENTIFIERS_HPP
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#ifndef DMMM_UTILS_HPP
|
2
|
+
#define DMMM_UTILS_HPP
|
3
|
+
|
4
|
+
#include <vector>
|
5
|
+
#include <map>
|
6
|
+
#include <sstream>
|
7
|
+
#include <dmmm_id.hpp>
|
8
|
+
|
9
|
+
namespace DMMM {
|
10
|
+
|
11
|
+
template<class T>
|
12
|
+
std::string
|
13
|
+
toString(const T& t)
|
14
|
+
{
|
15
|
+
std::ostringstream oss;
|
16
|
+
oss << t;
|
17
|
+
|
18
|
+
return oss.str();
|
19
|
+
}
|
20
|
+
|
21
|
+
template<class T>
|
22
|
+
T
|
23
|
+
fromString(const std::string& s)
|
24
|
+
{
|
25
|
+
std::istringstream iss;
|
26
|
+
iss.str(s);
|
27
|
+
|
28
|
+
T ret;
|
29
|
+
iss >> ret;
|
30
|
+
|
31
|
+
return ret;
|
32
|
+
}
|
33
|
+
|
34
|
+
template<>
|
35
|
+
std::string
|
36
|
+
fromString<std::string>(const std::string& s);
|
37
|
+
|
38
|
+
} //namespace DMMM
|
39
|
+
|
40
|
+
#endif //DMMM_UTILS_HPP
|
@@ -0,0 +1,102 @@
|
|
1
|
+
<% class_name = self.name %>
|
2
|
+
<% all_caps_name = class_name.upcase %>
|
3
|
+
#ifndef O_<%= all_caps_name %>
|
4
|
+
#define O_<%= all_caps_name %>
|
5
|
+
|
6
|
+
#include <map>
|
7
|
+
#include <string>
|
8
|
+
#include "dmmm_utils.hpp"
|
9
|
+
#include "dmmm_dbface.h"
|
10
|
+
#include "dmmm_identifiers.hpp"
|
11
|
+
#include "dmmm_fields.hpp"
|
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 %>.hpp"
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<%# self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::OneToMany::Relationship'}.each do |relative| %>
|
18
|
+
<%# end %>
|
19
|
+
namespace DMMM {
|
20
|
+
|
21
|
+
class O_<%= class_name %>{
|
22
|
+
public:
|
23
|
+
|
24
|
+
O_<%= class_name %>() {}
|
25
|
+
<% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
|
26
|
+
<% parent = r[0].to_const_string %>
|
27
|
+
O_<%= class_name %>(const O_<%= parent %>& parent)
|
28
|
+
: _f_<%= r[1].child_key.first.name.to_s %>(parent._<%= r[1].parent_key.first.name.to_s %>())
|
29
|
+
{}
|
30
|
+
O_<%= class_name %>(const I_<%= parent %>& parent_id)
|
31
|
+
: _f_<%= r[1].child_key.first.name.to_s %>(parent_id)
|
32
|
+
{}
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% generated_properties.each do |property| %>
|
36
|
+
const <%= property.instance_variable_get(:@cpp_name) %>::Base& _<%= property.name %>() const {
|
37
|
+
return _f_<%= property.name %>._base;
|
38
|
+
}
|
39
|
+
<%= property.instance_variable_get(:@cpp_name) %>::Base& _<%= property.name %>() {
|
40
|
+
_f_<%= property.name %>._dirty = true;
|
41
|
+
return _f_<%= property.name %>._base;
|
42
|
+
}
|
43
|
+
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<% if serial %>
|
47
|
+
bool update(){
|
48
|
+
std::map<std::string, std::string> field2Val;
|
49
|
+
<% generated_properties.each do |property| %>
|
50
|
+
if (_f_<%= property.name %>._dirty)
|
51
|
+
field2Val["<%= property.name %>"] =
|
52
|
+
toString(_f_<%= property.name %>._base);
|
53
|
+
<% end %>
|
54
|
+
std::string where =
|
55
|
+
"<%= serial.name %>=" + toString(_f_<%= serial.name %>._base);
|
56
|
+
return DBFace::instance()->update("<%= storage_name %>",
|
57
|
+
field2Val, where);
|
58
|
+
}
|
59
|
+
|
60
|
+
<% end %>
|
61
|
+
|
62
|
+
|
63
|
+
bool insert(){
|
64
|
+
std::map<std::string, std::string> field2Val;
|
65
|
+
<% generated_properties.each do |property| %>
|
66
|
+
if (_f_<%= property.name %>._dirty)
|
67
|
+
field2Val["<%= property.name %>"] =
|
68
|
+
toString(_f_<%= property.name %>._base);
|
69
|
+
<% end %>
|
70
|
+
<% if serial %>
|
71
|
+
return DBFace::instance()->
|
72
|
+
insert("<%= storage_name %>", field2Val,
|
73
|
+
_f_<%= serial.name %>._base.serialization());
|
74
|
+
<% else %>
|
75
|
+
size_t id;
|
76
|
+
return DBFace::instance()->
|
77
|
+
insert("<%= storage_name %>", field2Val,
|
78
|
+
id);
|
79
|
+
<% end %>
|
80
|
+
|
81
|
+
}
|
82
|
+
|
83
|
+
<% self.relationships.select{|r,m| m.class.name == 'DataMapper::Associations::ManyToOne::Relationship'}.each do |r| %>
|
84
|
+
<% parent = r[0].to_const_string %>
|
85
|
+
std::pair<O_<%= parent %>, bool> <%= r[0] %>(){
|
86
|
+
T_<%= parent %> T(T_<%= parent %>::E_<%= r[1].parent_key.first.name.to_s %>() == _<%= r[1].child_key.first.name.to_s %>());
|
87
|
+
return T.first();
|
88
|
+
}
|
89
|
+
<% end %>
|
90
|
+
|
91
|
+
|
92
|
+
private:
|
93
|
+
<% generated_properties.each do |property| %>
|
94
|
+
<%= property.instance_variable_get(:@cpp_name) %> _f_<%= property.name %>;
|
95
|
+
<% end %>
|
96
|
+
|
97
|
+
|
98
|
+
friend class T_<%= class_name %>;
|
99
|
+
};
|
100
|
+
|
101
|
+
} //namespace DMMM
|
102
|
+
#endif //O_<%= all_caps_name %>
|
data/output/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dm-metamapper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Jonah Honeyman
|
13
|
+
- Omer Tamuz
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-08 00:00:00 +03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: C++ API for databases created with DM. Hard typing, compile time checked queries.
|
23
|
+
email: jonah@honeyman.org
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.md
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- Gemfile
|
33
|
+
- README.md
|
34
|
+
- VERSION
|
35
|
+
- example/.gitignore
|
36
|
+
- example/Makefile
|
37
|
+
- example/example.cpp
|
38
|
+
- example/example.rb
|
39
|
+
- lib/dm-metamapper.rb
|
40
|
+
- lib/dm-metamapper/extension.rb
|
41
|
+
- lib/dm-metamapper/generator.rb
|
42
|
+
- lib/dm-metamapper/metamapper.rb
|
43
|
+
- lib/dm-metamapper/property.rb
|
44
|
+
- lib/templates/cpp/class.hpp.erb
|
45
|
+
- lib/templates/cpp/dmmm_comparators.hpp.erb
|
46
|
+
- lib/templates/cpp/dmmm_dbface.cpp.erb
|
47
|
+
- lib/templates/cpp/dmmm_dbface.h.erb
|
48
|
+
- lib/templates/cpp/dmmm_fields.hpp.erb
|
49
|
+
- lib/templates/cpp/dmmm_id.hpp.erb
|
50
|
+
- lib/templates/cpp/dmmm_identifiers.hpp.erb
|
51
|
+
- lib/templates/cpp/dmmm_utils.cpp.erb
|
52
|
+
- lib/templates/cpp/dmmm_utils.hpp.erb
|
53
|
+
- lib/templates/cpp/instance.hpp.erb
|
54
|
+
- output/.gitignore
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/jonuts/dm-metamapper
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
requirements: []
|
80
|
+
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 1.3.6
|
83
|
+
signing_key:
|
84
|
+
specification_version: 3
|
85
|
+
summary: Code generating C++ ORM
|
86
|
+
test_files:
|
87
|
+
- spec/spec_helper.rb
|