Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
ee4a5f3c
Commit
ee4a5f3c
authored
Jan 22, 2019
by
Douglas Barbosa Alexandre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Turn Gitlab::Geo::Fdw into a Class
parent
f7bd0d2e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
188 deletions
+91
-188
ee/lib/gitlab/geo/fdw.rb
ee/lib/gitlab/geo/fdw.rb
+89
-85
ee/spec/lib/gitlab/geo/fdw_spec.rb
ee/spec/lib/gitlab/geo/fdw_spec.rb
+2
-103
No files found.
ee/lib/gitlab/geo/fdw.rb
View file @
ee4a5f3c
...
...
@@ -2,114 +2,118 @@
module
Gitlab
module
Geo
module
Fdw
class
Fdw
DEFAULT_SCHEMA
=
'public'
.
freeze
FDW_SCHEMA
=
'gitlab_secondary'
.
freeze
# Return full table name with FDW schema
#
# @param [String] table_name
def
self
.
table
(
table_name
)
FDW_SCHEMA
+
".
#{
table_name
}
"
end
class
<<
self
# Return full table name with FDW schema
#
# @param [String] table_name
def
table
(
table_name
)
FDW_SCHEMA
+
".
#{
table_name
}
"
end
# Return if FDW is enabled for this instance
#
# @return [Boolean] whether FDW is enabled
def
self
.
enabled?
return
false
unless
fdw_capable?
# Return if FDW is enabled for this instance
#
# @return [Boolean] whether FDW is enabled
def
enabled?
return
false
unless
fdw_capable?
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value
=
Rails
.
configuration
.
geo_database
[
'fdw'
]
value
.
nil?
?
true
:
value
end
# FDW is enabled by default, disable it by setting `fdw: false` in config/database_geo.yml
value
=
Rails
.
configuration
.
geo_database
[
'fdw'
]
value
.
nil?
?
true
:
value
end
def
self
.
fdw_capabl
e?
has_foreign_schema?
&&
connection_exist?
&&
count_tables
.
positive
?
end
def
fdw_up_to_dat
e?
has_foreign_schema?
&&
foreign_schema_tables_match
?
end
def
self
.
fdw_up_to_date?
has_foreign_schema?
&&
foreign_schema_tables_match?
end
# Number of existing tables
#
# @return [Integer] number of tables
def
count_tables
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_count_tables
)
do
sql
=
<<~
SQL
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '
#{
FDW_SCHEMA
}
'
AND table_type = 'FOREIGN TABLE'
AND table_name NOT LIKE 'pg_%'
SQL
::
Geo
::
TrackingBase
.
connection
.
execute
(
sql
).
first
.
fetch
(
'count'
).
to_i
end
end
def
self
.
has_foreign_schema?
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_schema_exist
)
do
sql
=
<<~
SQL
SELECT 1
FROM information_schema.schemata
WHERE schema_name='
#{
FDW_SCHEMA
}
'
SQL
def
count_tables_match?
gitlab_tables
.
count
==
count_tables
end
::
Geo
::
TrackingBase
.
connection
.
execute
(
sql
).
count
.
positive?
def
gitlab_tables
ActiveRecord
::
Schema
.
tables
.
reject
{
|
table
|
table
.
start_with?
(
'pg_'
)
}
end
end
# Check if there is at least one FDW connection configured
#
# @return [Boolean] whether any FDW connection exists
def
self
.
connection_exist?
::
Geo
::
TrackingBase
.
connection
.
execute
(
"SELECT 1 FROM pg_foreign_server"
).
count
.
positive?
end
private
# Number of existing tables
#
# @return [Integer] number of tables
def
self
.
count_tables
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_count_tables
)
do
sql
=
<<~
SQL
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '
#{
FDW_SCHEMA
}
'
AND table_type = 'FOREIGN TABLE'
AND table_name NOT LIKE 'pg_%'
SQL
def
fdw_capable?
has_foreign_schema?
&&
connection_exist?
&&
count_tables
.
positive?
end
def
has_foreign_schema?
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_schema_exist
)
do
sql
=
<<~
SQL
SELECT 1
FROM information_schema.schemata
WHERE schema_name='
#{
FDW_SCHEMA
}
'
SQL
::
Geo
::
TrackingBase
.
connection
.
execute
(
sql
).
first
.
fetch
(
'count'
).
to_i
::
Geo
::
TrackingBase
.
connection
.
execute
(
sql
).
count
.
positive?
end
end
# Check if there is at least one FDW connection configured
#
# @return [Boolean] whether any FDW connection exists
def
connection_exist?
::
Geo
::
TrackingBase
.
connection
.
execute
(
"SELECT 1 FROM pg_foreign_server"
).
count
.
positive?
end
end
# Check if foreign schema has exact the same tables and fields defined on secondary database
#
# @return [Boolean] whether schemas match and are not empty
def
self
.
foreign_schema_tables_match?
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_schema_tables_match
)
do
schema
=
gitlab_schema
# Check if foreign schema has exact the same tables and fields defined on secondary database
#
# @return [Boolean] whether schemas match and are not empty
def
foreign_schema_tables_match?
Gitlab
::
Geo
.
cache_value
(
:geo_fdw_schema_tables_match
)
do
schema
=
gitlab_schema
schema
.
present?
&&
(
schema
.
to_set
==
fdw_schema
.
to_set
)
schema
.
present?
&&
(
schema
.
to_set
==
fdw_schema
.
to_set
)
end
end
end
def
self
.
count_tables_match?
gitlab_tables
.
count
==
count_tables
end
def
gitlab_schema
retrieve_schema_tables
(
ActiveRecord
::
Base
,
ActiveRecord
::
Base
.
connection_config
[
:database
],
DEFAULT_SCHEMA
).
to_a
end
def
self
.
gitlab_tables
ActiveRecord
::
Schema
.
tables
.
reject
{
|
table
|
table
.
start_with?
(
'pg_'
)
}
end
def
fdw_schema
retrieve_schema_tables
(
::
Geo
::
TrackingBase
,
Rails
.
configuration
.
geo_database
[
'database'
],
FDW_SCHEMA
).
to_a
end
def
self
.
gitlab_schema
retrieve_schema_tables
(
ActiveRecord
::
Base
,
ActiveRecord
::
Base
.
connection_config
[
:database
],
DEFAULT_SCHEMA
).
to_a
end
def
retrieve_schema_tables
(
adapter
,
database
,
schema
)
sql
=
<<~
SQL
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_catalog = '
#{
database
}
'
AND table_schema = '
#{
schema
}
'
AND table_name NOT LIKE 'pg_%'
ORDER BY table_name, column_name, data_type
SQL
def
self
.
fdw_schema
retrieve_schema_tables
(
::
Geo
::
TrackingBase
,
Rails
.
configuration
.
geo_database
[
'database'
],
FDW_SCHEMA
).
to_a
adapter
.
connection
.
select_all
(
sql
)
end
end
def
self
.
retrieve_schema_tables
(
adapter
,
database
,
schema
)
sql
=
<<~
SQL
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_catalog = '
#{
database
}
'
AND table_schema = '
#{
schema
}
'
AND table_name NOT LIKE 'pg_%'
ORDER BY table_name, column_name, data_type
SQL
adapter
.
connection
.
select_all
(
sql
)
end
private_class_method
:retrieve_schema_tables
end
end
end
ee/spec/lib/gitlab/geo/fdw_spec.rb
View file @
ee4a5f3c
...
...
@@ -22,7 +22,7 @@ describe Gitlab::Geo::Fdw, :geo do
expect
(
described_class
.
enabled?
).
to
be_truthy
end
it
'returns false if
configur
ed in `config/database_geo.yml`'
do
it
'returns false if
disabl
ed in `config/database_geo.yml`'
do
allow
(
Rails
.
configuration
).
to
receive
(
:geo_database
).
and_return
(
'fdw'
=>
false
)
expect
(
described_class
.
enabled?
).
to
be_falsey
...
...
@@ -38,67 +38,14 @@ describe Gitlab::Geo::Fdw, :geo do
describe
'.gitlab_tables'
do
it
'excludes pg_ tables'
do
tables
=
described_class
.
gitlab_tables
ActiveRecord
::
Base
.
connection
.
create_table
(
:pg_gitlab_test
)
expect
(
described_class
.
gitlab_tables
).
to
eq
(
tables
)
expect
(
described_class
.
gitlab_tables
).
not_to
include
(
'pg_gitlab_test'
)
ActiveRecord
::
Base
.
connection
.
drop_table
(
:pg_gitlab_test
)
end
end
describe
'fdw_capable?'
do
context
'with mocked FDW environment'
do
it
'returns true when PostgreSQL FDW is enabled'
do
expect
(
described_class
).
to
receive
(
:has_foreign_schema?
).
and_return
(
true
)
expect
(
described_class
).
to
receive
(
:count_tables
).
and_return
(
1
)
expect
(
described_class
.
fdw_capable?
).
to
be_truthy
end
it
'returns false when PostgreSQL FDW is not enabled'
do
expect
(
described_class
).
to
receive
(
:has_foreign_schema?
).
and_return
(
false
)
expect
(
described_class
.
fdw_capable?
).
to
be_falsey
end
it
'returns false when PostgreSQL FDW is enabled but remote tables are empty'
do
expect
(
described_class
).
to
receive
(
:has_foreign_schema?
).
and_return
(
true
)
expect
(
described_class
).
to
receive
(
:count_tables
).
and_return
(
0
)
expect
(
described_class
.
fdw_capable?
).
to
be_falsey
end
it
'returns false when PostgreSQL FDW is enabled but no remote connection is defined'
do
expect
(
described_class
).
to
receive
(
:has_foreign_schema?
).
and_return
(
true
)
expect
(
described_class
).
to
receive
(
:connection_exist?
).
and_return
(
false
)
expect
(
described_class
.
fdw_capable?
).
to
be_falsey
end
end
context
'with functional FDW environment'
do
it
'returns true'
do
expect
(
described_class
.
fdw_capable?
).
to
be_truthy
end
context
'with a pg_ table'
do
before
do
ActiveRecord
::
Base
.
connection
.
create_table
(
:pg_gitlab_test
)
end
after
do
ActiveRecord
::
Base
.
connection
.
drop_table
(
:pg_gitlab_test
)
end
it
'returns true'
do
expect
(
described_class
.
fdw_capable?
).
to
be_truthy
end
end
end
end
describe
'fdw_up_to_date?'
do
context
'with mocked FDW environment'
do
it
'returns true when FDW is enabled and foreign schema has same tables as secondary database'
do
...
...
@@ -129,18 +76,6 @@ describe Gitlab::Geo::Fdw, :geo do
end
end
describe
'has_foreign_schema?'
do
context
'with functional FDW environment'
do
it
'returns true'
do
# When testing it locally, make sure you have FDW set up correctly.
# If you are using GDK, you can run, from GDK root folder:
#
# make postgresql/geo-fdw/test
expect
(
described_class
.
has_foreign_schema?
).
to
be_truthy
end
end
end
describe
'count_tables'
do
context
'with functional FDW environment'
do
it
'returns same amount as defined in schema migration'
do
...
...
@@ -151,40 +86,4 @@ describe Gitlab::Geo::Fdw, :geo do
end
end
end
describe
'connection_exist?'
do
context
'with functional FDW environment'
do
it
'returns true'
do
# When testing it locally, make sure you have FDW set up correctly.
# If you are using GDK, you can run, from GDK root folder:
#
# make postgresql/geo-fdw/test
expect
(
described_class
.
connection_exist?
).
to
be_truthy
end
end
end
describe
'foreign_schema_tables_match?'
do
context
'with functional FDW environment'
do
it
'returns true'
do
# When testing it locally, you may need to refresh FDW with:
#
# rake geo:db:test:refresh_foreign_tables
expect
(
described_class
.
foreign_schema_tables_match?
).
to
be_truthy
end
it
'returns true if order is different'
do
one_schema
=
[
{
"table_name"
=>
"events"
,
"column_name"
=>
"target_type"
,
"data_type"
=>
"character varying"
},
{
"table_name"
=>
"ci_job_artifacts"
,
"column_name"
=>
"id"
,
"data_type"
=>
"integer"
}
]
second_schema
=
one_schema
.
reverse
allow
(
described_class
).
to
receive
(
:gitlab_schema
).
and_return
(
one_schema
)
allow
(
described_class
).
to
receive
(
:fdw_schema
).
and_return
(
second_schema
)
expect
(
described_class
.
foreign_schema_tables_match?
).
to
be_truthy
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment