dm-metamapper 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.
- 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
|