FEATURE: Marshallable serializer (#25)

FEATURE: Marshallable serializer (#25)

We can not use json for serialization cause dates are not de-serializable in any simple way, rely on Marshal instead.

diff --git a/lib/mini_sql/serializer.rb b/lib/mini_sql/serializer.rb
index 2bea962..3b023a1 100644
--- a/lib/mini_sql/serializer.rb
+++ b/lib/mini_sql/serializer.rb
@@ -1,26 +1,40 @@
 # frozen_string_literal: true
 
 module MiniSql
-  module Serializer
+  class Serializer < Array
     MAX_CACHE_SIZE = 500
 
-    def self.to_json(result)
-      wrapper =
-        if result.length == 0
-          {}
-        else
-          {
-            "decorator" => result[0].class.decorator.to_s,
-            "fields" => result[0].to_h.keys,
-            "data" => result.map(&:values),
-          }
-        end
+    def initialize(result)
+      replace(result)
+    end
+
+    def self.marshallable(result)
+      new(result)
+    end
+
+    def _dump(level)
+      JSON.generate(serialize)
+    end
 
-      JSON.generate(wrapper)
+    def self._load(dump)
+      materialize(JSON.parse(dump))
+    end
+
+    private
+
+    def serialize
+      if length == 0
+        {}
+      else
+        {
+          "decorator" => first.class.decorator.to_s,
+          "fields" => first.to_h.keys,
+          "data" => map(&:values),
+        }
+      end
     end
 
-    def self.from_json(json)
-      wrapper = JSON.parse(json)
+    def self.materialize(wrapper)
       if !wrapper["data"]
         []
       else
diff --git a/test/mini_sql/connection_tests.rb b/test/mini_sql/connection_tests.rb
index 5a82254..2b58462 100644
--- a/test/mini_sql/connection_tests.rb
+++ b/test/mini_sql/connection_tests.rb
@@ -151,20 +151,20 @@ module MiniSql::ConnectionTests
     assert_nil(r.class.decorator)
   end
 
-  def test_serializers
+  def test_serializer_marshal
     r = @connection.query("select 1 one, 'two' two")
-    json = MiniSql::Serializer.to_json(r)
-    r = MiniSql::Serializer.from_json(json)
+    dump = Marshal.dump(MiniSql::Serializer.marshallable(r))
+    r = Marshal.load(dump)
 
     assert_equal(r[0].one, 1)
     assert_equal(r[0].two, "two")
     assert_equal(r.length, 1)
   end
 
-  def test_serializer_with_decorator
+  def test_serializer_marshal_with_decorator
     r = @connection.query_decorator(ProductDecorator, 'select 20 price, 3 quantity')
-    json = MiniSql::Serializer.to_json(r)
-    r = MiniSql::Serializer.from_json(json)
+    dump = Marshal.dump(MiniSql::Serializer.marshallable(r))
+    r = Marshal.load(dump)
 
     assert_equal(r[0].price, 20)
     assert_equal(r[0].quantity, 3)

GitHub sha: 3e08323f

This commit appears in #25 which was merged by SamSaffron.