{"id":16119387,"url":"https://github.com/darkredz/zeko-data-mapper","last_synced_at":"2025-03-16T08:32:48.470Z","repository":{"id":37270683,"uuid":"97022335","full_name":"darkredz/Zeko-Data-Mapper","owner":"darkredz","description":"A lightweight data mapper library in Kotlin that helps to map the result of queries from your normalized dataset(from RDBMS or any source) back into relational mapped Hash maps","archived":false,"fork":false,"pushed_at":"2024-05-02T06:34:26.000Z","size":357,"stargazers_count":18,"open_issues_count":3,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-27T05:56:28.475Z","etag":null,"topics":["data-mapper","data-structure","jasync-sql","kotlin","rdbms","vertx","zeko"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darkredz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-12T15:15:38.000Z","updated_at":"2024-09-04T15:04:13.000Z","dependencies_parsed_at":"2024-05-02T07:46:04.356Z","dependency_job_id":"1285fdf7-9b3a-4036-9b95-d71d2f36585f","html_url":"https://github.com/darkredz/Zeko-Data-Mapper","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkredz%2FZeko-Data-Mapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkredz%2FZeko-Data-Mapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkredz%2FZeko-Data-Mapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkredz%2FZeko-Data-Mapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darkredz","download_url":"https://codeload.github.com/darkredz/Zeko-Data-Mapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243807471,"owners_count":20350999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-mapper","data-structure","jasync-sql","kotlin","rdbms","vertx","zeko"],"created_at":"2024-10-09T20:54:01.048Z","updated_at":"2025-03-16T08:32:47.935Z","avatar_url":"https://github.com/darkredz.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Zeko Data Mapper\n![alt Zeko Data Mapper](./docs/assets/zeko-rabbit.svg \"Zeko lightweight data mapper\")\n\n\u003cp align=\"left\"\u003e\n    \u003ca href=\"https://search.maven.org/search?q=g:%22io.zeko%22\"\u003e\n        \u003cimg src=\"https://img.shields.io/maven-central/v/io.zeko/zeko-data-mapper.svg?label=Maven%20Central\" alt=\"Maven Central\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"LICENSE\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/license-Apache%202-blue.svg?maxAge=2592000\" alt=\"Apache License 2\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/KotlinBy/awesome-kotlin\"\u003e\n        \u003cimg src=\"https://kotlin.link/awesome-kotlin.svg\" alt=\"Awesome Kotlin Badge\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\nA lightweight, fast and simple data mapper library in Kotlin that helps to map the result of queries from your normalized dataset(from RDBMS, SQLite, CSV or any source) back into relational mapped Hash maps\n\nps: Zeko turns out to be rabbit in Croatian, thus the logo :D\n\n[Show your ❤ with a ★](https://github.com/darkredz/Zeko-Data-Mapper/stargazers)\n\n### To use, add these to your maven pom.xml\n\n    \u003cdependency\u003e\n      \u003cgroupId\u003eio.zeko\u003c/groupId\u003e\n      \u003cartifactId\u003ezeko-data-mapper\u003c/artifactId\u003e\n      \u003cversion\u003e1.6.7\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n    \n## Features\n- No configuration files, no XML, no YAML, no annotations, lightweight, easy to use\n- Fast startup \u0026 performance\n- No Reflections. Great for [GraalVM](https://www.graalvm.org/) and [Quarkus](https://quarkus.io/)\n    \n## Basic usage\nUse this library to denormalized your data from a plaintext CSV, in-memory data, RDBMS tables, etc.\nInstead of using an ORM, do whatever you need to query \u0026 retrieve your normalized data, and mapped the data back \ninto a relational nested object which make sense to your system.\n\n### Configuring relationship of the normalized data\nGiven a MySQL database with tables of user, role and address, where each user should have one or more address and can have multiple roles. Every roles can be assigned to more than one users. So user-role is a many to many (M:M) relationship, user-address is 1:M relationship\n\n![alt relationship between tables](./docs/assets/zeko-test-schema.jpg \"Relationship between tables\")\n \n\n```kotlin\nval table = linkedMapOf\u003cString, TableInfo\u003e()\ntable[\"user\"] = TableInfo(key = \"id\")\ntable[\"role\"] = TableInfo(key = \"id\", move_under = \"user\", foreign_key = \"user_id\", many_to_many = true)\ntable[\"address\"] = TableInfo(key = \"id\", move_under = \"user\", foreign_key = \"user_id\", many_to_one = true) \n```\n\n### Using DataMapper class\nDataMapper::map accepts the mapper config of your tables which it uses to understand the relationship of the flatten data structure.\nPass in the results of your sql query with the field names (with table name as prefix) to mapped the result.\nMore example can be found in [DataMapperSpec](https://github.com/darkredz/Zeko-Data-Mapper/blob/master/src/test/kotlin/com.zeko.model/DataMapperSpec.kt)\n\nExample:\n```kotlin\nval rawResults = ArrayList\u003cLinkedHashMap\u003cString, Any\u003e\u003e()\nrawResults.add(linkedMapOf(\n    \"user-id\" to 1,\n    \"user-name\" to \"Leng\",\n    \"role-id\" to 2,\n    \"role-role_name\" to \"Super Admin\",\n    \"role-user_id\" to 1,   //this is selected as alias, not actual field in table. To be used with the mapper\n    \"address-id\" to 128,\n    \"address-user_id\" to 1,\n    \"address-street1\" to \"Some block\",\n    \"address-street2\" to \"in the street\"\n))\n```\nMap the raw results into a denormalized structure\n```kotlin\nval mapper = DataMapper()\nval result = mapper.map(tables, rawResults)\nval json = Json.encodePrettily(result)\nprintln(json)\n```\n\nmap() method accepts a third argument which is to specify the delimiter of the column name, eg. user-id\nBy default it uses \"-\" but you can always change it when calling map()\n```kotlin\nmapper.map(tables, rawResults, \"-\")\n\n```\n\nThis will give you a list of users with role and address nested under user's role and address field.\n```json\n[ {\n  \"id\" : 1,\n  \"name\" : \"Leng\",\n  \"role\" : [ {\n    \"id\" : 2,\n    \"user_id\" : 1,\n    \"role_name\" : \"super admin\"\n  } ],\n  \"address\" : [ {\n    \"id\" : 1,\n    \"user_id\" : 1,\n    \"street1\" : \"Jalan 123\",\n    \"street2\" : \"Taman Tun\"\n  }, {\n    \"id\" : 3,\n    \"user_id\" : 1,\n    \"street1\" : \"Jalan Bunga\",\n    \"street2\" : \"Taman Negara\"\n  } ]\n} ]\n``` \n \n Notice that user_id field is in the role and address data which is quite redundant in many cases. \n To automatically remove those linked field from the mapped result, set the list of fields in TableInfo remove property.\n ```kotlin\n val table = linkedMapOf\u003cString, TableInfo\u003e()\n table[\"user\"] = TableInfo(key = \"id\")\n table[\"role\"] = TableInfo(remove = listOf(\"user_id\"), key = \"id\", move_under = \"user\", foreign_key = \"user_id\", many_to_many = true)\n table[\"address\"] = TableInfo(remove = listOf(\"user_id\"), key = \"id\", move_under = \"user\", foreign_key = \"user_id\", many_to_one = true) \n ```\n\nThis will give you a result of\n```json\n[ {\n  \"id\" : 1,\n  \"name\" : \"Leng\",\n  \"role\" : [ {\n    \"id\" : 2,\n    \"role_name\" : \"super admin\"\n  } ],\n  \"address\" : [ {\n    \"id\" : 1,\n    \"street1\" : \"Jalan 123\",\n    \"street2\" : \"Taman Tun\"\n  }, {\n    \"id\" : 3,\n    \"street1\" : \"Jalan Bunga\",\n    \"street2\" : \"Taman Negara\"\n  } ]\n} ]\n```\n\nUse MapperConfig class to conveniently set relationship without figuring out the order of nested data and removal of redundant field.\nThe same relationship just now can be defined as the following with MapperConfig\n```kotlin\n// id is the default primary key of all tables, so you don't have to define for every table\n// true auto removes the linked fields such as user_id here\n\nval tables = MapperConfig(\"id\", true)  \n    .table(\"user\")\n    .table(\"role\").manyToMany(true).moveUnder(\"user\").foreignKey(\"user_id\")\n    .table(\"address\").manyToOne(true).moveUnder(\"user\").foreignKey(\"user_id\")\n```\n\n### Example usage with [Jasync-sql](https://github.com/jasync-sql/jasync-sql) queries\nFor the DB schema above, you can find the example Zeko usage with [Jasync-sql here](https://github.com/darkredz/Zeko-Data-Mapper/blob/dev/examples/zeko-vertx-query/src/main/kotlin/com/zeko/example/MainVerticle.kt#L35).\nThe SQL structure and data for the sample app is [provided](https://github.com/darkredz/Zeko-Data-Mapper/tree/dev/examples/sql) too.\n\nJasync-sql is a port of [mauricio/postgresql-async](https://github.com/mauricio/postgresql-async), to Kotlin.\n\n### Example usage with [Vert.x Common-sql](http://vertx.io/docs/vertx-sql-common/kotlin) queries\nIf you use Vert.x common sql interface, such as the async [MySQL and postgresql client](https://vertx.io/docs/vertx-mysql-postgresql-client/java/)\nwhich uses Mauricio Linhares [async driver](https://github.com/mauricio/postgresql-async), you will find that the result return is typed as List of JsonArray\n\nExample using Zeko with vertx common sql results can be [found here](https://github.com/darkredz/Zeko-Data-Mapper/blob/dev/examples/zeko-vertx-query/src/main/kotlin/com/zeko/example/MainVerticle.kt#L112)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkredz%2Fzeko-data-mapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarkredz%2Fzeko-data-mapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkredz%2Fzeko-data-mapper/lists"}