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
50eb9786
Commit
50eb9786
authored
Dec 01, 2021
by
Adam Hegyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix LFK foreign key definition
parent
f5fbcdac
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
47 additions
and
45 deletions
+47
-45
app/services/loose_foreign_keys/cleaner_service.rb
app/services/loose_foreign_keys/cleaner_service.rb
+4
-4
doc/development/database/loose_foreign_keys.md
doc/development/database/loose_foreign_keys.md
+8
-8
lib/gitlab/database/gitlab_loose_foreign_keys.yml
lib/gitlab/database/gitlab_loose_foreign_keys.yml
+10
-9
lib/gitlab/database/loose_foreign_keys.rb
lib/gitlab/database/loose_foreign_keys.rb
+7
-7
spec/db/schema_spec.rb
spec/db/schema_spec.rb
+4
-3
spec/lib/gitlab/database/loose_foreign_keys_spec.rb
spec/lib/gitlab/database/loose_foreign_keys_spec.rb
+7
-7
spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb
...services/loose_foreign_keys/batch_cleaner_service_spec.rb
+2
-2
spec/services/loose_foreign_keys/cleaner_service_spec.rb
spec/services/loose_foreign_keys/cleaner_service_spec.rb
+2
-2
spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
+3
-3
No files found.
app/services/loose_foreign_keys/cleaner_service.rb
View file @
50eb9786
...
...
@@ -16,7 +16,7 @@ module LooseForeignKeys
def
execute
result
=
connection
.
execute
(
build_query
)
{
affected_rows:
result
.
cmd_tuples
,
table:
loose_foreign_key_definition
.
to
_table
}
{
affected_rows:
result
.
cmd_tuples
,
table:
loose_foreign_key_definition
.
from
_table
}
end
def
async_delete?
...
...
@@ -48,15 +48,15 @@ module LooseForeignKeys
end
def
arel_table
@arel_table
||=
Arel
::
Table
.
new
(
loose_foreign_key_definition
.
to
_table
)
@arel_table
||=
Arel
::
Table
.
new
(
loose_foreign_key_definition
.
from
_table
)
end
def
primary_keys
@primary_keys
||=
connection
.
primary_keys
(
loose_foreign_key_definition
.
to
_table
).
map
{
|
key
|
arel_table
[
key
]
}
@primary_keys
||=
connection
.
primary_keys
(
loose_foreign_key_definition
.
from
_table
).
map
{
|
key
|
arel_table
[
key
]
}
end
def
quoted_table_name
@quoted_table_name
||=
Arel
.
sql
(
connection
.
quote_table_name
(
loose_foreign_key_definition
.
to
_table
))
@quoted_table_name
||=
Arel
.
sql
(
connection
.
quote_table_name
(
loose_foreign_key_definition
.
from
_table
))
end
def
delete_query
...
...
doc/development/database/loose_foreign_keys.md
View file @
50eb9786
...
...
@@ -62,28 +62,28 @@ following information:
-
The data cleanup method (
`async_delete`
or
`async_nullify`
)
The YAML file is located at
`lib/gitlab/database/gitlab_loose_foreign_keys.yml`
. The file groups
foreign key definitions by the name of the
parent table. The parent
table can have multiple loose
foreign key definitions by the name of the
child table. The child
table can have multiple loose
foreign key definitions, therefore we store them as an array.
Example definition:
```
yaml
project
s
:
-
t
o_table
:
ci_pipeline
s
ci_pipeline
s
:
-
t
able
:
project
s
column
:
project_id
on_delete
:
async_delete
```
If the
`
project
s`
key is already present in the YAML file, then a new entry can be added
If the
`
ci_pipeline
s`
key is already present in the YAML file, then a new entry can be added
to the array:
```
yaml
project
s
:
-
t
o_table
:
ci_pipeline
s
ci_pipeline
s
:
-
t
able
:
project
s
column
:
project_id
on_delete
:
async_delete
-
t
o_t
able
:
another_table
column
:
project
_id
-
table
:
another_table
column
:
another
_id
on_delete
:
:async_nullify
```
...
...
lib/gitlab/database/gitlab_loose_foreign_keys.yml
View file @
50eb9786
c
hat_names
:
-
t
o_table
:
ci_pipeline_chat_data
c
i_pipeline_chat_data
:
-
t
able
:
chat_names
column
:
chat_name_id
on_delete
:
async_delete
ci
_builds
:
-
t
o_table
:
dast_site_profiles
_builds
dast_scanner_profiles
_builds
:
-
t
able
:
ci
_builds
column
:
ci_build_id
on_delete
:
async_delete
-
to_table
:
dast_scanner_profiles_builds
dast_scanner_profiles_builds
:
-
table
:
ci_builds
column
:
ci_build_id
on_delete
:
async_delete
ci
_pipelines
:
-
t
o_table
:
dast_profiles
_pipelines
dast_profiles
_pipelines
:
-
t
able
:
ci
_pipelines
column
:
ci_pipeline_id
on_delete
:
async_delete
c
i
_runners
:
-
t
o_table
:
clusters_applications
_runners
c
lusters_applications
_runners
:
-
t
able
:
ci
_runners
column
:
runner_id
on_delete
:
async_nullify
lib/gitlab/database/loose_foreign_keys.rb
View file @
50eb9786
...
...
@@ -4,25 +4,25 @@ module Gitlab
module
Database
module
LooseForeignKeys
def
self
.
definitions_by_table
@definitions_by_table
||=
definitions
.
group_by
(
&
:
from
_table
).
with_indifferent_access
.
freeze
@definitions_by_table
||=
definitions
.
group_by
(
&
:
to
_table
).
with_indifferent_access
.
freeze
end
def
self
.
definitions
@definitions
||=
loose_foreign_keys_yaml
.
flat_map
do
|
parent
_table_name
,
configs
|
configs
.
map
{
|
config
|
build_definition
(
parent
_table_name
,
config
)
}
@definitions
||=
loose_foreign_keys_yaml
.
flat_map
do
|
child
_table_name
,
configs
|
configs
.
map
{
|
config
|
build_definition
(
child
_table_name
,
config
)
}
end
.
freeze
end
def
self
.
build_definition
(
parent
_table_name
,
config
)
to_table
=
config
.
fetch
(
'to_
table'
)
def
self
.
build_definition
(
child
_table_name
,
config
)
parent_table_name
=
config
.
fetch
(
'
table'
)
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
child_table_name
,
parent_table_name
,
to_table
,
{
column:
config
.
fetch
(
'column'
),
on_delete:
config
.
fetch
(
'on_delete'
).
to_sym
,
gitlab_schema:
GitlabSchema
.
table_schema
(
to_tabl
e
)
gitlab_schema:
GitlabSchema
.
table_schema
(
child_table_nam
e
)
}
)
end
...
...
spec/db/schema_spec.rb
View file @
50eb9786
...
...
@@ -29,7 +29,6 @@ RSpec.describe 'Database schema' do
ci_builds:
%w[erased_by_id runner_id trigger_request_id user_id]
,
ci_namespace_monthly_usages:
%w[namespace_id]
,
ci_pipelines:
%w[user_id]
,
ci_pipeline_chat_data:
%w[chat_name_id]
,
# it uses the loose foreign key featue
ci_runner_projects:
%w[runner_id]
,
ci_trigger_requests:
%w[commit_id]
,
cluster_providers_aws:
%w[security_group_id vpc_id access_key_id]
,
...
...
@@ -102,6 +101,8 @@ RSpec.describe 'Database schema' do
let
(
:indexes
)
{
connection
.
indexes
(
table
)
}
let
(
:columns
)
{
connection
.
columns
(
table
)
}
let
(
:foreign_keys
)
{
connection
.
foreign_keys
(
table
)
}
let
(
:loose_foreign_keys
)
{
Gitlab
::
Database
::
LooseForeignKeys
.
definitions
.
group_by
(
&
:from_table
).
fetch
(
table
,
[])
}
let
(
:all_foreign_keys
)
{
foreign_keys
+
loose_foreign_keys
}
# take the first column in case we're using a composite primary key
let
(
:primary_key_column
)
{
Array
(
connection
.
primary_key
(
table
)).
first
}
...
...
@@ -114,7 +115,7 @@ RSpec.describe 'Database schema' do
columns
=
columns
.
split
(
','
)
if
columns
.
is_a?
(
String
)
columns
.
first
.
chomp
end
foreign_keys_columns
=
foreign_keys
.
map
(
&
:column
)
foreign_keys_columns
=
all_
foreign_keys
.
map
(
&
:column
)
# Add the primary key column to the list of indexed columns because
# postgres and mysql both automatically create an index on the primary
...
...
@@ -129,7 +130,7 @@ RSpec.describe 'Database schema' do
context
'columns ending with _id'
do
let
(
:column_names
)
{
columns
.
map
(
&
:name
)
}
let
(
:column_names_with_id
)
{
column_names
.
select
{
|
column_name
|
column_name
.
ends_with?
(
'_id'
)
}
}
let
(
:foreign_keys_columns
)
{
foreign_keys
.
map
(
&
:column
)
}
let
(
:foreign_keys_columns
)
{
all_foreign_keys
.
map
(
&
:column
).
uniq
}
# we can have FK and loose FK present at the same time
let
(
:ignored_columns
)
{
ignored_fk_columns
(
table
)
}
it
'do have the foreign keys'
do
...
...
spec/lib/gitlab/database/loose_foreign_keys_spec.rb
View file @
50eb9786
...
...
@@ -24,19 +24,19 @@ RSpec.describe Gitlab::Database::LooseForeignKeys do
Gitlab
::
Database
.
schemas_to_base_models
.
fetch
(
parent_table_schema
)
end
it
'all `
from
_table` tables are present'
do
it
'all `
to
_table` tables are present'
do
definitions
.
each
do
|
definition
|
base_models_for
(
definition
.
from
_table
).
each
do
|
model
|
expect
(
model
.
connection
).
to
be_table_exist
(
definition
.
from
_table
)
base_models_for
(
definition
.
to
_table
).
each
do
|
model
|
expect
(
model
.
connection
).
to
be_table_exist
(
definition
.
to
_table
)
end
end
end
it
'all `
to
_table` tables are present'
do
it
'all `
from
_table` tables are present'
do
definitions
.
each
do
|
definition
|
base_models_for
(
definition
.
to
_table
).
each
do
|
model
|
expect
(
model
.
connection
).
to
be_table_exist
(
definition
.
to
_table
)
expect
(
model
.
connection
).
to
be_column_exist
(
definition
.
to
_table
,
definition
.
column
)
base_models_for
(
definition
.
from
_table
).
each
do
|
model
|
expect
(
model
.
connection
).
to
be_table_exist
(
definition
.
from
_table
)
expect
(
model
.
connection
).
to
be_column_exist
(
definition
.
from
_table
,
definition
.
column
)
end
end
end
...
...
spec/services/loose_foreign_keys/batch_cleaner_service_spec.rb
View file @
50eb9786
...
...
@@ -24,8 +24,8 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
let
(
:loose_foreign_key_definitions
)
do
[
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'_test_loose_fk_parent_table'
,
'_test_loose_fk_child_table_1'
,
'_test_loose_fk_parent_table'
,
{
column:
'parent_id'
,
on_delete: :async_delete
,
...
...
@@ -33,8 +33,8 @@ RSpec.describe LooseForeignKeys::BatchCleanerService do
}
),
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'_test_loose_fk_parent_table'
,
'_test_loose_fk_child_table_2'
,
'_test_loose_fk_parent_table'
,
{
column:
'parent_id_with_different_column'
,
on_delete: :async_nullify
,
...
...
spec/services/loose_foreign_keys/cleaner_service_spec.rb
View file @
50eb9786
...
...
@@ -13,8 +13,8 @@ RSpec.describe LooseForeignKeys::CleanerService do
let
(
:loose_fk_definition
)
do
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'projects'
,
'issues'
,
'projects'
,
{
column:
'project_id'
,
on_delete: :async_nullify
,
...
...
@@ -80,8 +80,8 @@ RSpec.describe LooseForeignKeys::CleanerService do
let
(
:loose_fk_definition
)
do
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'users'
,
'project_authorizations'
,
'users'
,
{
column:
'user_id'
,
on_delete: :async_delete
,
...
...
spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
View file @
50eb9786
...
...
@@ -31,8 +31,8 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
{
'_test_loose_fk_parent_table_1'
=>
[
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'_test_loose_fk_parent_table_1'
,
'_test_loose_fk_child_table_1_1'
,
'_test_loose_fk_parent_table_1'
,
{
column:
'parent_id'
,
on_delete: :async_delete
,
...
...
@@ -40,8 +40,8 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
}
),
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'_test_loose_fk_parent_table_1'
,
'_test_loose_fk_child_table_1_2'
,
'_test_loose_fk_parent_table_1'
,
{
column:
'parent_id_with_different_column'
,
on_delete: :async_nullify
,
...
...
@@ -51,8 +51,8 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
],
'_test_loose_fk_parent_table_2'
=>
[
ActiveRecord
::
ConnectionAdapters
::
ForeignKeyDefinition
.
new
(
'_test_loose_fk_parent_table_2'
,
'_test_loose_fk_child_table_2_1'
,
'_test_loose_fk_parent_table_2'
,
{
column:
'parent_id'
,
on_delete: :async_delete
,
...
...
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