New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix & Refactor BackendAPI scopes: orphans & not_used_by #1450
Conversation
c7d55b2
to
a29cdbf
Compare
Codecov Report
@@ Coverage Diff @@
## master #1450 +/- ##
===========================================
- Coverage 91.71% 77.27% -14.45%
===========================================
Files 2310 1054 -1256
Lines 75215 32293 -42922
===========================================
- Hits 68983 24953 -44030
- Misses 6232 7340 +1108
Continue to review full report at Codecov.
|
5a1e532
to
644a829
Compare
d9f2ffd
to
8651319
Compare
fe8a2cb
to
3637b32
Compare
3637b32
to
3ed1b2e
Compare
- Use not_exists instead of not_in for the possible null values. - Do it through BabySqueel and unscoping the order in the subquery to make it work in Oracle. - Test .orphans with disable_transactional_fixtures! to not have null values like in the real execution.
3ed1b2e
to
a4e71ca
Compare
scope :not_used_by, ->(service_id) { | ||
# TODO: Baby Squeel | ||
# It should be: | ||
# where.has do | ||
# not_exists BackendApiConfig.by_service(service_id).by_backend_api(BabySqueel[:backend_apis].id).select(:id) | ||
# end | ||
# And that works for MySQL and Postgres but not Oracle | ||
sql_query = <<~SQL | ||
( | ||
NOT EXISTS ( | ||
SELECT id | ||
FROM backend_api_configs | ||
WHERE service_id = ? AND backend_api_configs.backend_api_id = backend_apis.id | ||
) | ||
where.has do | ||
not_exists( | ||
BackendApiConfig.except(:order).select(:id) | ||
.by_service(service_id) | ||
.by_backend_api(BabySqueel[:backend_apis].id) | ||
) | ||
SQL | ||
where(sql_query, service_id) | ||
end | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What generates for Oracle now for BackendApi.not_used_by(service.id).explain
:
SELECT "BACKEND_APIS".*
FROM "BACKEND_APIS"
WHERE (
NOT EXISTS(
SELECT "BACKEND_API_CONFIGS"."ID"
FROM "BACKEND_API_CONFIGS"
WHERE "BACKEND_API_CONFIGS"."SERVICE_ID" = theServiceID
AND "BACKEND_API_CONFIGS"."BACKEND_API_ID" = "BACKEND_APIS"."ID"
)
)
scope :orphans, -> { where.has { id.not_in(BackendApiConfig.selecting { :backend_api_id }) } } | ||
scope :orphans, -> { | ||
where.has do | ||
not_exists(BackendApiConfig.except(:order).by_backend_api(BabySqueel[:backend_apis].id).select(:id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should improve efficiency a lot! Well done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!!
馃挴 good work 馃挭
scope :orphans, -> { | ||
where.has do | ||
not_exists(BackendApiConfig.except(:order).by_backend_api(BabySqueel[:backend_apis].id).select(:id)) | ||
end | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1st commit
This comment is not true anymore. Now it is tested in the place where one would expect:
test/unit/fields/fields_test.rb
test/unit/account/fields_test.rb
test/unit/extra_fields_test.rb
Each testing individually what it should.
It is unrelated to the rest of the PR but it is just removing an outdated pretty irrelevant comment and removing it was committed originally just to check if circleci was working properly back then 馃槃
The rest
Makes
lib/tasks/backend_api.rake
more efficient by fetching the account in the same query and selecting only the necessary fields.Closes THREESCALE-3966
Closes THREESCALE-3554
Fixes this random failure.
The reason is in
BackendApiConfigs
at that moment it fails there is stored something like this:What this line is actually doing in that case is:
I don't know what provokes the table to have records with null values occasionally in the CircleCI tests, but that shouldn't be possible.
I hope the reason is just that the test is missing
disable_transactional_fixtures!
anyway, using NOT IN operator with null values is asking for problems.
And doing
not exists
instead fixes it, except for Oracle without doing anything else because BabySqueel does not convert well the not_exists to SQL for Oracle. It can be done using bare SQL for the not_exists as we are doing for BackendApi.not_used_by, but we did that because it was urgent back then but it is a bad idea and we should fix the BabySqueel conversion to SQL of not_exists.Now I discovered that the problem is just that it attempts to add an 'order by' in the subquery by default but in a weird format that it makes it crash (the error is
ORA-00907 missing right parenthesis: SELECT * FROM (SELECT "BACKEND_APIS".* FROM "BACKEND_APIS" WHERE (NOT EXISTS(SELECT "BACKEND_API_CONFIGS".* FROM "BACKEND_API_CONFIGS" WHERE "BACKEND_API_CONFIGS"."BACKEND_API_ID" = "BACKEND_APIS"."ID" ORDER BY "BACKEND_API_CONFIGS"."ID" ASC)) ORDER BY "BACKEND_APIS"."ID" ASC ) WHERE ROWNUM <= 1000
), and we do not even need the 'order' at all, so I unscoped the order for the subquery and it works this way.