Entity Engine in Memory
The memory provider applies the same typed entity model and KQL execution rules to existing Klyn collections. It is useful for fixtures, reference data, deterministic tests, and applications whose authoritative state already lives in memory.
| Capability | Memory provider behavior |
|---|---|
| Access mode | Read-only, no-tracking repositories over existing entity lists. |
| Storage | The list is wrapped without copying; the repository owns no entity storage. |
| Identity | Provider-neutral keys are validated eagerly when the repository is created. |
| Queries | Provider-neutral KQL is evaluated directly over the current list content. |
| Relationships | Mapped eager relations and requested fetch paths are prepared before execution. |
| Mutation | Entity Engine persistence operations are not supported by this provider. |
Memory entities use the provider-neutral annotations from klyn.data.mapping. They do
not require SQL, XML, or JSON binding annotations.
import klyn.data.mapping
@Entity
class User:
@Id
public property id as Int
public property login as String
public property connectionNumber as Int
public property active as Boolean
public User(
id as Int,
login as String,
connectionNumber as Int,
active as Boolean = true
):
this.id = id
this.login = login
this.connectionNumber = connectionNumber
this.active = active
users = [
User(1, "alice", 4),
User(2, "bob", 14),
User(3, "carol", 21)
]
Register one typed MemoryRepository<T, TId> for every allowed entity type.
The factory entity list remains the authoritative model and is checked against those
registrations.
import klyn.data
import klyn.data.memory
userSource = MemoryRepository<User, Int>(users)
configuration = MemoryConfiguration([userSource])
try factory = EntityManagerFactory(
configuration,
entities=[User]
):
assert factory.schema.exists()
assert factory.schema.exists(User.type)
try em = factory.createEntityManager():
bob = em.find<User>(2)
assert bob.login == "bob"
Construction rejects null identities and raises DuplicateIdentityException as soon
as a duplicate key is found. validateBeforeRead() can repeat complete key validation
after the backing list has changed.
When a factory and manager already define the entity model, use query(em):. The root
entity identifies the registered memory repository and no alias is required when the query has a
single unambiguous source.
frequentUsers = query(em):
from User
where active and connectionNumber > 10
order by connectionNumber desc, login
for user in frequentUsers.toList():
print(f"{user.login}: {user.connectionNumber}")
Query creation is lazy. Terminal operations such as toList(), count(),
exists(), first(), and single() execute against the list
content visible at that time.
The explicit repository form is useful when a function should accept any compatible query
source. Unlike query(em):, this form names both the source value and its alias.
def frequent(
source as Queryable<User>,
minimum as Int
) as Query<User>:
return query:
from source user
where user.connectionNumber > minimum
order by user.connectionNumber desc
selected = frequent(userSource, 10).toList()
Manager and repository forms lower to the same immutable query representation; only root resolution differs.
- Creating a repository does not copy its backing list.
- A later query observes values currently present in that list.
- Key validation is eager at construction and explicit through
validateBeforeRead(). - Each query execution owns its cursor and must be consumed sequentially.
- Concurrent list mutation requires an appropriate synchronized collection and application-level coordination.
The memory provider does not persist, merge, remove, or roll back entities. Modify the backing collection through its owner when mutation is required.
Provider-neutral relationship annotations are supported. Direct entity references are retained;
inverse endpoints are reconstructed from ownership metadata. Eager relationships are prepared
automatically, while join fetch requests a lazy relationship for one execution.
@ManyToOne(optional=false)
public property author as User
@OneToMany(mappedBy="author")
public property articles as List<Article> = []
Every relationship target must be present in the factory entity list and have a matching registered memory repository.
The memory schema is the set of registered entity repositories. exists() and
validate() verify that the factory model is fully registered. There is no physical
resource to create or migrate, and drop() is unsupported because ownership remains
with the application.
schema = factory.schema
schema.validate()
plan = schema.diff()
assert plan.empty
Return to Entity Engine KQL for the complete query syntax, or continue with the Windows GUI Library.