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
0
Merge Requests
0
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
Léo-Paul Géneau
gitlab-ce
Commits
d07addbf
Commit
d07addbf
authored
Feb 05, 2018
by
Andreas Brandl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add foreign keys to todos table.
Fixes #32282.
parent
2fe09e6a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
115 additions
and
4 deletions
+115
-4
app/models/note.rb
app/models/note.rb
+1
-1
app/models/user.rb
app/models/user.rb
+1
-1
changelogs/unreleased/32282-add-foreign-keys-to-todos.yml
changelogs/unreleased/32282-add-foreign-keys-to-todos.yml
+5
-0
db/migrate/20180201110056_add_foreign_keys_to_todos.rb
db/migrate/20180201110056_add_foreign_keys_to_todos.rb
+38
-0
db/schema.rb
db/schema.rb
+3
-0
spec/migrations/add_foreign_keys_to_todos_spec.rb
spec/migrations/add_foreign_keys_to_todos_spec.rb
+65
-0
spec/models/note_spec.rb
spec/models/note_spec.rb
+1
-1
spec/models/user_spec.rb
spec/models/user_spec.rb
+1
-1
No files found.
app/models/note.rb
View file @
d07addbf
...
@@ -60,7 +60,7 @@ class Note < ActiveRecord::Base
...
@@ -60,7 +60,7 @@ class Note < ActiveRecord::Base
belongs_to
:updated_by
,
class_name:
"User"
belongs_to
:updated_by
,
class_name:
"User"
belongs_to
:last_edited_by
,
class_name:
'User'
belongs_to
:last_edited_by
,
class_name:
'User'
has_many
:todos
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:todos
has_many
:events
,
as: :target
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:events
,
as: :target
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_one
:system_note_metadata
has_one
:system_note_metadata
...
...
app/models/user.rb
View file @
d07addbf
...
@@ -125,7 +125,7 @@ class User < ActiveRecord::Base
...
@@ -125,7 +125,7 @@ class User < ActiveRecord::Base
has_many
:spam_logs
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:spam_logs
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:builds
,
dependent: :nullify
,
class_name:
'Ci::Build'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:builds
,
dependent: :nullify
,
class_name:
'Ci::Build'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:pipelines
,
dependent: :nullify
,
class_name:
'Ci::Pipeline'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:pipelines
,
dependent: :nullify
,
class_name:
'Ci::Pipeline'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:todos
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:todos
has_many
:notification_settings
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:notification_settings
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:award_emoji
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:award_emoji
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:triggers
,
dependent: :destroy
,
class_name:
'Ci::Trigger'
,
foreign_key: :owner_id
# rubocop:disable Cop/ActiveRecordDependent
has_many
:triggers
,
dependent: :destroy
,
class_name:
'Ci::Trigger'
,
foreign_key: :owner_id
# rubocop:disable Cop/ActiveRecordDependent
...
...
changelogs/unreleased/32282-add-foreign-keys-to-todos.yml
0 → 100644
View file @
d07addbf
---
title
:
Add foreign key constraints to todos table.
merge_request
:
16849
author
:
type
:
other
db/migrate/20180201110056_add_foreign_keys_to_todos.rb
0 → 100644
View file @
d07addbf
class
AddForeignKeysToTodos
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
class
Todo
<
ActiveRecord
::
Base
self
.
table_name
=
'todos'
include
EachBatch
end
BATCH_SIZE
=
1000
DOWNTIME
=
false
disable_ddl_transaction!
def
up
Todo
.
where
(
'NOT EXISTS ( SELECT true FROM users WHERE id=todos.user_id )'
).
each_batch
(
of:
BATCH_SIZE
)
do
|
batch
|
batch
.
delete_all
end
Todo
.
where
(
'NOT EXISTS ( SELECT true FROM users WHERE id=todos.author_id )'
).
each_batch
(
of:
BATCH_SIZE
)
do
|
batch
|
batch
.
delete_all
end
Todo
.
where
(
'note_id IS NOT NULL AND NOT EXISTS ( SELECT true FROM notes WHERE id=todos.note_id )'
).
each_batch
(
of:
BATCH_SIZE
)
do
|
batch
|
batch
.
delete_all
end
add_concurrent_foreign_key
:todos
,
:users
,
column: :user_id
,
on_delete: :cascade
add_concurrent_foreign_key
:todos
,
:users
,
column: :author_id
,
on_delete: :cascade
add_concurrent_foreign_key
:todos
,
:notes
,
column: :note_id
,
on_delete: :cascade
end
def
down
remove_foreign_key
:todos
,
:users
remove_foreign_key
:todos
,
column: :author_id
remove_foreign_key
:todos
,
:notes
end
end
db/schema.rb
View file @
d07addbf
...
@@ -2045,7 +2045,10 @@ ActiveRecord::Schema.define(version: 20180202111106) do
...
@@ -2045,7 +2045,10 @@ ActiveRecord::Schema.define(version: 20180202111106) do
add_foreign_key
"system_note_metadata"
,
"notes"
,
name:
"fk_d83a918cb1"
,
on_delete: :cascade
add_foreign_key
"system_note_metadata"
,
"notes"
,
name:
"fk_d83a918cb1"
,
on_delete: :cascade
add_foreign_key
"timelogs"
,
"issues"
,
name:
"fk_timelogs_issues_issue_id"
,
on_delete: :cascade
add_foreign_key
"timelogs"
,
"issues"
,
name:
"fk_timelogs_issues_issue_id"
,
on_delete: :cascade
add_foreign_key
"timelogs"
,
"merge_requests"
,
name:
"fk_timelogs_merge_requests_merge_request_id"
,
on_delete: :cascade
add_foreign_key
"timelogs"
,
"merge_requests"
,
name:
"fk_timelogs_merge_requests_merge_request_id"
,
on_delete: :cascade
add_foreign_key
"todos"
,
"notes"
,
name:
"fk_91d1f47b13"
,
on_delete: :cascade
add_foreign_key
"todos"
,
"projects"
,
name:
"fk_45054f9c45"
,
on_delete: :cascade
add_foreign_key
"todos"
,
"projects"
,
name:
"fk_45054f9c45"
,
on_delete: :cascade
add_foreign_key
"todos"
,
"users"
,
column:
"author_id"
,
name:
"fk_ccf0373936"
,
on_delete: :cascade
add_foreign_key
"todos"
,
"users"
,
name:
"fk_d94154aa95"
,
on_delete: :cascade
add_foreign_key
"trending_projects"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"trending_projects"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"u2f_registrations"
,
"users"
add_foreign_key
"u2f_registrations"
,
"users"
add_foreign_key
"user_callouts"
,
"users"
,
on_delete: :cascade
add_foreign_key
"user_callouts"
,
"users"
,
on_delete: :cascade
...
...
spec/migrations/add_foreign_keys_to_todos_spec.rb
0 → 100644
View file @
d07addbf
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'migrate'
,
'20180201110056_add_foreign_keys_to_todos.rb'
)
describe
AddForeignKeysToTodos
,
:migration
do
let
(
:todos
)
{
table
(
:todos
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
context
'add foreign key on user_id'
do
let!
(
:todo_with_user
)
{
create_todo
(
user_id:
user
.
id
)
}
let!
(
:todo_without_user
)
{
create_todo
(
user_id:
4711
)
}
it
'removes orphaned todos without corresponding user'
do
expect
{
migrate!
}.
to
change
{
Todo
.
count
}.
from
(
2
).
to
(
1
)
end
it
'does not remove entries with valid user_id'
do
expect
{
migrate!
}.
not_to
change
{
todo_with_user
.
reload
}
end
end
context
'add foreign key on author_id'
do
let!
(
:todo_with_author
)
{
create_todo
(
author_id:
user
.
id
)
}
let!
(
:todo_with_invalid_author
)
{
create_todo
(
author_id:
4711
)
}
it
'removes orphaned todos by author_id'
do
expect
{
migrate!
}.
to
change
{
Todo
.
count
}.
from
(
2
).
to
(
1
)
end
it
'does not touch author_id for valid entries'
do
expect
{
migrate!
}.
not_to
change
{
todo_with_author
.
reload
}
end
end
context
'add foreign key on note_id'
do
let
(
:note
)
{
create
(
:note
)
}
let!
(
:todo_with_note
)
{
create_todo
(
note_id:
note
.
id
)
}
let!
(
:todo_with_invalid_note
)
{
create_todo
(
note_id:
4711
)
}
let!
(
:todo_without_note
)
{
create_todo
(
note_id:
nil
)
}
it
'deletes todo if note_id is set but does not exist in notes table'
do
expect
{
migrate!
}.
to
change
{
Todo
.
count
}.
from
(
3
).
to
(
2
)
end
it
'does not touch entry if note_id is nil'
do
expect
{
migrate!
}.
not_to
change
{
todo_without_note
.
reload
}
end
it
'does not touch note_id for valid entries'
do
expect
{
migrate!
}.
not_to
change
{
todo_with_note
.
reload
}
end
end
def
create_todo
(
**
opts
)
todos
.
create!
(
project_id:
project
.
id
,
user_id:
user
.
id
,
author_id:
user
.
id
,
target_type:
''
,
action:
0
,
state:
''
,
**
opts
)
end
end
spec/models/note_spec.rb
View file @
d07addbf
...
@@ -8,7 +8,7 @@ describe Note do
...
@@ -8,7 +8,7 @@ describe Note do
it
{
is_expected
.
to
belong_to
(
:noteable
).
touch
(
false
)
}
it
{
is_expected
.
to
belong_to
(
:noteable
).
touch
(
false
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
have_many
(
:todos
)
.
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:todos
)
}
end
end
describe
'modules'
do
describe
'modules'
do
...
...
spec/models/user_spec.rb
View file @
d07addbf
...
@@ -33,7 +33,7 @@ describe User do
...
@@ -33,7 +33,7 @@ describe User do
it
{
is_expected
.
to
have_many
(
:merge_requests
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:merge_requests
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:identities
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:identities
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:spam_logs
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:spam_logs
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:todos
)
.
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:todos
)
}
it
{
is_expected
.
to
have_many
(
:award_emoji
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:award_emoji
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:triggers
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:triggers
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:builds
).
dependent
(
:nullify
)
}
it
{
is_expected
.
to
have_many
(
:builds
).
dependent
(
:nullify
)
}
...
...
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