This is the first baby step in replacing custom reflection-based code with shapeless.
- 2017.10.26 -
longevity.model.PType[M, P]
now has an abstract member with typelongevity.model.PEv[M, P]
. This is filled in by the@longevity.model.annotations.persistent
family of annotations, so it is not a concern to you if you are using these annotations to construct yourPTypes
. If not, you might consider using the new@longevity.model.annotations.pEv
annotation to create thePEv
for you. - 2017.10.26 - Traits for polymorphic persistent and component types - typically declared via
annotations
@longevity.model.annotations.polyPersistent
and@longevity.model.annotations.polyComponent
- now need to be sealed. This will require moving subtypes into the same file. - 2017.10.26 - The
longevity.test.TestDataGenerator
API has been simplified. If you were using this class in a way for which the new version is no longer sufficient, please let us know, and we will see what we can do to help you out. - 2018.06.07 - Classes
longevity.test.CustomGenerator
andlongevity.test.CustomGeneratorPool
have been removed. Custom test generation to account for constraints enforced within your domain model can now be accomplished using ScalaCheck'sArbitrary
andGen
, See the user manual page on enforcing constraints for more information.
Please see the user manual for an explanation of this new feature.
- 2017.07.12 - Add some specialized "implicit not found" error messages for implicit types in
longevity.model
. - 2017.07.12 - Reverse order of implicits for
Repo.retrieve
andRepo.retrieveOne
methods. This way, we get "implicit not found" compiler errors for thePEv
before theKey
. This will give more relevant error messages when the retrieve methods are called without explicating theP
type parameter. - 2017.07.12 - Rename
PState.map
toPState.modify
. This follows more standard lense-type terminology, and removes the incorrect impression that this is a monadic method. - 2017.07.24 - Add
PState.modifyF
, which acts likemodify
, except for functions that return an effectful result.
- 2017.06.14 - Rename config flag
autocreateSchema
toautoCreateSchema
. - 2017.06.14 - Add config flag
autoOpenConnection
. - 2017.06.15 - Add API method
Repo.openConnection
. - 2017.06.15 - Rename API method
Repo.closeConnection
toRepo.closeConnection
. - 2017.06.16 - Add config flag
cassandra.autoCreateKeyspace
. - 2017.06.19 - Rename
longevity.config.LongevityConfig.apply(com.typesafe.config.Config)
toLongevityConfig.fromTypesafeConfig
. This was necessary to prevent the library we use to parse the Typesafe config from infinite looping on a configuration error. - 2017.06.29 - Remove
longevity.persistent.FOPState
and variants. Now that we have generalized effects, these classes are special case. And they already take up a lot of space in API. - 2017.06.29 - Remove method
longevity.persistent.Repo.createMany
and relatedlongevity.persistent.PWithEv
. These provided very little value added at the expense of cluttering the API with confusing stuff. - 2017.07.06 - Replace hardcoded
Future
effect with generic effectF
inlongevity.context.LongevityContext
andlongevity.persistence.Repo
.
The changes in this release are many, and the overall picture is hard to grasp by looking through a bullet list of the changes. For this reason, we present a quick migration guide here to get you from 0.22 to 0.23. Making the changes in the migration guide will probably get you 95-100% of the way there.
-
Replace this:
@domainModel object MyModel
with this:
@domainModel trait MyModel
-
Replace
@persistent
with@persistent[MyModel]
,@component
with@component[MyModel]
, and@keyVal[P]
with@keyVal[MyModel, P]
-
Remove the
keySet = Set(key(props.a), key(props.b))
as an argument to the@persistent
annotation. Put the following lines in the companion object for your persistent class instead:implicit val aKey = key(props.a)
implicit val bKey = key(props.b)
-
Replace this:
val context = LongevityContext(MyModel)
with this:
val context = LongevityContext[MyModel]()
-
Replace references to
Repo[P]
withRepo[MyModel]
-
Replace calls like this:
context.repoPool[P]
with this:
context.repo
-
For repository methods
createSchema
andcloseConnection
, replace calls like this:context.repoPool.createSchema()
with call chains like this:
context.repo.createSchema()
-
Merge
longevity.persistence.Repo
andlongevity.persistence.RepoPool
APIs. There is now a single repository, and the create/retrieve/update/delete/query methods now all take the persistent type as a type parameter. To migrate, code that used to look like this:longevityContext.repoPool[User].create(user)
now looks like this:
longevityContext.repo.create[User](user)
In most cases, you can leave off type parameter, as the compiler can easily infer it:
longevityContext.repo.create(user)
-
Replace
longevity.model.DomainModel
with alongevity.model.ModelType
type-class. Everything that used to live inDomainModel
now lives inModelType
.longevity.model.annotations.domainModel
now annotates a marker class or trait, instead of the object that was to become the oldDomainModel
. This annotation macro adds animplicit object modelType
into the companion object of the annotated class.ModelType
now takes a type parameterM
that refers to the phantom class annotated withdomainModel
.longevity.context.LongevityContext
now takes a type parameterM
for the model class. In place of the explicitDomainModel
argument, it now takes an implicitModelType[M]
, which can easily be found in the companion object ofM
, as built by the annotation macro.longevity.context.Repo
also now takes a type parameterM
. -
Add
longevity.model.ModelEv
type-class. ("Ev" is short for "evidence" here.) Thelongevity.model.annotations.domainModel
annotation macro now adds animplicit object modelEv
into the companion object of the annotated class. This evidence class is private to the package that the domain model is found in.longevity.model.PType
now has a type parameterM
for the model, and an implicitModelEv[M]
is required to initialize aPType[M, P]
. Because the generated model evidence is private to the model package, persistent types outside of the model package will not find the evidence, and will fail to compile. This prevents the user from accidentally creating a persistent type that falls outside the model. -
Add
longevity.model.PEv
type-class. ("Ev" is short for "evidence" here.) Thelongevity.model.PType
now includes animplicit val ev: PEv[M, P]
. Because the companion object of a persistent class is normally the correspondingPType
, this evidence should be available where needed.longevity.persistence.Repo
methods that used to take an implicitTypeKey[P]
argument, now take an implicitPEv[M, P]
argument. As users will not be able to find an implicitPEv[M, P]
available without the typeP
actually being part of the model, (excepting the case where the user goes to extended lengths to subvert our type system), it will now be a compile-time error to call these repository methods with a non-persistent object. This is a great improvement over the old situation, since aTypeKey[P]
is available for any typeP
for which there is aTypeTag[P]
available. -
Replace
longevity.model.KeyVal[P]
withlongevity.model.KVType[M, P, V]
, which includes an implicit vallongevity.model.KVEv[M, P, V]
.@longevity.model.annotations.keyVal
now takes a type parameterM
along with the type parameterP
. The@keyVal
annotation now creates or augments the companion object as aKVType[M, P, V]
. -
Methods
PType.key
andPType.primaryKey
now take implicitKVEv
arguments, to make sure the key value type provided matches aKVType
that is provided to theModelType
. -
The old constructors and factory methods for creating a
longevity.model.ModelType
have been replaced with a single constructor that takes lists oflongevity.model.PTypes
,longevity.model.CTypes
, andlongevity.model.KVTypes
. The runtime package scanning constructor has been replaced by a compile-time package scanning. The new scanner,longevity.model.annotations.packscanToList
, is used bylongevity.model.annotations.domainModel
, but you can use it yourself if you like. If you have been using the@domainModel
annotation, these changes should not affect you. -
longevity.model.PTypePool
andlongevity.model.CTypePool
have been removed. -
Instead of passing in a
keySet
to the@persistent
annotation, users should now specify their keys themselves, directly in the body of the companion object, as implicit values. ThePType.keySet
has been made private, and is populated by reflecting on the members of the companion object. -
Methods
longevity.persistence.Repo.retrieve
andlongevity.persistence.Repo.retrieveOne
now take an implicitKey[M, P, V]
instead of an implicitTypeKey[V]
. This will typically be found by implicit resolution in the companion object ofP
. -
Remove method
longevity.model.PType.prop
. You can extendlongevity.model.ptype.Prop
instead, but note that we advise you to use thelongevity.model.annotations.persistent
annotation to generate properties.
- 2017.03.24 - Rename
Repo.retrieveByQuery
toRepo.queryToFutureVec
. The return type of this method has also been adjusted fromFuture[Seq[PState[P]]]
toFuture[Vector[PState[P]]]
. - 2017.03.24 - Add method
Repo.queryToItereator
. - 2017.03.24 - Rename
Repo.streamByQuery
toRepo.queryToAkkaStream
. - 2017.03.24 - Add method
Repo.queryToFS2
. - 2017.03.24 - Add method
Repo.queryToIterateeIo
. - 2017.03.24 - Add method
Repo.queryToPlay
.
- 2017.02.08 - Add new
JDBC
back end. - 2017.02.06 - Rename
longevity.config.SQLiteConfig
toJdbcConfig
. Renamelongevity.config.LongevityConfig.sqlite
tojdbc
. Renamelongevity.config.TestConfig.sqlite
tojdbc
. - 2017.02.15 - Add configuration flag
longevity.writeTimestamps
.
- 2017.01.12 - Rename dependency bundle artifact from
longevity-mongo-deps
tolongevity-mongodb-deps
. - 2017.01.12 - Rename
longevity.config.Mongo
tolongevity.config.MongoDB
. Renamelongevity.config.MongoConfig
tolongevity.config.MongoBDConfig
. - 2017.01.14 - Add SQLite back end. See
longevity.config.SQLite
andlongevity.config.SQLiteConfig
. - 2017.01.14 - Rename
longevity.model.PType.partitionKey
toprimaryKey
.
- 2016.12.09 - Rename package
longevity.subdomain
tolongevity.model
. Alsolongevity.exceptions.subdomain
tolongevity.exceptions.model
. - 2016.12.09 - Rename
longevity.model.Subdomain
toDomainModel
. - 2016.12.09 - Rename annotation
longevity.model.annotations.subdomain
todomainModel
. - 2016.12.09 - Move config classes
LongevityConfig
,BackEnd
,MongoDBConfig
,CassandraConfig
,TestConfig
, andPersistenceConfig
from packagelongevity.context
to new packagelongevity.config
.
- 2016.12.06 - Prevent emblem leakage of
TestDataGenerator
andCustomGeneratorPool
by wrapping them in longevity classes. Slightly simplified the API for adding a custom test data generators. - 2016.12.06 - Add
LongevityContext
constructors andapply
methods that take either aLongevityConfig
or a Typesafe config. - 2016.12.06 - Add annotation macro
@subdomain
in packagelongevity.subdomain.annotations
. - 2016.12.06 - Add
Subdomain
constructor andapply
method that collect all thePTypes
andCTypes
by package scanning. - 2016.11.30 - Add annotation macros
@component
,@derivedComponent
,@derivedPersistent
,@keyVal
,@mprops
,@persistent
,@polyComponent
, and@polyPersistent
in packagelongevity.subdomain.annotations
. - 2016.11.30 - Remove scanning of
PType
inner objectskeys
andindexes
to look for keys and indexes. Users must now definePType.keySet
, and overridePType.indexSet
, to declare keys and indexes. We made this change since the object scanning was superfluous, and complicates the API. (In contrast, scanning for properties is useful, as users need to be able to call properties by name. However, users never really need to call keys and indexes by name, so there is no advantage to naming them in an inner object.) - 2016.11.23 - Add method
PType.emptyKeySet
. - 2016.11.23 - Make
PType.partitionKey
methods returnKey[P]
instead ofPartitionKey[P]
. this is for convenience of Scala 2.11 users, so they dont have to declare the full type of their keySet. - 2016.11.22 - Remove second type parameter from
longevity.subdomain.Key
andlongevity.subdomain.PartitionKey
. Remove typeslongevity.subdomain.AnyKey
andlongevity.subdomain.AnyPartitionKey
, as they no longer serve any purpose.
- 2016.11.13 - Remove second type parameter from
longevity.subdomain.KeyVal
. - 2016.11.12 - Rename
longevity.subdomain.EType
(for "embeddable type") tolongevity.subdomain.CType
(for "component type"). - 2016.11.12 - Remove traits
longevity.subdomain.Embeddable
andlongevity.subdomain.Persistent
. Users no longer need to extend their subdomain classes with these empty marker traits. - 2016.11.12 - Change
RepoCrudSpec
from aFeatureSpec
to aFlatSpec
. Users usingLongevityContext.repoCrudSpec
will notice significantly less verbose test output.
- 2016.11.09 - Uniformly convert
DateTime
to UTC time zone. This seems like the best approach right now, as both Cassandra and MongoDB back ends support timestamps without time zone information. It also resolves issues with sorting dates. - 2016.11.09 - Implement partition keys. Please see the user manual for details.
- 2016.10.27 - Replace Casbah with Java driver in MongoDB back end. We are now using the vanilla Java driver for Mongo. This change should not affect users.
- 2016.10.27 - Fix MongoDB URIs so they work in a sharded environment.
- 2016.10.27 - Disallow keys and indexes that duplicate the properties of other keys or indexes. This may cause existing code to break. Fix is to root out the duplicates. If you have a key and an index that duplicate each other, you can safely remove the index, as it is redundant with the key.
- 2016.10.08 - Remove
KeyVal.key
and changeKeyVal
from an abstract class into a trait. To migrate existing code, you will need to remove theKey
argument supplied to each of yourKeyVal
types. - 2016.10.12 - Queries have been extended with "order-by", "offset", and "limit" clauses. The query DSL has likewise been extended.
- 2016.10.12 - Many of the classes used to build queries have been
re-organized into new package
longevity.subdomain.query
. This should not affect you if you are only using the query DSL.
Please refer to the user manual for the latest on the query API.
- 2016.10.04 - Rename
DerivedType
toDerivedEType
. RenamePolyType
toPolyEType
. - 2016.10.04 - Move
CoreDomain
,GenericSubdomain
, andSupportingSubdomain
from packagelongevity.subdomain
tolongevity.ddd.subdomain
. - 2016.10.04 - Move
Entity
,EntityType
,ValueObject
, andValueType
from packagelongevity.subdomain.embeddable
tolongevity.ddd.subdomain
. - 2016.10.04 - Move
Event
,Root
, andViewItem
from packagelongevity.subdomain.persistent
to packagelongevity.ddd.subdomain
. - 2016.10.04 - Move
EventType
,RootType
, andView
from packagelongevity.subdomain.ptype
to packagelongevity.ddd.subdomain
. - 2016.10.04 - Move
DerivedEType
,EType
,ETypePool
,Embeddable
, andPolyEType
from packagelongevity.subdomain.embeddable
tolongevity.subdomain
. - 2016.10.04 - Move
Persistent
from packagelongevity.subdomain.persistent
tolongevity.subdomain
. - 2016.10.04 - Move
DerivedPType
,PType
,PTypePool
, andPolyPType
from packagelongevity.subdomain.ptype
tolongevity.subdomain
. - 2016.10.04 - Move package
longevity.ddd.subdomain
into a separate project calledlongevity-ddd
. If you want to continue using the wrapper classes found there, please add the following dependency to your project:libraryDependencies += "org.longevityframework" %% "longevity-ddd" % "x.y.z"
.
There was a bug in our use of Scala reflection. In brief, we were
using the class loader (i.e., scala reflection Mirror
) that was used
to load the longevity library. This is bogus, as we are reflecting
against user classes! We changed things to reflect on the mirror of
the TypeTags
(they get wrapped in TypeKeys
) that the user library
provides to use.
End result is that projects that do funky things with class loaders will not get reflection exceptions when using longevity.
Some odds and ends that have been accumulating in the backlog.
- 2016.09.22 - Rename
PersistenceStrategy
toBackEnd
. MoveBackEnd
from being a separate argument toLongevityContext
creator methods, to being part of the config, under config propertylongevity.backEnd
. - 2016.09.19 - Add
OPState
to go along withFPState
andFOPState
. - 2016.09.19 - Add JSON marshallers at
LongevityContext.jsonMarshaller
andLongevityContext.jsonUnmarshaller
.
Some odds and ends that have been accumulating in the backlog.
- 2016.09.15 - Remove
PState.dirty
. We are taking this out because there we may decide to stop keeping track of the original version of the persistent object, in order to reduce memory usage. - 2016.09.14 - Add
RepoPool.createSchema()
and configuration flagautogenerateSchema
. - 2016.09.13 - Add logging for all
Repo
methods and database calls. - 2016.09.13 - Add API method
RepoPool.closeConnection()
. This was added because leaving the Cassandra session open can cause user programs to fail to terminate under certain circumstances, If your main program is hanging when using Cassandra, please call this method at the end of your program.
- 2016.08.29 - Add factory methods for
EType
and all its descendents. The older pattern of making embeddable companion objects intoETypes
(e.g.,case class Email extends EType[Email]
) still works, but now you can just mention theEType
directly, when building your subdomain. (E.g.,Subdomain(???, ???, ETypePool(EType[Email]))
). - 2016.08.28 - Get rid of
DerivedType.polyType
andDerivedPType.polyPType
.DerivedType
andDerivedPType
are now abstract classes instead of traits, so users may need to reorder their inheritancewith
clauses. (It's highly unlikely a user would have been be using these traits to extend a class.)
- 2016.08.25 - Fix JSON translation of DateTimes to use time zone codes instead of offsets. Fix JSON parser to respect the time zone in the string representation of the DateTime.
- 2016.08.24 - Add optimistic locking. To turn it on, you will need to
set
longevity.optimisticLocking = true
in your typesafe config. - 2016.08.23 - Add
LongevityContext.testDataGenerator
. - 2016.08.17 - Add support for
Persistents
andEmbeddables
that are case objects. - 2016.07.29 - Add
LongevityConfig
for well-typed configuration. Users can useLongevityConfig
instead of a Typesafe Config to configure their context. Just use theLongevityContext
constructor instead of theLongevityContext.apply
factor method. - 2016.07.29 - Make
PType.indexes
optional. You used to have to declare an emptyindexes
singleton object within yourPType
if you had no indexes. Now, you can just leave it out. This should have no effect on existing code, but you can go back and remove emptyindexes
objects if you want. - 2016.07.22 - Make Akka
Streams an optional
dependency. If you are using
Repo.streamByQuery
, you must now declare a dependency on Akka Streams yourself:libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.4.9"
.
- 2016.08.24 - There was an error in the build that caused longevity poms to refer to the emblem GitHub project, instead of the longevity GitHub project. This release fixes that. There are no code changes whatsoever.
- 2016.07.12 - Completely rework
KeyVal
andKey
for improved understandability and ease of use. please see the manual for details. - 2016.07.12 -
Assoc
s are gone. please useKeyVal
s andKey
s instead. - 2016.07.12 - a
PType
's properties and keys are now only realized when theSubdomain
is constructed. this should have no affect on the user, except that some exceptions for malformed properties will be delayed untilSubdomain
initialization. also, properties created outside ofPType.propSet
will no longer work. - 2016.06.23 - shorthands are gone. please use single-property
embeddables such as
ValueObject
instead. - 2016.06.21 - single-property embeddables are now inlined. this has no affect on the user other than how the persistents are translated into JSON/BSON.
- 2016.06.20 - add parent types
Embeddable
andEType
forEntity
,ValueObject
,EntityType
, andValueType
. - 2016.06.10 - add noop query
Query.All()
. - 2016.06.07 - add method
Deleted.get
. - 2016.06.07 - fix method names
LiftFPState.mapRoot
,LiftFPState.flatMapRoot
,LiftFOPState.mapRoot
, andLiftFOPState.flatMapRoot
by replacingRoot
withP
. - 2016.06.01 -
CoreDomain
,SupportingSubdomain
andGenericSubdomain
are now actual traits that extendSubdomain
(instead of just type aliases). this allows users to directly subclass these three types if they wish.
- 2016.06.01 - make Akka streams non-optional dependency. difficult-to-resolve linking problems occur when this is optional. we might revisit this later but for now the best solution is to make it non-optional.
- 2016.05.24 - add API method
Repo.streamByQuery(query: Query[P]): Source[PState[P], NotUsed]
.
- 2016.05.18 - users can now subclass
Shorthand
. - 2016.05.12 -
PType
and sub-classes no longer take an implicitShorthandPool
argument. - 2016.05.12 -
Subdomain
,CoreDomain
,SupportingSubdomain
, andGenericSubdomain
factory method signatures have changed. They now have a single parameter list, and theShorthandPool
parameter is no longer implicit. - 2016.05.12 -
Persistent
no longer inherits fromEntity
.PType
no longer inherits fromEntityType
. these changes should not affect user code. - 2016.05.12 - modify
Subdomain.apply
to separate outentityTypePool
intopTypePool
andentityTypePool
. - 2016.05.12 - add
PolyType
,DerivedType
,PolyPType
, andDerivedPType
. see user manual. - 2016.05.12 - move the following classes from package
longevity.subdomain to package longevity.subdomain.entity:
EntityTypePool
EntityType
Entity
ValueObject
ValueType
- 2016.03.02 - add implicit execution context parameter to: all
Repo
methods;RepoPool.createMany
; andLongevityContext.repoCrudSpec
andinMemTestRepoCrudSpec
. users now need to provide execution contexts to use all these methods. the easiest way to do this is to includeimport scala.concurrent.ExecutionContext.Implicits.global
at the top of the file. - 2016.03.08 - update to latest version of library dependencies casbah (3.1.1) and cassandra (3.0.0).
- 2016.03.08 - add sub-projects
longevity-cassandra-deps
andlongevity-mongo-deps
. - 2016.03.10 - replace
Root
withPersistent
. givePersistent
three child traits:Root
,ViewItem
, andEvent
. these changes should not affect existing code that usesRoot
. - 2016.03.10 - replace
RootType
withPType
. givePType
three child traits:RootType
,View
, andEventType
. these changes should not affect existing code that usesRootType
. - 2016.03.25 - rework
PType
API forkeySet
andindexSet
. please see the latest documentation for a review of the new API.
- 2016.01.12 - rename
RootType.keys
toRootType.keySet
. - 2016.01.12 - rename
RootType.indexes
toRootType.indexSet
. - 2016.03.01 - add Cassandra back end.
- 2016.03.01 - deprecate all methods that allow for use of a string
property path in place of a
Prop
. affected methods areRootEntity.{ key, index }
,Query.{ eqs, neq, lt, lte, gt, gte }
, and the corresponging methods in theQueryDsl
. - 2016.03.01 - rework
QuerySpec
. - 2016.03.02 - provide a parent trait
PRef
forAssoc
andKeyVal
. merge the two versions of theRepo
methodsretrieve
andretrieveOne
so that they take aPRef
. this shouldn't affect any client code.