-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CHE-4372; add unique constraing for factory name + user #4521
Changes from 4 commits
580a0f4
4087afa
2944199
9cc84e9
a13ee62
86c457b
fe24361
03702cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012-2017 Codenvy, S.A. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Codenvy, S.A. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.che.api.factory.server; | ||
|
||
import org.eclipse.che.api.factory.server.model.impl.AuthorImpl; | ||
import org.eclipse.che.api.factory.server.model.impl.FactoryImpl; | ||
import org.eclipse.che.api.factory.server.spi.FactoryDao; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.Captor; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.testng.MockitoTestNGListener; | ||
import org.testng.annotations.Listeners; | ||
import org.testng.annotations.Test; | ||
|
||
import static com.google.common.base.Strings.isNullOrEmpty; | ||
import static org.mockito.Matchers.eq; | ||
import static org.mockito.Mockito.verify; | ||
import static org.mockito.Mockito.when; | ||
import static org.testng.Assert.assertFalse; | ||
|
||
/** | ||
* @author Max Shaposhnik ([email protected]) on 3/20/17. | ||
*/ | ||
@Listeners(value = {MockitoTestNGListener.class}) | ||
public class FactoryManagerTest { | ||
|
||
@Mock | ||
private FactoryDao factoryDao; | ||
|
||
@InjectMocks | ||
private FactoryManager factoryManager; | ||
|
||
@Captor | ||
private ArgumentCaptor<FactoryImpl> factoryCaptor; | ||
|
||
@Test | ||
public void shouldGenerateNameOnFactoryCreation() throws Exception { | ||
final FactoryImpl factory = FactoryImpl.builder().generateId().build(); | ||
factoryManager.saveFactory(factory); | ||
verify(factoryDao).create(factoryCaptor.capture()); | ||
assertFalse(isNullOrEmpty(factoryCaptor.getValue().getName())); | ||
} | ||
|
||
@Test | ||
public void shouldGenerateNameOnFactoryUpdate() throws Exception { | ||
final AuthorImpl author = new AuthorImpl(); | ||
author.setCreated(1231241234L); | ||
author.setUserId("user123123"); | ||
final FactoryImpl factory = FactoryImpl.builder().generateId().setCreator(author).build(); | ||
when(factoryDao.getById(eq(factory.getId()))).thenReturn(factory); | ||
factoryManager.updateFactory(factory); | ||
verify(factoryDao).update(factoryCaptor.capture()); | ||
assertFalse(isNullOrEmpty(factoryCaptor.getValue().getName())); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
-- | ||
-- [2012] - [2017] Codenvy, S.A. | ||
-- All Rights Reserved. | ||
-- | ||
-- NOTICE: All information contained herein is, and remains | ||
-- the property of Codenvy S.A. and its suppliers, | ||
-- if any. The intellectual and technical concepts contained | ||
-- herein are proprietary to Codenvy S.A. | ||
-- and its suppliers and may be covered by U.S. and Foreign Patents, | ||
-- patents in process, and are protected by trade secret or copyright law. | ||
-- Dissemination of this information or reproduction of this material | ||
-- is strictly forbidden unless prior written permission is obtained | ||
-- from Codenvy S.A.. | ||
-- | ||
|
||
CREATE UNIQUE INDEX index_name_plus_userid ON che_factory (user_id, name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
-- | ||
-- [2012] - [2017] Codenvy, S.A. | ||
-- All Rights Reserved. | ||
-- | ||
-- NOTICE: All information contained herein is, and remains | ||
-- the property of Codenvy S.A. and its suppliers, | ||
-- if any. The intellectual and technical concepts contained | ||
-- herein are proprietary to Codenvy S.A. | ||
-- and its suppliers and may be covered by U.S. and Foreign Patents, | ||
-- patents in process, and are protected by trade secret or copyright law. | ||
-- Dissemination of this information or reproduction of this material | ||
-- is strictly forbidden unless prior written permission is obtained | ||
-- from Codenvy S.A.. | ||
-- | ||
|
||
UPDATE che_factory | ||
SET name = concat('f', right(id, 9)) WHERE name IS NULL OR name = ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Script name does not match the content |
||
|
||
WITH dupes AS | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we do this migration on codenvy tables before we move factory to che? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I can move naming uniques into 1.1 in codenvy, then 1.2 will do the migration, and costraint will be just in |
||
( SELECT id, user_id, name | ||
FROM che_factory | ||
WHERE (name,user_id) | ||
IN (SELECT name, user_id | ||
FROM che_factory | ||
GROUP BY name, user_id | ||
HAVING count(*) > 1) | ||
), | ||
uniques AS | ||
( WITH q as | ||
( SELECT *, row_number() | ||
OVER (PARTITION BY name,user_id ORDER BY name,user_id) | ||
AS rn FROM che_factory | ||
) | ||
SELECT id FROM q WHERE rn = 1 | ||
) | ||
UPDATE che_factory | ||
SET name = concat(che_factory.name, '-', right(dupes.id, 9)) | ||
FROM dupes, uniques | ||
WHERE dupes.id = che_factory.id AND NOT EXISTS (SELECT id FROM uniques WHERE che_factory.id = uniques.id); | ||
|
||
|
||
CREATE UNIQUE INDEX index_name_plus_userid ON che_factory (user_id, name); |
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.
It would be better not to generate new name when update doesn't contain it. Let's set old name when it is null or empty in update.
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.
In this case you cant re-assign the name to another factory. I don't know if it's good.
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.
Why you can't re-assign the name? You can send name in update then name will be updated. Or you can miss it, then old name will be used (but not generated new)
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.
For me it looks stupid, if you deleting the factory name on Dashb, and it returns back after update :). But seems others are with you, so ok.
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.
So seems it must not be generated on update at all.