Jenesis Data Store: a dynamic, cross platform, high performance, ORM data-mapper. Designed to assist in rapid development and data mining

Overview

Build Status Maven Central Javadocs License Size

Jenesis Data Store

Jenesis Data Store (JDS) was created to help developers persist data to a strongly-typed portable JSON format.

JDS has four goals:

  • To allow for the rapid development of complex Java/Kotlin systems with stringent data definition / quality requirements
  • To provide a flexible and reliable framework to persist and retrieve data against.
  • To provide a robust, strongly-typed Field Dictionary.
  • To leverage JSON as a datastore over EAV based paradigms.

The library eliminates the need to modify schemas once a class has been altered.

It also eliminates all concerns regarding "breaking changes" in regards to fields and their addition and/or removal.

Put simply, JDS is useful for any developer that requires a flexible data store running on top of a Relational databases.

JDS is licensed under the 3-Clause BSD License

Design

The concept behind JDS is quite simple. Extend a base Entity class, define strongly-typed Fields and then map them against implementations of the Property interface.

JDS was designed to avoid reflection and its potential performance pitfalls. As such mapping functions which are overridden, and invoked at least once at runtime, are used to enforce/validate typing as instead of annotations. This is discussed below in section 1.1.4 "Binding properties".

Features

  • Transparent persistence
  • Supports the persistence of NULL values for boxed types (e.g Integer, Double)
  • Full support for generics and inheritance
  • Easily integrates with new or existing databases
  • Portable format which can be serialised to JSON allows for the flexibility of EAV without its drawbacks
  • Supports MySQL, T-SQL, PostgreSQL, Oracle 11G, MariaDB and SQLite
  • Supports a robust Field Dictonary allowing for metadata such as Tags and Alternate Coding to be applied to Fields and Entities.

Maven Central

You can search on The Central Repository with GroupId and ArtifactId Maven Search for Maven Search

Maven

<dependency>
    <groupId>io.github.subiyacryolite</groupId>
    <artifactId>jds</artifactId>
    <version>20.4</version>
</dependency>

Gradle

compile 'io.github.subiyacryolite:jds:20.4'

Dependencies

The library depends on Java 1.8. Both 64 and 32 bit variants should suffice. Both the Development Kit and Runtime can be downloaded from here.

Supported Databases

The API currently supports the following Relational Databases, each of which has their own dependencies, versions and licensing requirements. Please consult the official sites for specifics.

Database Version Tested Against Official Site JDBC Driver Tested Against
PostgreSQL 9.5 Official Site org.postgresql
MySQL 5.7.14 Official Site com.mysql.cj.jdbc.Driver
MariaDb 10.2.12 Official Site org.mariadb.jdbc.Driver
Microsoft SQL Server 2008 R2 Official Site com.microsoft.sqlserver
SQLite 3.16.1 Official Site org.sqlite.JDBC
Oracle 11g Release 2 Official Site oracle.jdbc.driver.OracleDriver

1 How it works

1.1 Creating Classes

Classes that use JDS need to extend Entity.

import io.github.subiyacryolite.jds.Entity;

public class Address : Entity

However, if you plan on using interfaces they must extend IEntity. Concrete classes can then extend Entity

import io.github.subiyacryolite.jds.Entity;
import io.github.subiyacryolite.jds.IEntity;

public interface IAddress : IEntity

public class Address : IAddress

1.1.1 Annotating Classes

Every class/interface which extends Entity/IEntity must have its own unique Entity ID as well as an Entity Name. This is done by annotating the class, or its (parent) interface.

@EntityAnnotation(id = 1, name = "address", description = "An entity representing address information")
class Address : Entity()

Entity IDs MUST be unique in your application, any value of type long is valid. Entity Names do not enforce unique constraints but its best to use a unique name regardless. These values can be referenced to mine data.

1.1.2 Defining Fields

Fields are big part of the JDS framework. Each Field MUST have a unique Field Id. Field Names do not enforce unique constraints but its best to use a unique name regardless. These values can be referenced to mine data. Every Field that you define can be one of the following types.

JDS Field Type Java Type Description
DateTimeCollection Collection<LocalDateTime> Collection of type LocalDateTime
DoubleCollection Collection<Double> Collection of type Double
EntityCollection Collection<Class<? extends Entity>> Collection of type Entity
FloatCollection Collection<Float> Collection of type Float
IntCollection Collection<Integer> Collection of type Integer
ShortCollection Collection<Short> Collection of type Short
LongCollection Collection<Long> Collection of type Long
StringCollection Collection<String> Collection of type String
UuidCollection Collection<UUID> Collection of type UUID
Blob byte[] or InputStream Blob values
Boolean boolean / Boolean Boolean values
Entity Class<? extends Entity> Object of type Entity
DateTime LocalDateTime DateTime instances based on the host machines local timezone
Date LocalDate Local date instances
Double double / Double Numeric double values
Duration Duration Object of type Duration
EnumCollection Collection<Enum> Collection of type Enum
Enum Enum Object of type Enum
Float float / Float Numeric float values
Int int / Integer Numeric integer values
Short short / Short Numeric SHORT values
Long long / Long Numeric long values
MonthDay MonthDay Object of type MonthDay
Period Period Object of type Period
String String String values with no max limit
Time LocalTime Local time instances
YearMonth YearMonth Object of type YearMonth
ZonedDateTime ZonedDateTime Zoned DateTime instances
Uuid UUID UUID instances

We recommend defining your Fields as static constants

import io.github.subiyacryolite.jds.Field;
import io.github.subiyacryolite.jds.enumProperties.FieldType;

object Fields {
    val StreetName = Field(1, "street_name", FieldType.String)
    val PlotNumber = Field(2, "plot_number", FieldType.Int)
    val Area = Field(3, "area_name", FieldType.String)
    val ProvinceOrState = Field(4, "province_name", FieldType.String)
    val City = Field(5, "city_name", FieldType.String)
    val Country = Field(7, "country_name", FieldType.String)
    val PrimaryAddress = Field(8, "primary_address", FieldType.Boolean)
    val Timestamp = Field(9, "timestamp", FieldType.DateTime)
}

Furthermore, you can add descriptions, of up to 256 characters, to each field

import io.github.subiyacryolite.jds.Field;
import io.github.subiyacryolite.jds.enumProperties.FieldType;

object Fields {
    val StreetName = Field(1, "street_name", FieldType.String, "The street name of the address")
    val PlotNumber = Field(2, "plot_number", FieldType.Int, "The street name of the address")
    val Area = Field(3, "area_name", FieldType.String, "The name of the area / neighbourhood")
    //...
}

JDS also supports Tags which can be applied to each Field and Entity definitions. Tags can be defined as a set of strings, there is no limit on how many tags a field can have. This can be useful for categorising certain kinds of information

import io.github.subiyacryolite.jds.Field;
import io.github.subiyacryolite.jds.enumProperties.FieldType;

object Fields {
    val StreetName = Field(1, "street_name", FieldType.String, description = "The street name of the address", tags = setOf("AddressInfo", "ClientInfo", "IdentifiableInfo"))
    //...
}

1.1.3 Defining Enums

JDS Enums are an extension of Fields. Usually these values would be represented by Check Boxes, Radio Buttons or Combo Boxes on the front-end.

First we'd define a standard JDS Field of type Enum.

import io.github.subiyacryolite.jds.Field
import io.github.subiyacryolite.jds.enums.FieldType

public class Fields
{
    val Direction = Field(10, "direction", FieldType.Enum)
}

Then, we can define our actual enum in the following manner.

enum class Direction {
    North, West, South, East
}

Lastly, we create an instance of the JDS Field Enum type.

import io.github.subiyacryolite.jds.FieldEnum

object Enums {
    val Directions = FieldEnum(Direction::class.java, Fields.Direction, *Direction.values())
}

Behind the scenes these Enums will be stored as either:

  • an Integer (FieldType.Enum);
  • a String (FieldType.EnumString);
  • an Integer Array (FieldType.EnumCollection); or
  • a String Collection (FieldType.EnumStringCollection)

1.1.4 Binding Properties

Depending on the type of Field, JDS will require that you set you objects properties to one of the following IValue container types.

JDS Field Type Container Java Mapping Call Kotlin Mapping Call
DateTimeCollection MutableCollection<LocalDateTime> mapDateTimes map
DoubleCollection MutableCollection<Double> mapDoubles map
EntityCollection MutableCollection<Class<? extends Entity>> map map
FloatCollection MutableCollection<Float> mapFloats map
IntCollection MutableCollection<Integer> mapInts map
LongCollection MutableCollection<Long> mapLongs map
StringCollection MutableCollection<String> mapStrings map
Boolean IValue<Boolean> mapBoolean map
Blob IValue<ByteArray> map map
Entity Class<? extends Entity> map map
Date IValue<LocalDate> mapDate map
DateTime IValue<LocalDateTime> mapDateTime map
Double IValue<Double> mapNumeric map
Duration IValue<Duration> mapDuration map
Enum IValue<Enum> mapEnum map
EnumCollection Collection<Enum> mapEnums map
Float IValue<Float> mapNumeric map
Int IValue<Integer> mapNumeric map
Long IValue<Long> mapNumeric map
MonthDay IValue<MonthDay> mapMonthDay map
Period IValue<Period> mapPeriod map
String IValue<String> mapString map
Time IValue<LocalTime> mapTime map
YearMonth IValue<YearMonth> mapYearMonth map
ZonedDateTime IValue<ZonedDateTime> mapZonedDateTime map
Uuid IValue<ZonedDateTime> mapZonedDateTime map

To simplify the mapping Process Jds has the following helper classes defined:

  • Generic containers (Entities and Enums)
    • ObjectValue
  • Non null containers
    • BlobValue
    • BooleanValue
    • DoubleValue
    • DurationValue
    • EnumValue
    • FloatValue
    • IntegerValue
    • LocalDateValue
    • LocalDateTimeValue
    • LocalTimeValue
    • LongValue
    • MonthDayValue
    • PeriodValue
    • ShortValue
    • StringValue
    • UuidValue
    • YearMonthValue
    • ZonedDateTimeValue
  • Nullable containers
    • NullableBlobValue
    • NullableBooleanValue
    • NullableDoubleValue
    • NullableDurationValue
    • NullableEnumValue
    • NullableFloatValue
    • NullableIntegerValue
    • NullableLocalDateValue
    • NullableLocalDateTimeValue
    • NullableLocalTimeValue
    • NullableLongValue
    • NullableMonthDayValue
    • NullablePeriodValue
    • NullableShortValue
    • NullableStringValue
    • NullableUuidValue
    • NullableYearMonthValue
    • NullableZonedDateTimeValue

Note: JDS assumes that all collection types will not contain null entries.

Note: Collection types can be of any valid type e.g. ArrayList, LinkedList, HashSet etc

After your class and its properties have been defined you must map the property to its corresponding Field using the map() method. I recommend doing this in your primary constructor.

The example below shows a class definition with valid properties and bindings. With this your class can be persisted.

Note that the example below has a 3rd parameter to the map method, this is the Property Name

The Property Name is used by the JDS Field Dictionary to know which property a particular Field is mapped to within an Entity.

This is necessary as one Field definition can be mapped to a different property amongst different Entities.

For example a Field called "FirstName" could be mapped to a property called "firstName" in one Entity and a property called "givenName" in another.

package io.github.subiyacryolite.jds.tests.entities

import io.github.subiyacryolite.jds.Entity
import io.github.subiyacryolite.jds.annotations.EntityAnnotation
import io.github.subiyacryolite.jds.beans.property.NullableBooleanValue
import io.github.subiyacryolite.jds.beans.property.NullableShortValue
import io.github.subiyacryolite.jds.tests.constants.Fields
import java.time.LocalDateTime

data class Address(
        private val _streetName: IValue<String> = StringValue(),
        private val _plotNumber: IValue<Short?> = NullableShortValue(),
        private val _area: IValue<String> = StringValue(),
        private val _city: IValue<String> = StringValue(),
        private val _provinceOrState: IValue<String> = StringValue(),
        private val _country: IValue<String> = StringValue(),
        private val _primaryAddress: IValue<Boolean?> = NullableBooleanValue(),
        private val _timestamp: IValue<LocalDateTime> = LocalDateTimeValue()
) : Entity(), IAddress {

    override fun bind() {
        super.bind()
        map(Fields.StreetName, _streetName, "streetName")
        map(Fields.PlotNumber, _plotNumber, "plotNumber")
        map(Fields.ResidentialArea, _area, "area")
        map(Fields.City, _city, "city")
        map(Fields.ProvinceOrState, _provinceOrState, "provinceOrState")
        map(Fields.Country, _country, "country")
        map(Fields.PrimaryAddress, _primaryAddress, "primaryAddress")
        map(Fields.TimeStamp, _timestamp, "timestamp")
    }

    var primaryAddress: Boolean?
        get() = _primaryAddress.get()
        set(value) = _primaryAddress.set(value)

    var streetName: String
        get() = _streetName.get()
        set(value) = _streetName.set(value)

    var plotNumber: Short?
        get() = _plotNumber.get()
        set(value) = _plotNumber.set(value)

    var area: String
        get() = _area.get()
        set(value) = _area.set(value)

    var city: String
        get() = _city.get()
        set(value) = _city.set(value)

    var provinceOrState: String
        get() = _provinceOrState.get()
        set(value) = _provinceOrState.set(value)

    var country: String
        get() = _country.get()
        set(value) = _country.set(value)

    var timeOfEntry: LocalDateTime
        get() = _timestamp.get()
        set(timeOfEntry) = _timestamp.set(timeOfEntry)
}

1.1.5 Binding Objects and Object Arrays

JDS can also persist embedded objects and object arrays.

All that's required is a valid Entity or IEntity subclass to be mapped to a Field of type Entity or EntityCollection .

import io.github.subiyacryolite.jds.Field
import io.github.subiyacryolite.jds.enums.FieldType

object Fields
{
    val Addresses = Field(23, "addresses", FieldType.EntityCollection, "A collection of addresses")
}
import io.github.subiyacryolite.jds.FieldEntity

object Entities {
    val Addresses: FieldEntity<Address> = FieldEntity(Address::class.java, Fields.Addresses)
}
import io.github.subiyacryolite.jds.Entity
import io.github.subiyacryolite.jds.annotations.EntityAnnotation
import io.github.subiyacryolite.jds.tests.constants.Entities

@EntityAnnotation(id = 2, name = "address_book")
data class AddressBook(
        val addresses: MutableCollection<IAddress> = ArrayList()
) : Entity() {

    override fun bind() {
        super.bind()
        map(Entities.Addresses, addresses, "addresses")
    }
}

1.2 CRUD Operations

1.2.1 Initialising the database

In order to use JDS you will need an instance of DbContext. Your instance of DbContext will have to extend one of the following classes:

  • MariaDbContext;
  • MySqlContext;
  • OracleContext;
  • SqLiteDbContext; or
  • TransactionalSqlContext

After this you must override the dataSource property.

Please note that your project must have the correct JDBC driver in its class path. The drivers that were used during development are listed under Supported Databases above.

These samples use HikariCP to provide connection pooling for enhanced performance.

Postgres example

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.github.subiyacryolite.jds.context.PostGreSqlContext
import java.io.File
import java.io.FileInputStream
import java.util.*
import javax.sql.DataSource

class PostGreSqlContextImplementation : PostGreSqlContext() {

    private val properties: Properties = Properties()
    private val hikariDataSource: DataSource

    init {
        FileInputStream(File("db.pg.properties")).use { properties.load(it) }

        val hikariConfig = HikariConfig()
        hikariConfig.driverClassName = properties["driverClassName"].toString()
        hikariConfig.maximumPoolSize = properties["maximumPoolSize"].toString().toInt()
        hikariConfig.username = properties["username"].toString()
        hikariConfig.password = properties["password"].toString()
        hikariConfig.dataSourceProperties = properties //additional props
        hikariConfig.jdbcUrl = "jdbc:postgresql://${properties["dbUrl"]}:${properties["dbPort"]}/${properties["dbName"]}"
        hikariDataSource = HikariDataSource(hikariConfig)
    }

    override val dataSource: DataSource
        get () = hikariDataSource
}

MySQL Example

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.github.subiyacryolite.jds.context.MySqlContext
import java.io.File
import java.io.FileInputStream
import java.util.*
import javax.sql.DataSource

class MySqlContextImplementation : MySqlContext() {

    private val properties: Properties = Properties()
    private val hikariDataSource: DataSource

    init {
        FileInputStream(File("db.mysql.properties")).use { properties.load(it) }

        val hikariConfig = HikariConfig()
        hikariConfig.driverClassName = properties["driverClassName"].toString()
        hikariConfig.maximumPoolSize = properties["maximumPoolSize"].toString().toInt()
        hikariConfig.username = properties["username"].toString()
        hikariConfig.password = properties["password"].toString()
        hikariConfig.dataSourceProperties = properties //additional props
        hikariConfig.jdbcUrl = "jdbc:mysql://${properties["dbUrl"]}:${properties["dbPort"]}/${properties["dbName"]}"
        hikariDataSource = HikariDataSource(hikariConfig)
    }

    override val dataSource: DataSource
        get () = hikariDataSource
}

MariaDb Example

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.github.subiyacryolite.jds.context.MariaDbContext
import java.io.File
import java.io.FileInputStream
import java.util.*
import javax.sql.DataSource

class MariaDbContextImplementation : MariaDbContext() {

    private val properties: Properties = Properties()
    private val hikariDataSource: DataSource

    init {
        FileInputStream(File("db.mariadb.properties")).use { properties.load(it) }

        val hikariConfig = HikariConfig()
        hikariConfig.driverClassName = properties["driverClassName"].toString()
        hikariConfig.maximumPoolSize = properties["maximumPoolSize"].toString().toInt()
        hikariConfig.username = properties["username"].toString()
        hikariConfig.password = properties["password"].toString()
        hikariConfig.dataSourceProperties = properties //additional props
        hikariConfig.jdbcUrl = "jdbc:mariadb://${properties["dbUrl"]}:${properties["dbPort"]}/${properties["dbName"]}"

        hikariDataSource = HikariDataSource(hikariConfig)
    }

    override val dataSource: DataSource
        get () = hikariDataSource
}

Microsoft SQL Server Example

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.github.subiyacryolite.jds.context.TransactionalSqlContext
import java.io.File
import java.io.FileInputStream
import java.util.*
import javax.sql.DataSource

class TransactionalSqlContextImplementation : TransactionalSqlContext() {

    private val properties: Properties = Properties()
    private val hikariDataSource: DataSource

    init {
        FileInputStream(File("db.tsql.properties")).use { properties.load(it) }

        val hikariConfig = HikariConfig()
        hikariConfig.driverClassName = properties["driverClassName"].toString()
        hikariConfig.maximumPoolSize = properties["maximumPoolSize"].toString().toInt()
        hikariConfig.username = properties["username"].toString()
        hikariConfig.password = properties["password"].toString()
        hikariConfig.jdbcUrl = "jdbc:sqlserver://${properties["dbUrl"]}\\${properties["dbInstance"]};databaseName=${properties["dbName"]}"
        hikariConfig.dataSourceProperties = properties //additional props
        hikariDataSource = HikariDataSource(hikariConfig)
    }

    override val dataSource: DataSource
        get () = hikariDataSource
}

Oracle Example

import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.github.subiyacryolite.jds.context.OracleContext
import java.io.File
import java.io.FileInputStream
import java.util.*
import javax.sql.DataSource

class OracleContextImplementation : OracleContext() {

    private val properties: Properties = Properties()
    private val hikariDataSource: DataSource

    init {
        FileInputStream(File("db.ora.properties")).use { properties.load(it) }

        val hikariConfig = HikariConfig()
        hikariConfig.driverClassName = properties["driverClassName"].toString()
        hikariConfig.maximumPoolSize = properties["maximumPoolSize"].toString().toInt()
        hikariConfig.username = properties["username"].toString()
        hikariConfig.password = properties["password"].toString()
        hikariConfig.dataSourceProperties = properties //additional props
        hikariConfig.jdbcUrl = "jdbc:oracle:thin:@${properties["dbUrl"]}:${properties["dbPort"]}:${properties["dbName"]}"
        hikariDataSource = HikariDataSource(hikariConfig)
    }

    override val dataSource: DataSource
        get () = hikariDataSource
}

Sqlite Example

import io.github.subiyacryolite.jds.context.SqLiteDbContext
import org.sqlite.SQLiteConfig
import org.sqlite.SQLiteDataSource
import java.io.File
import javax.sql.DataSource

class SqLiteDbContextImplementation : SqLiteDbContext() {

    private val sqLiteDataSource: DataSource

    init {
        val path = File(System.getProperty("user.home") + File.separator + ".jdstest" + File.separator + "jds.db")
        if (!path.exists())
            if (!path.parentFile.exists())
                path.parentFile.mkdirs()
        val sqLiteConfig = SQLiteConfig()
        sqLiteConfig.enforceForeignKeys(true) //You must enable foreign keys in SQLite
        sqLiteDataSource = SQLiteDataSource(sqLiteConfig)
        sqLiteDataSource.url = "jdbc:sqlite:${path.absolutePath}"
    }

    override val dataSource: DataSource
        get () {
            Class.forName("org.sqlite.JDBC")
            return sqLiteDataSource
        }
}

With this you should have a valid data source allowing you to access your database. JDS will automatically setup its tables and procedures at runtime.

Furthermore, you can use the getConnection() method OR connection property from this dataSource property in order to return a standard java.sql.Connection in your application.

1.2.2 Initialising JDS

Once you have initialised your database you can go ahead and initialise all your JDS classes. You can achieve this by mapping ALL your JDS classes in the following manner.

fun initialiseJdsClasses(dbContext: DbContext)
{
    dbContext.map(Address::class.java);
    dbContext.map(AddressBook::class.java);
}

You only have to do this once at start-up. Without this you will not be able to persist or load data.

1.2.3 Creating objects

Once you have defined your class you can initialise them. A dynamic id is created for every Entity by default (using javas UUID class). This value is used to uniquely identify an object and it data in the database. You can set your own values if you wish.

    val primaryAddress = Address()
    primaryAddress.overview.id = "primaryAddress" //explicit id defined, JDS assigns a value by default on instantiation
    primaryAddress.area = "Norte Broad"
    primaryAddress.city = "Livingstone"
    primaryAddress.country = "Zambia"
    primaryAddress.plotNumber = null
    primaryAddress.provinceOrState = "Southern"
    primaryAddress.streetName = "East Street"
    primaryAddress.timeOfEntry = LocalTime.now()
    primaryAddress.primaryAddress = PrimaryAddress.YES

1.2.4 Saving objects (Portable Format)

...

1.2.5 Loading objects (Portable Format)

...

Development

I highly recommend the use of the IntelliJ IDE for development.

Contributing to Jenesis Data Store

If you would like to contribute code you can do so through Github by forking the repository and sending a pull request targeting the current development branch.

When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible.

Bugs and Feedback

For bugs, questions and discussions please use the Github Issues.

Special Thanks

To all our users and contributors!

You might also like...
LiteOrm is a fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line of code efficiently.

#LiteOrm:Android高性能数据库框架 A fast, small, powerful ORM framework for Android. LiteOrm makes you do CRUD operarions on SQLite database with a sigle line

JAKO: Just Another Kotlin Orm (PostgreSQL)
JAKO: Just Another Kotlin Orm (PostgreSQL)

JAKO: Just Another Kotlin Orm (PostgreSQL) JAKO is a simple, minimal, no-dependency library to build and execute postgresql statements using a fluent

A simple NoSQL client for Android. Meant as a document store using key/value pairs and some rudimentary querying. Useful for avoiding the hassle of SQL code.

SimpleNoSQL A simple NoSQL client for Android. If you ever wanted to just save some data but didn't really want to worry about where it was going to b

A Java/Kotlin library for Android platform, to manage bean's persistence in SQLite, SharedPreferences, JSON, XML, Properties, Yaml, CBOR.
A Java/Kotlin library for Android platform, to manage bean's persistence in SQLite, SharedPreferences, JSON, XML, Properties, Yaml, CBOR.

Thanks to JetBrains for support Kripton Persistence Library project! Kripton Persistence Library Kripton is a java library, for Android platform, that

An app with implementation of Room database for Android platform

Room Room An app with implementation of Room database for Android platform The Room persistence library provides an abstraction layer over SQLite to a

Implementation of MVVM , Live Data and Room DAO for a robust materialistic design
Implementation of MVVM , Live Data and Room DAO for a robust materialistic design

Someday App to manage Weekly tasks Because who needs to remind you every week to do Samething Preview Main Layout Light Dark Main Layout (Expanded) Li

Core Data for Android

NexusData Core Data for Android NexusData is an object graph and persistence framework for Android. It allows for organizing and managing relational d

A tool to convert & query Apache Calcite data sources as GraphQL API's
A tool to convert & query Apache Calcite data sources as GraphQL API's

Apache Calcite - Distributed, Federated GraphQL API Apache Calcite - Distributed, Federated GraphQL API Goals Roadmap and Current Progress The Roa

LiteGo is a Java-based asynchronous concurrency library. It has a smart executor, which can be freely set the maximum number of concurrent at same time , and the number of threads in waiting queue. It can also set waiting policies and overload strategies.

LiteGo:「迷你」的Android异步并发类库 LiteGo是一款基于Java语言的「异步并发类库」,它的核心是一枚「迷你」并发器,它可以自由地设置同一时段的最大「并发」数量,等待「排队」线程数量,还可以设置「排队策略」和「超载策略」。 LiteGo可以直接投入Runnable、Callable

Comments
  • Add the ability to create views representing entities as tuples

    Add the ability to create views representing entities as tuples

    Add the ability to create views representing entities as tuples

    public boolean createView(JdsEntity entity) public boolean createViews(JdsEntity... entities)

    enhancement 
    opened by SubiyaCryolite 3
  • Make JDS entities serializable

    Make JDS entities serializable

    Implement writeObject(ObjectOutputStream s) and readObject(ObjectInputStream s).

    Properties will have to be serialized and serialized in the same order though. Sort by Field-id for consistency I guess

    enhancement 
    opened by SubiyaCryolite 1
Releases(v20.4)
  • v20.4(Aug 26, 2020)

    • Added Serialization support to portable types
    • Improved memory usage & RT performance by making mapping either one time or "optional" via the bind() method
    • Numerous optimizations and code refactoring
    • Stripped out unused functionality (Schema creation, EAV code)
    Source code(tar.gz)
    Source code(zip)
  • v9.2.0(May 5, 2018)

    Significant changes and features added to JDS

    • Robust flat table generation functionality
    • Granular options and control
    • Performance and stability enhancements
    • Optimized database structure and standardized naming convension
    Source code(tar.gz)
    Source code(zip)
  • v4.1.6(Jan 14, 2018)

    • Increased size of primary key from 48 - 96
    • Added the ability to truncate custom tables
    • Added co-variance to Entity and Entity Collection mappers (Covariant)
    • Fixed bug with same field being bound in multiple entities
    • Compacted portable JSON of embedded save/load
    • Fixed HUGE performance issues in general
    • Added ability to run custom sql code on batch save in JdsSave
    • Added tag to control the writing of Overview fields
    • Fixed bug with JdsTables not seeing superclass JdsAnnotation
    • JDS Tables now contain an EntityId column in order to determine the source of a specific entry
    Source code(tar.gz)
    Source code(zip)
  • v4.0.4(Nov 14, 2017)

  • v4.0.3(Nov 14, 2017)

  • v4.0.0(Nov 1, 2017)

    • Breaks compatibility with older versions
    • Supports new time types: Period, Duration, YearMonth, MonthDay
    • Added support for alternate connections (i.e to reporting or backup dbs), as well as associated methods for CRUD events
    • Adding dynamic Schema generation capabilities with support for native column types
    Source code(tar.gz)
    Source code(zip)
  • v4.0.0-SNAPSHOT(Oct 18, 2017)

    • Supports multiple properties of the JdsEntity in one class
    • Supports 4 new time constructs: Period, Duration, YearMonth and MonthYear
    • Fixed View generation in Oracle
    • Fixed incorrect column types for Long in MySQL and TSQL
    • BREAKS all backward compatibility :(
    Source code(tar.gz)
    Source code(zip)
  • v3.4.3(Oct 18, 2017)

  • v3.2.3(Aug 10, 2017)

  • 3.2.0(Aug 3, 2017)

    • Added support for Oracle 11G
    • Added filter support for Oracle
    • Adding preliminary View support for Oracle
    • Fixing SQL issues with Oracle implementation
    • Fixed bug with batch save implementation
    • Performance enhancements all around
    Source code(tar.gz)
    Source code(zip)
  • v2.17.0726b(Jul 27, 2017)

    • Fixed bug with SQLConnection not set to AutoCommiti(true) in PostSave events
    • Renamed setters for global properties: -- printOutput -> isPrintingOutput -- logEdits -> isLoggingEdits -- !isPersistingChangesOnly -> isWritingToPrimaryDataTables
    Source code(tar.gz)
    Source code(zip)
  • v2.17.0724(Jul 24, 2017)

  • v2.17.0718b(Jul 18, 2017)

    • Added support for the persistence of atomic Enum fields
    • Generated views now support Enums
    • Fixed bug in-which filtered JDS load always return an object (default empty)
    • Memory optimizations via use of Stream<> in JDSLoad
    • Added JdsDeleteListener to the library
    • Consolidated existing post and pre listeners into JdsSaveListener, JdsLoadListener
    Source code(tar.gz)
    Source code(zip)
  • v2.17.0711(Jul 11, 2017)

    Features

    • Fully backward compatible with V1 databases
    • Optimized View generation
    • Object inheritance View will never be affected regardless of how you save the object
    • Binary values will be saved in the old table as well

    Planned Features

    • SQLite wont use ridiculous replace or insert into
    • Saving enum as single object, not just array [month, sex]
    Source code(tar.gz)
    Source code(zip)
  • v1.170708(Jul 8, 2017)

    • JDS now maps native Java Enums as opposed to String collections before
    • Only modifications are persisted to the log table, as opposed to any commit before
    Source code(tar.gz)
    Source code(zip)
  • v1.170705(Jul 5, 2017)

  • v1.170626(Jun 25, 2017)

    • Reworked Entity map implementation
    • Completed View implementation. JDS can now create views in MySQL, PostgreSQL and TSQL to represent entities as rows.
    • Completed the Filter implementation. The following operations are supported:
      • equals
      • notEquals
      • like
      • startsLike
      • endsLike
      • notLike
      • in
      • notIn
      • greaterThan
      • greaterThanOrEqualTo
      • lessThan
      • lessThanOrEqualTo
      • notLessThan
      • notGreaterThan
      • isNull
      • isNotNull
      • between
    Source code(tar.gz)
    Source code(zip)
  • v1.170619c(Jun 23, 2017)

    • Added support for Blobs
    • Fixed bug with MySQL implementation when several databases on the same instance use JDS
    • Fixed bug with TSQL implementation of BLOB store
    • Fixed another bug in the MySQL
    Source code(tar.gz)
    Source code(zip)
  • 1.170619(Jun 19, 2017)

  • 1.170619b(Jun 19, 2017)

    • Added support for Blobs
    • Fixed bug with MySQL implementation when several databases on the same instance use JDS
    • Fixed bug with TSQL implementation of BLOB store
    Source code(tar.gz)
    Source code(zip)
  • v1.170531(May 31, 2017)

    • Added support for listeners via four new interfaces:
      • JdsPostLoadListener
      • JdsPostSaveListener
      • JdsPreLoadListener
      • JdsPreSaveListener
    • New save implementation relies on one SQL connection. This is primarily to assist with SQLites file-locking interrupting embedded object saves, but also for performance.
    Source code(tar.gz)
    Source code(zip)
  • 1.170531b(May 31, 2017)

    • New save implementation relies on one SQL connection. This is primarily to assist with SQLites file-locking interrupting embedded object saves, but also for performance.
    • Added new enhancement to embedded object array saves as well
    • Added support for listeners via four new interfaces:
      • JdsPostLoadListener
      • JdsPostSaveListener
      • JdsPreLoadListener
      • JdsPreSaveListener
    Source code(tar.gz)
    Source code(zip)
  • v1.170514(May 14, 2017)

    Save, Load, Delete and Filter implement the Callable interface. Old static methods are now marked deprecated and use blocking .call() implementations in the background. This was to allow for easy async implementations in target applications

    Source code(tar.gz)
    Source code(zip)
  • v1.170511(May 11, 2017)

  • v1.170414(Apr 14, 2017)

  • v1.170405(Apr 4, 2017)

  • 1.170402(Apr 2, 2017)

  • v1.170402-SNAPSHOT(Apr 2, 2017)

Owner
Ifunga Ndana
General Ninja License
Ifunga Ndana
A blazing fast, powerful, and very simple ORM android database library that writes database code for you.

README DBFlow is fast, efficient, and feature-rich Kotlin database library built on SQLite for Android. DBFlow utilizes annotation processing to gener

Andrew Grosner 4.9k Dec 30, 2022
A blazing fast, powerful, and very simple ORM android database library that writes database code for you.

README DBFlow is fast, efficient, and feature-rich Kotlin database library built on SQLite for Android. DBFlow utilizes annotation processing to gener

Andrew Grosner 4.9k Dec 30, 2022
lightweight and minimalist ORM for Java/Android. works with SQLite & MySQL. (not actively maintained)

Description ORMAN is an minimalistic and lightweight ORM framework for Java which can handle your common database usage without writing SQL and strugg

Ahmet Alp Balkan 246 Nov 20, 2022
lightweight and minimalist ORM for Java/Android. works with SQLite & MySQL. (not actively maintained)

Description ORMAN is an minimalistic and lightweight ORM framework for Java which can handle your common database usage without writing SQL and strugg

Ahmet Alp Balkan 246 Nov 20, 2022
An ORM for Android with type-safety and painless smart migrations

Android Orma Orma is a ORM (Object-Relation Mapper) for Android SQLiteDatabase. Because it generates helper classes at compile time with annotation pr

The Maskarade project 440 Nov 25, 2022
greenDAO is a light & fast ORM solution for Android that maps objects to SQLite databases.

Check out ObjectBox Check out our new mobile database ObjectBox (GitHub repo). ObjectBox is a superfast object-oriented database with strong relation

Markus Junginger 12.6k Jan 3, 2023
Android ORM

Shillelagh Shillelagh is an sqlite library. It was built to make life easier. The entire library was built around simplicity when using sqlite in Andr

Andrew Reitz 49 Sep 11, 2020
Compile-time active record ORM for Android

Ollie Compile-time active record ORM for Android. Multiple mapping methods. SQLiteDatabase-like interface (QueryUtils.java). Lightweight query builder

Michael Pardo 423 Dec 30, 2022
a 3d database ORM experiment. (used in two commercial projects)

Android-TriOrm a 3d database ORM experiment for Android. (used in two commercial projects). based around small tables concept and JVM Serialization. H

Tomer Shalev 19 Nov 24, 2021
ORMDroid is a simple ORM persistence framework for your Android applications.

ORMDroid is a simple ORM persistence framework for your Android applications, providing an easy to use, almost-zero-config way to handle model persist

Ross Bamford 87 Nov 10, 2022