Repository: yorkie-team/yorkie
Pull request #418 (2022-09-29 05:38:06)

Jeonjonghyeok fix/create project
<!--  Thanks for sending a pull request! -->

**What this PR does / why we need it**:

This follows up https://github.com/yorkie-team/yorkie/pull/406.

**Which issue(s) this PR fixes**:
<!--
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
Fixes #

**Special notes for your reviewer**:

**Does this PR introduce a user-facing change?**:
<!--
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note

```

**Additional documentation**:

<!--
This section can be blank if this pull request does not require a release note.

Please use the following format for linking documentation:
- [Usage]: <link>
- [Other doc]: <link>
-->
```docs

```

**Checklist**:
- [ ] Added relevant tests or not required
- [ ] Didn't break anything


codecov[bot]: # [Codecov](https://codecov.io/gh/yorkie-team/yorkie/pull/418?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) Report
> Merging [#418](https://codecov.io/gh/yorkie-team/yorkie/pull/418?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) (fe1e84f) into [main](https://codecov.io/gh/yorkie-team/yorkie/commit/47f050467f5e898d4623ed8ca78725556e086870?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) (47f0504) will **increase** coverage by `0.14%`.
> The diff coverage is `75.00%`.

> :exclamation: Current head fe1e84f differs from pull request most recent head 1a38cd9. Consider uploading reports for the commit 1a38cd9 to get more accurate results

```diff
@@            Coverage Diff             @@
##             main     #418      +/-   ##
==========================================
+ Coverage   46.82%   46.96%   +0.14%     
==========================================
  Files          71       71              
  Lines        5922     5919       -3     
==========================================
+ Hits         2773     2780       +7     
+ Misses       2846     2835      -11     
- Partials      303      304       +1     
```


| [Impacted Files](https://codecov.io/gh/yorkie-team/yorkie/pull/418?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) | Coverage Δ | |
|---|---|---|
| [api/types/create\_project\_fields.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-YXBpL3R5cGVzL2NyZWF0ZV9wcm9qZWN0X2ZpZWxkcy5nbw==) | `0.00% <ø> (ø)` | |
| [api/types/updatable\_project\_fields.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-YXBpL3R5cGVzL3VwZGF0YWJsZV9wcm9qZWN0X2ZpZWxkcy5nbw==) | `100.00% <ø> (ø)` | |
| [pkg/document/crdt/array.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L2NyZHQvYXJyYXkuZ28=) | `36.36% <0.00%> (ø)` | |
| [pkg/document/crdt/rga\_tree\_list.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L2NyZHQvcmdhX3RyZWVfbGlzdC5nbw==) | `64.46% <0.00%> (ø)` | |
| [pkg/document/crdt/rga\_tree\_split.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L2NyZHQvcmdhX3RyZWVfc3BsaXQuZ28=) | `73.75% <0.00%> (ø)` | |
| [pkg/document/crdt/rich\_text.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L2NyZHQvcmljaF90ZXh0Lmdv) | `60.67% <0.00%> (ø)` | |
| [pkg/document/crdt/text.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L2NyZHQvdGV4dC5nbw==) | `48.43% <0.00%> (ø)` | |
| [pkg/document/time/ticket.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL2RvY3VtZW50L3RpbWUvdGlja2V0Lmdv) | `89.18% <ø> (ø)` | |
| [server/backend/database/mongo/indexes.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-c2VydmVyL2JhY2tlbmQvZGF0YWJhc2UvbW9uZ28vaW5kZXhlcy5nbw==) | `50.00% <ø> (ø)` | |
| [pkg/splay/splay.go](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team#diff-cGtnL3NwbGF5L3NwbGF5Lmdv) | `77.08% <66.66%> (ø)` | |
| ... and [9 more](https://codecov.io/gh/yorkie-team/yorkie/pull/418/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=yorkie-team)


Patch:
diff --git a/server/backend/database/memory/database.go b/server/backend/database/memory/database.go
index 54dafe12..84130dd4 100644
--- a/server/backend/database/memory/database.go
+++ b/server/backend/database/memory/database.go
@@ -83,7 +83,7 @@ func (d *DB) FindProjectInfoByName(
 	txn := d.db.Txn(false)
 	defer txn.Abort()
 
-	raw, err := txn.First(tblProjects, "name", name)
+	raw, err := txn.First(tblProjects, "owner_name", owner.String(), name)
 	if err != nil {
 		return nil, err
 	}
@@ -92,9 +92,6 @@ func (d *DB) FindProjectInfoByName(
 	}
 
 	info := raw.(*database.ProjectInfo).DeepCopy()
-	if info.Owner != owner {
-		return nil, fmt.Errorf("%s: %w", name, database.ErrProjectNotFound)
-	}
 
 	return info, nil
 }
@@ -205,7 +202,7 @@ func (d *DB) CreateProjectInfo(
 
 	// NOTE(hackerwins): Check if the project already exists.
 	// https://github.com/hashicorp/go-memdb/issues/7#issuecomment-270427642
-	existing, err := txn.First(tblProjects, "name", name)
+	existing, err := txn.First(tblProjects, "owner_name", owner.String(), name)
 	if err != nil {
 		return nil, err
 	}
@@ -231,12 +228,11 @@ func (d *DB) ListProjectInfos(
 	txn := d.db.Txn(false)
 	defer txn.Abort()
 
-	defaultProjectID := database.DefaultProjectID
 	iter, err := txn.LowerBound(
 		tblProjects,
-		"owner_id",
+		"owner_name",
 		owner.String(),
-		defaultProjectID.String(),
+		"",
 	)
 	if err != nil {
 		return nil, err
@@ -279,7 +275,7 @@ func (d *DB) UpdateProjectInfo(
 	}
 
 	if fields.Name != nil {
-		existing, err := txn.First(tblProjects, "name", *fields.Name)
+		existing, err := txn.First(tblProjects, "owner_name", owner.String(), *fields.Name)
 		if err != nil {
 			return nil, err
 		}
diff --git a/server/backend/database/memory/indexes.go b/server/backend/database/memory/indexes.go
index 25f23d2b..e357a5f3 100644
--- a/server/backend/database/memory/indexes.go
+++ b/server/backend/database/memory/indexes.go
@@ -38,21 +38,16 @@ var schema = &memdb.DBSchema{
 					Unique:  true,
 					Indexer: &memdb.StringFieldIndex{Field: "ID"},
 				},
-				"owner_id": {
-					Name:   "owner_id",
+				"owner_name": {
+					Name:   "owner_name",
 					Unique: true,
 					Indexer: &memdb.CompoundIndex{
 						Indexes: []memdb.Indexer{
 							&memdb.StringFieldIndex{Field: "Owner"},
-							&memdb.StringFieldIndex{Field: "ID"},
+							&memdb.StringFieldIndex{Field: "Name"},
 						},
 					},
 				},
-				"name": {
-					Name:    "name",
-					Unique:  true,
-					Indexer: &memdb.StringFieldIndex{Field: "Name"},
-				},
 				"public_key": {
 					Name:    "public_key",
 					Unique:  true,
diff --git a/server/backend/database/mongo/indexes.go b/server/backend/database/mongo/indexes.go
index 95db66f3..d9821b50 100644
--- a/server/backend/database/mongo/indexes.go
+++ b/server/backend/database/mongo/indexes.go
@@ -44,7 +44,10 @@ var collectionInfos = []collectionInfo{
 	{
 		name: colProjects,
 		indexes: []mongo.IndexModel{{
-			Keys:    bsonx.Doc{{Key: "name", Value: bsonx.Int32(1)}},
+			Keys: bsonx.Doc{
+				{Key: "owner", Value: bsonx.Int32(1)},
+				{Key: "name", Value: bsonx.Int32(1)},
+			},
 			Options: options.Index().SetUnique(true),
 		}, {
 			Keys:    bsonx.Doc{{Key: "public_key", Value: bsonx.Int32(1)}},


Test patch:
diff --git a/server/backend/database/memory/database_test.go b/server/backend/database/memory/database_test.go
index fdd0cb63..c3904eea 100644
--- a/server/backend/database/memory/database_test.go
+++ b/server/backend/database/memory/database_test.go
@@ -75,18 +75,33 @@ func TestDB(t *testing.T) {
 	})
 
 	t.Run("project test", func(t *testing.T) {
-		_, err = db.CreateProjectInfo(ctx, t.Name(), otherOwnerID)
-		assert.NoError(t, err)
-
 		suffixes := []int{0, 1, 2}
 		for _, suffix := range suffixes {
 			_, err = db.CreateProjectInfo(ctx, fmt.Sprintf("%s-%d", t.Name(), suffix), dummyOwnerID)
 			assert.NoError(t, err)
 		}
 
+		_, err = db.CreateProjectInfo(ctx, t.Name(), otherOwnerID)
+		assert.NoError(t, err)
+
+		// Lists all projects that the dummyOwnerID is the owner.
 		projects, err := db.ListProjectInfos(ctx, dummyOwnerID)
 		assert.NoError(t, err)
 		assert.Len(t, projects, len(suffixes))
+
+		_, err = db.CreateProjectInfo(ctx, t.Name(), dummyOwnerID)
+		assert.NoError(t, err)
+
+		project, err := db.FindProjectInfoByName(ctx, dummyOwnerID, t.Name())
+		assert.NoError(t, err)
+		assert.Equal(t, project.Name, t.Name())
+
+		newName := fmt.Sprintf("%s-%d", t.Name(), 3)
+		fields := &types.UpdatableProjectFields{Name: &newName}
+		_, err = db.UpdateProjectInfo(ctx, dummyOwnerID, project.ID, fields)
+		assert.NoError(t, err)
+		_, err = db.FindProjectInfoByName(ctx, dummyOwnerID, newName)
+		assert.NoError(t, err)
 	})
 
 	t.Run("user test", func(t *testing.T) {
diff --git a/server/backend/database/mongo/client_test.go b/server/backend/database/mongo/client_test.go
index b7ea5f5c..7b8772c0 100644
--- a/server/backend/database/mongo/client_test.go
+++ b/server/backend/database/mongo/client_test.go
@@ -42,6 +42,7 @@ func TestClient(t *testing.T) {
 	assert.NoError(t, err)
 
 	dummyOwnerID := types.ID("000000000000000000000000")
+	otherOwnerID := types.ID("000000000000000000000001")
 
 	t.Run("UpdateProjectInfo test", func(t *testing.T) {
 		info, err := cli.CreateProjectInfo(ctx, t.Name(), dummyOwnerID)
@@ -102,4 +103,15 @@ func TestClient(t *testing.T) {
 		_, err = cli.UpdateProjectInfo(ctx, dummyOwnerID, id, fields)
 		assert.ErrorIs(t, err, database.ErrProjectNameAlreadyExists)
 	})
+
+	t.Run("FindProjectInfoByName test", func(t *testing.T) {
+		info1, err := cli.CreateProjectInfo(ctx, t.Name(), dummyOwnerID)
+		assert.NoError(t, err)
+		_, err = cli.CreateProjectInfo(ctx, t.Name(), otherOwnerID)
+		assert.NoError(t, err)
+
+		info2, err := cli.FindProjectInfoByName(ctx, dummyOwnerID, t.Name())
+		assert.NoError(t, err)
+		assert.Equal(t, info1.ID, info2.ID)
+	})
 }