From 9ca0b19d9e83173bed07d30e779997258219b475 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 4 Jul 2016 12:46:45 -0300 Subject: [PATCH] Support mappable classes in query_one and query_all methods --- spec/mapping_spec.cr | 19 +++++++++++++++++++ src/db/mapping.cr | 5 +++++ src/db/result_set.cr | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/spec/mapping_spec.cr b/spec/mapping_spec.cr index 8c622af..42362fd 100644 --- a/spec/mapping_spec.cr +++ b/spec/mapping_spec.cr @@ -131,4 +131,23 @@ describe "DB.mapping" do end end + it "should initialize from a query_one" do + with_dummy do |db| + obj = db.query_one "1,a", as: SimpleMapping + obj.c0.should eq(1) + obj.c1.should eq("a") + end + end + + it "should initialize from a query_all" do + with_dummy do |db| + objs = db.query_all "1,a 2,b", as: SimpleMapping + objs.size.should eq(2) + objs[0].c0.should eq(1) + objs[0].c1.should eq("a") + objs[1].c0.should eq(2) + objs[1].c1.should eq("b") + end + end + end diff --git a/src/db/mapping.cr b/src/db/mapping.cr index 126b4c8..b7b0093 100644 --- a/src/db/mapping.cr +++ b/src/db/mapping.cr @@ -1,5 +1,8 @@ module DB + # Empty module used for marking a class as supporting DB:Mapping + module Mappable; end + # The `DB.mapping` macro defines how an object is built from a DB::ResultSet. # # It takes hash literal as argument, in which attributes and types are defined. @@ -56,6 +59,8 @@ module DB # # This macro also declares instance variables of the types given in the mapping. macro mapping(properties, strict = true) + include DB::Mappable + {% for key, value in properties %} {% properties[key] = {type: value} unless value.is_a?(HashLiteral) || value.is_a?(NamedTupleLiteral) %} {% end %} diff --git a/src/db/result_set.cr b/src/db/result_set.cr index c6a5f09..a3a4e6d 100644 --- a/src/db/result_set.cr +++ b/src/db/result_set.cr @@ -64,6 +64,11 @@ module DB # Reads the next column value abstract def read + # Reads the next columns and maps them to a class + def read(type : DB::Mappable.class) + type.new(self) + end + # Reads the next column value as a **type** def read(type : T.class) : T read.as(T)