Skip to content

Commit c24636a

Browse files
committed
add ChangeObserver
1 parent 42c13e0 commit c24636a

File tree

10 files changed

+120
-17
lines changed

10 files changed

+120
-17
lines changed

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## Versions
44

5+
### 1.9.1
6+
* database provider: runCommand added
7+
* database provider: addChangeObserver added
8+
* DAO changeObserver added
9+
* DAO stats (GridFSDAO fileStats, chunkStats) as case class added
10+
511
### 1.9.0
612

713
* ObservableIncludes changed method names for better understanding =>

src/main/scala/com/sfxcode/nosql/mongo/GridFSDAO.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.sfxcode.nosql.mongo
22

3-
import com.sfxcode.nosql.mongo.database.DatabaseProvider
3+
import com.sfxcode.nosql.mongo.database.{ ChangeObserver, CollectionStats, DatabaseProvider }
44
import com.sfxcode.nosql.mongo.gridfs.Metadata
55
import org.bson.types.ObjectId
66
import org.mongodb.scala.bson.conversions.Bson
@@ -13,12 +13,18 @@ abstract class GridFSDAO(provider: DatabaseProvider, bucketName: String) extends
1313
var bucket: GridFSBucket = {
1414
if (bucketName.contains(DatabaseProvider.CollectionSeparator)) {
1515
val newDatabaseName = bucketName.substring(0, bucketName.indexOf(DatabaseProvider.CollectionSeparator))
16-
val newBucketName = bucketName.substring(bucketName.indexOf(DatabaseProvider.CollectionSeparator) + 1)
16+
val newBucketName = bucketName.substring(bucketName.indexOf(DatabaseProvider.CollectionSeparator) + 1)
1717
GridFSBucket(provider.database(newDatabaseName), newBucketName)
1818
} else {
1919
GridFSBucket(provider.database(), bucketName)
2020
}
2121
}
22+
def addChangeObserver(observer: ChangeObserver[Document]): ChangeObserver[Document] =
23+
Files.addChangeObserver(observer: ChangeObserver[Document])
24+
25+
def fileStats: Observable[CollectionStats] = Files.stats
26+
27+
def chunkStats: Observable[CollectionStats] = Chunks.stats
2228

2329
protected def gridfsBucket: GridFSBucket = bucket
2430

src/main/scala/com/sfxcode/nosql/mongo/MongoDAO.scala

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,40 @@ package com.sfxcode.nosql.mongo
22

33
import java.nio.charset.Charset
44

5-
import better.files.{ File, Scanner }
5+
import better.files.File
66
import com.sfxcode.nosql.mongo.bson.DocumentHelper
7-
import com.sfxcode.nosql.mongo.database.DatabaseProvider
7+
import com.sfxcode.nosql.mongo.database.{ ChangeObserver, CollectionStats, DatabaseProvider }
88
import com.sfxcode.nosql.mongo.operation.Crud
99
import org.bson.json.JsonParseException
10-
import org.mongodb.scala.{ BulkWriteResult, Document, MongoCollection, SingleObservable }
10+
import org.mongodb.scala.{ BulkWriteResult, Document, MongoCollection, Observable, SingleObservable }
1111

1212
import scala.collection.mutable.ArrayBuffer
1313
import scala.reflect.ClassTag
1414

1515
/**
16-
* Created by tom on 20.01.17.
17-
*/
16+
* Created by tom on 20.01.17.
17+
*/
1818
abstract class MongoDAO[A](provider: DatabaseProvider, collectionName: String)(implicit ct: ClassTag[A])
19-
extends Crud[A] {
19+
extends Crud[A] {
2020

2121
val collection: MongoCollection[A] = {
2222
if (collectionName.contains(DatabaseProvider.CollectionSeparator)) {
23-
val newDatabaseName = collectionName.substring(0, collectionName.indexOf(DatabaseProvider.CollectionSeparator))
23+
val newDatabaseName = collectionName.substring(0, collectionName.indexOf(DatabaseProvider.CollectionSeparator))
2424
val newCollectionName = collectionName.substring(collectionName.indexOf(DatabaseProvider.CollectionSeparator) + 1)
2525
provider.database(newDatabaseName).getCollection[A](newCollectionName)
2626
} else {
2727
provider.database().getCollection[A](collectionName)
2828
}
2929
}
3030

31+
def addChangeObserver(observer: ChangeObserver[A]): ChangeObserver[A] = {
32+
coll.watch[A]().subscribe(observer)
33+
observer
34+
}
35+
36+
def stats: Observable[CollectionStats] =
37+
provider.runCommand(Map("collStats" -> collectionName)).map(document => CollectionStats(document))
38+
3139
protected def coll: MongoCollection[A] = collection
3240

3341
// internal object for raw document access
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.sfxcode.nosql.mongo.database
2+
3+
import java.util.Date
4+
5+
import com.sfxcode.nosql.mongo._
6+
import org.mongodb.scala.bson.Document
7+
8+
case class CollectionStats(
9+
ns: String,
10+
collectionType: String,
11+
size: Double,
12+
count: Long,
13+
storageSize: Double,
14+
avgObjSize: Double,
15+
nindexes: Double,
16+
indexSizes: Map[String, Int],
17+
totalIndexSize: Double,
18+
indexDetails: Map[String, Map[String, Any]],
19+
scaleFactor: Double,
20+
ok: Long,
21+
fetched: Date = new Date()
22+
)
23+
24+
object CollectionStats {
25+
def apply(document: Document): CollectionStats = {
26+
val map = document.asPlainMap
27+
CollectionStats(
28+
map("ns").toString,
29+
map.getOrElse("type", "Standard").toString,
30+
map("size").asInstanceOf[Int],
31+
map("count").asInstanceOf[Int],
32+
map("storageSize").asInstanceOf[Int],
33+
map("avgObjSize").asInstanceOf[Int],
34+
map("nindexes").asInstanceOf[Int],
35+
map("indexSizes").asInstanceOf[Map[String, Int]],
36+
map("totalIndexSize").asInstanceOf[Int],
37+
map("indexDetails").asInstanceOf[Map[String, Map[String, Any]]],
38+
map("scaleFactor").asInstanceOf[Int],
39+
map("ok").asInstanceOf[Double].toInt
40+
)
41+
}
42+
}

src/main/scala/com/sfxcode/nosql/mongo/database/DatabaseProvider.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class DatabaseProvider(config: MongoConfig, registry: CodecRegistry) extends Ser
4545
observer
4646
}
4747

48+
def runCommand(document: Document, databaseName: String = config.database): SingleObservable[Document] =
49+
database(databaseName).runCommand(document)
50+
4851
def collection(collectionName: String): MongoCollection[Document] =
4952
dao(collectionName).collection
5053

src/main/scala/com/sfxcode/nosql/mongo/gridfs/Metadata.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ abstract class Metadata(provider: DatabaseProvider, bucketName: String) extends
1515

1616
def filesCollectionName: String = "%s.%s".format(bucketName, "files")
1717

18+
def chunksCollectionName: String = "%s.%s".format(bucketName, "chunks")
19+
1820
def updateMetadata(oid: ObjectId, value: Any): Observable[UpdateResult] = {
1921
val doc: BsonValue = BsonConverter.toBson(value)
20-
val result = Files.updateOne(equal("_id", oid), set("metadata", doc))
22+
val result = Files.updateOne(equal("_id", oid), set("metadata", doc))
2123
result
2224
}
2325

@@ -42,6 +44,7 @@ abstract class Metadata(provider: DatabaseProvider, bucketName: String) extends
4244
def updateMetadataElement(filter: Bson, key: String, value: Any): Observable[UpdateResult] =
4345
updateMetadataElements(filter, Map(key -> value))
4446

45-
object Files extends MongoDAO[Document](provider, filesCollectionName)
47+
object Files extends MongoDAO[Document](provider, filesCollectionName)
48+
object Chunks extends MongoDAO[Document](provider, chunksCollectionName)
4649

4750
}

src/main/scala/com/sfxcode/nosql/mongo/operation/Base.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,4 @@ abstract class Base[A]()(implicit ct: ClassTag[A]) extends LazyLogging {
6767

6868
def hasIndexForField(fieldName: String): Boolean = MongoIndex.hasIndexForFieldWithName(listIndexes, fieldName)
6969

70-
def addChangeObserver(observer: ChangeObserver[A]): ChangeObserver[A] = {
71-
coll.watch[A]().subscribe(observer)
72-
observer
73-
}
74-
7570
}

src/test/scala/com/sfxcode/nosql/mongo/dao/BookDAOSpec.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.sfxcode.nosql.mongo.dao
22

33
import better.files.{ File, Resource }
4-
import com.sfxcode.nosql.mongo.TestDatabase.{ BookDAO, PersonDAO }
4+
import com.sfxcode.nosql.mongo.TestDatabase.BookDAO
55
import com.sfxcode.nosql.mongo._
66
import org.specs2.mutable.Specification
77
import org.specs2.specification.BeforeAll
@@ -12,6 +12,10 @@ class BookDAOSpec extends Specification with BeforeAll {
1212
override def beforeAll(): Unit = {
1313
BookDAO.drop().result()
1414
BookDAO.importJsonFile(File(Resource.getUrl("json/books.json"))).result()
15+
16+
val stats = BookDAO.stats.result()
17+
stats.count mustEqual 431
18+
1519
}
1620

1721
"BookDAO" should {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.sfxcode.nosql.mongo.database
2+
3+
import com.sfxcode.nosql.mongo.TestDatabase._
4+
import com.sfxcode.nosql.mongo._
5+
import org.mongodb.scala.Document
6+
import org.specs2.mutable.Specification
7+
8+
class DatabaseProviderSpec extends Specification {
9+
10+
"Base Operations" should {
11+
12+
"must evaluate buildInfo" in {
13+
14+
val result: Document = provider.runCommand(Map("buildInfo" -> 1)).result()
15+
16+
result.getDouble("ok") mustEqual 1.0
17+
}
18+
19+
"must evaluate collectionInfo" in {
20+
21+
val result: Document = provider.runCommand(Map("collStats" -> "books")).result()
22+
23+
val s = result.asPlainJson
24+
result must not beEmpty
25+
}
26+
}
27+
}

src/test/scala/com/sfxcode/nosql/mongo/gridfs/GridFSDatabaseSpec.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ class GridFSDatabaseSpec extends Specification with GridfsDatabaseFunctions with
6666

6767
}
6868

69+
"find stats in file in" in {
70+
val fileStats = ImageFilesDAO.fileStats.result()
71+
val chunkStats = ImageFilesDAO.chunkStats.result()
72+
73+
fileStats.count must be greaterThan 0
74+
chunkStats.storageSize must be greaterThan 0
75+
76+
}
77+
6978
}
7079

7180
override def beforeAll(): Unit = {

0 commit comments

Comments
 (0)