sqlyzer 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,184 @@
1
+ # SQLYZER Ruby Object serializer to SQL.
2
+ # For more information visit http://sqlyzer.rubyforge.org
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation; either version 2
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #
18
+
19
+ require 'sqlyzer/errors'
20
+
21
+ module Sqlyzer
22
+
23
+ module Associate
24
+
25
+ public
26
+
27
+ class Link
28
+ include Serializer
29
+
30
+ public
31
+
32
+ def initialize(owner, key)
33
+ @source = owner.method key
34
+ @updated = {}
35
+ @current_var = get_current_var
36
+ end
37
+
38
+ protected
39
+
40
+ def sql_table(table, keys, values)
41
+ super(table, keys, values) +
42
+ sql_alter_table_fk(
43
+ table,
44
+ SQL_LINK_FROM::SQL_CONTAINER_TABLE,
45
+ SQL_LINK_FROM_FK.keys,
46
+ SQL_LINK_FROM_FK.values
47
+ ) +
48
+ sql_alter_table_fk(
49
+ table,
50
+ SQL_LINK_TO::SQL_CONTAINER_TABLE,
51
+ SQL_LINK_TO_FK.keys,
52
+ SQL_LINK_TO_FK.values
53
+ )
54
+ end
55
+
56
+ def set_current_item(item)
57
+ assertUnreached
58
+ end
59
+
60
+ private
61
+
62
+ def get_current_var
63
+ @source.call
64
+ end
65
+
66
+ def update_to_new_var(event, item)
67
+ @updated.each { |item, event|
68
+ set_current_item item
69
+ if event == :link_add
70
+ ::Handler::request self, :sql_insert
71
+ else
72
+ ::Handler::request self, :sql_delete
73
+ end
74
+ }
75
+ @updated.clear
76
+ @current_var = get_current_var
77
+ end
78
+
79
+ public
80
+
81
+ def push(*items)
82
+ for item in items
83
+ @updated[item] = :link_add unless @current.include?(item)
84
+ end
85
+ end
86
+
87
+ def pop(*items)
88
+ for item in items
89
+ @updated[item] = :link_del if @current.include?(item)
90
+ end
91
+ end
92
+
93
+ public
94
+
95
+ def flush
96
+ update_to_new_var unless @updated.empty?
97
+ end
98
+
99
+ public
100
+
101
+ def Link.make(from, to, owner, key)
102
+ idx = "#{from}_to_#{to}"
103
+ return @@klasses[idx] if @@klasses.include?(idx)
104
+ end
105
+
106
+ end
107
+
108
+ private
109
+
110
+ module Keys
111
+
112
+ public
113
+
114
+ def Keys.link(owner, key, klass)
115
+ if owner.const_defined?(:SQL_ASSOCIATE_VARS)
116
+ old = owner.const_get :SQL_ASSOCIATE_VARS
117
+ old[key] = klass
118
+ owner.const_set :SQL_ASSOCIATE_VARS, old
119
+ else
120
+ owner.const_set :SQL_ASSOCIATE_VARS, { key => klass }
121
+ end
122
+ end
123
+
124
+ public
125
+
126
+ def sql_associate_keys
127
+ self.class::SQL_ASSOCIATE_KEYS
128
+ end
129
+
130
+ def sql_associate_each(&block)
131
+ sql_associate_keys.each(&block)
132
+ end
133
+
134
+ end #~ Keys
135
+
136
+ public
137
+
138
+ module One
139
+ include Keys
140
+
141
+ public
142
+
143
+ def One.link(owner, key, klass)
144
+ Keys.link owner, key, klass
145
+ end
146
+
147
+ public
148
+
149
+ def sql_associate_select
150
+ end
151
+
152
+ def sql_associate_update
153
+ end
154
+
155
+ def sql_associate_insert
156
+ end
157
+
158
+ end #~ One
159
+
160
+ module Many
161
+ include Keys
162
+
163
+ public
164
+
165
+ def Many.link(owner, key, klass)
166
+ Keys.link owner, key, klass
167
+ end
168
+
169
+ public
170
+
171
+ def sql_associate_select
172
+ end
173
+
174
+ def sql_associate_update
175
+ end
176
+
177
+ def sql_associate_insert
178
+ end
179
+
180
+ end
181
+
182
+ end #~ Associate
183
+
184
+ end #~ Sqlyzer
@@ -0,0 +1,140 @@
1
+ # SQLYZER Ruby Object serializer to SQL.
2
+ # For more information visit http://sqlyzer.rubyforge.org
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation; either version 2
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #
18
+
19
+ require 'sqlyzer/errors'
20
+ require 'sqlyzer/parameters'
21
+
22
+ module Sqlyzer
23
+
24
+ #
25
+ #This Mixin is dedicated to Sql components registering for one class extended
26
+ #by Sqlyzer::Serializer.
27
+ #
28
+ #Here is the list of stored data :
29
+ #* name of the future Sql table (SQL_CONTAINER_TABLE),
30
+ #* primary keys of the future Sql table (SQL_CONTAINER_KEYS),
31
+ #* regular fields of the future Sql table (SQL_CONTAINER_VALUES).
32
+ #
33
+ module Container
34
+
35
+ public
36
+
37
+ #
38
+ #Retreive chosen table identifier for current class.
39
+ #This method is reading the constant named SQL_CONTAINER_TABLE.
40
+ #
41
+ def sql_container_table
42
+ self.class::SQL_CONTAINER_TABLE
43
+ end
44
+
45
+ #
46
+ #Retreive the list of registered Sqlyzer::Parameter::Default class (stored in
47
+ #a Sqlyzer::Parameter::List object) as current class primary keys.
48
+ #This method is reading the constant named SQL_CONTAINER_KEYS.
49
+ #
50
+ def sql_container_keys
51
+ self.class::SQL_CONTAINER_KEYS
52
+ end
53
+
54
+ #
55
+ #Retreive the list of registered Sqlyzer::Parameter::Default class (stored in
56
+ #a Sqlyzer::Parameter::List object) as current class regular table fields.
57
+ #This method is reading the constant named SQL_CONTAINER_VALUES.
58
+ #
59
+ def sql_container_values
60
+ self.class::SQL_CONTAINER_VALUES
61
+ end
62
+
63
+ protected
64
+
65
+ #
66
+ #Yield the list of Sqlyzer::Parameter::Default classes registered as object
67
+ #Sql keys.
68
+ #
69
+ #See also sql_container_keys.
70
+ #
71
+ def sql_each_keys(&block)
72
+ sql_container_keys.each(&block)
73
+ end
74
+
75
+ #
76
+ #Yield the list of Sqlyzer::Parameter::Default classes registered as object
77
+ #Sql values.
78
+ #
79
+ #See also sql_container_values.
80
+ #
81
+ def sql_each_values(&block)
82
+ sql_container_values.each(&block)
83
+ end
84
+
85
+ private
86
+
87
+ #
88
+ #Called to define or redefine the _owner_ constant named _dest_ by concating
89
+ #the previous value of _dest_ with _source_ value.
90
+ #If _dest_ was not defined, it is initialized as a Sqlyzer::Parameter::List
91
+ #contained all _source_ items (but translated).
92
+ #
93
+ #See also Sqlyzer::Parameter::List.
94
+ #
95
+ def Container.sql_container_has(owner, dest, source)
96
+ if owner.const_defined?(dest)
97
+ old = owner.const_get(dest)
98
+ owner.const_set(dest, old + source)
99
+ else
100
+ owner.const_set(dest, Parameter::List.new(source))
101
+ end
102
+ end
103
+
104
+ #
105
+ #Called to set a constant named _dest_ and containing _name_ (considered as
106
+ #a String) in _owner_ class.
107
+ #
108
+ def Container.sql_container_set(owner, dest, name)
109
+ owner.const_set dest, name.to_s
110
+ end
111
+
112
+ public
113
+
114
+ #
115
+ #Register _data_ into _owner_ class as list of table primary keys.
116
+ #Call to this method will define or complete SQL_CONTAINER_KEYS constant.
117
+ #
118
+ def Container.sql_has_keys(owner, data)
119
+ Container::sql_container_has owner, :SQL_CONTAINER_KEYS, data
120
+ end
121
+
122
+ #
123
+ #Register _data_ into _owner_ class as list of table regular fields.
124
+ #Call to this method will define or complete SQL_CONTAINER_VALUES constant.
125
+ #
126
+ def Container.sql_has_values(owner, data)
127
+ Container::sql_container_has owner, :SQL_CONTAINER_VALUES, data
128
+ end
129
+
130
+ #
131
+ #Register _name_ into _owner_ class as the name of Sql table.
132
+ #Call to this method will define or redefine SQL_CONTAINER_TABLE constant.
133
+ #
134
+ def Container.sql_set_table(owner, name)
135
+ Container::sql_container_set owner, :SQL_CONTAINER_TABLE, name.to_s.downcase
136
+ end
137
+
138
+ end #~ Container
139
+
140
+ end #~ Sqlyzer
@@ -0,0 +1,189 @@
1
+ # SQLYZER Ruby Object serializer to SQL.
2
+ # For more information visit http://sqlyzer.rubyforge.org
3
+ #
4
+ # This program is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU General Public License
6
+ # as published by the Free Software Foundation; either version 2
7
+ # of the License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
+ #
18
+
19
+ require 'sqlyzer/errors'
20
+
21
+ module Sqlyzer
22
+
23
+ module Sql
24
+
25
+ #
26
+ #Generate SQL commands for tables creation.
27
+ #
28
+ module Create
29
+
30
+ private
31
+
32
+ #
33
+ #Generate a basic CREATE Sql command for given _type_ called _name_.
34
+ #
35
+ def Create._sql_create(type, name)
36
+ "CREATE #{type.to_s.upcase} #{name} " +
37
+ (block_given? ? yield : '') +
38
+ ';'
39
+ end
40
+
41
+ #
42
+ #Generate a basic REPLACE Sql command for given _type_ called _name_.
43
+ #Concat block code return value if block given.
44
+ #
45
+ def Create._sql_replace(type, name)
46
+ "REPLACE #{type.to_s.upcase} #{name} " +
47
+ (block_given? ? yield : '') +
48
+ ';'
49
+ end
50
+
51
+ #
52
+ #Generate a basic CREATE OR REPLACE Sql command for given _type_ called _name_.
53
+ #Concat block code return value if block given.
54
+ #
55
+ def Create._sql_create_or_replace(type, name)
56
+ "CREATE OR REPLACE #{type.to_s.upcase} #{name} " +
57
+ (block_given? ? yield : '') +
58
+ ';'
59
+ end
60
+
61
+ #
62
+ #Generate a basic ALTER Sql command for given _type_ called _name_.
63
+ #Concat block code return value if block given.
64
+ #
65
+ def Create._sql_alter(type, name)
66
+ "ALTER #{type.to_s.upcase} #{name} " +
67
+ (block_given? ? yield : '') +
68
+ ';'
69
+ end
70
+
71
+ #
72
+ #Generate a basic DROP Sql command for given _type_ called _name_.
73
+ #_opts_ will be added at the end of the command (before semicolon).
74
+ #Concat block code return value if block given.
75
+ #
76
+ def Create._sql_drop(type, name, opts = '')
77
+ "DROP #{type.to_s.upcase} #{name} #{opts};"
78
+ end
79
+
80
+ public
81
+
82
+ #
83
+ #Create a new table called _name_, with Sqlyzer::Parameter::List _keys_ as
84
+ #primary keys and values as regular fields.
85
+ #The fresh table may be optionally inherited from an other table call
86
+ #_inherit_from_ if not nil.
87
+ #
88
+ def sql_create_table(name, keys, values, inherit_from = nil)
89
+ Create::_sql_create('TABLE', name) {
90
+ content = keys.clone.concat(values)
91
+ content.collect! { |p|
92
+ "#{p}\t#{p.to_sql_type}\t NOT NULL"
93
+ }
94
+ if inherit_from
95
+ "(\n#{content.join ",\n"}\n) INHERITS (#{inherit_from})"
96
+ else
97
+ "(\n#{content.join ",\n"}\n)"
98
+ end
99
+ }
100
+ end
101
+
102
+ #
103
+ #Generate a basic Sql ALTER command on table called _name_.
104
+ #Concat _block_ return value.
105
+ #
106
+ def sql_alter_table(name, &block)
107
+ Create::_sql_alter('TABLE', name, &block)
108
+ end
109
+
110
+ #
111
+ #Drop the table called _name_.
112
+ #The method will remove linked Sql objects if _cascade_ is true.
113
+ #
114
+ def sql_drop_table(name, cascade = true)
115
+ if cascade
116
+ Create::_sql_drop('TABLE', name, 'CASCADE')
117
+ else
118
+ Create::_sql_drop('TABLE', name)
119
+ end
120
+ end
121
+
122
+ public
123
+
124
+ #
125
+ #Create an index on fields _keys_ from table called _name_.
126
+ #_keys_ is assumed to be a Sqlyzer::Parameter::List.
127
+ #
128
+ def sql_create_table_index(name, keys)
129
+ Create::_sql_create('INDEX', "#{name.to_s.upcase}_PK") {
130
+ "ON #{name} (\n\t" +
131
+ keys.to_a.join(",\n\t") +
132
+ "\n)"
133
+ }
134
+ end
135
+
136
+ #
137
+ #Create an unique index on primary keys _keys_ from table called _name_.
138
+ #_keys_ is assumed to be a Sqlyzer::Parameter::List.
139
+ #
140
+ def sql_create_table_unique_index(name, keys)
141
+ Create::_sql_create('UNIQUE INDEX', "#{name.to_s.upcase}_PK") {
142
+ "ON #{name} (\n\t" +
143
+ keys.to_a.join(",\n\t") +
144
+ "\n)"
145
+ }
146
+ end
147
+ alias sql_create_table_index! sql_create_table_unique_index
148
+
149
+ public
150
+
151
+ #
152
+ #Generate a PRIMARY KEY constraint on fields _keys_ from table called _name_.
153
+ #_keys_ is assumed to be a Sqlyzer::Parameter::List.
154
+ #
155
+ def sql_alter_table_pk(name, keys)
156
+ sql_alter_table(name) {
157
+ "ADD CONSTRAINT PK_#{name.to_s.upcase} PRIMARY KEY (\n\t" +
158
+ keys.to_a.join(",\n\t") +
159
+ "\n)"
160
+ }
161
+ end
162
+ alias sql_alter_primary_key sql_alter_table_pk
163
+
164
+ #
165
+ #Generate a FOREIGN KEY constraint on fields _from_ from table called _source_
166
+ #to another called _dest_ on fields _to_.
167
+ #If _to_ is nil, assumed that the fields have the same name in both _source_
168
+ #and _dest_ tables.
169
+ #If _cascade_ is true, rows will be deleted on reference break.
170
+ #_from_ and _to_ are assumed to be a Sqlyzer::Parameter::List.
171
+ #
172
+ def sql_alter_table_fk(source, dest, from, to = nil, cascade = true)
173
+ to = from unless to
174
+ cascade = cascade ? "CASCADE" : "RESTRICT"
175
+ sql_alter_table(source) {
176
+ "ADD CONSTRAINT FK_#{source.to_s.upcase}_TO_#{dest.to_s.upcase} FOREIGN KEY (\n\t" +
177
+ from.join(",\n\t") +
178
+ "\n) REFERENCES #{dest} (\n\t" +
179
+ to.join(",\n\t") +
180
+ "\n) ON UPDATE #{cascade} ON DELETE #{cascade}"
181
+ }
182
+ end
183
+ alias sql_alter_foreign_key sql_alter_table_fk
184
+
185
+ end #~ Create
186
+
187
+ end #~ Sql
188
+
189
+ end #~ Sqlyzer