Skip to content

Commit

Permalink
Bcardiff crystal 0.36.0 (#443)
Browse files Browse the repository at this point in the history
* Add type restriction to Base#clear(table_name : String)

* Add type restrictions to Granite::Adapter::Base

* Update to crystal-db ~> 0.10.0

* remove UUID Converter

The latest database libraries support UUID.  This removes the UUID
converter.

* restore Enum converter

Co-authored-by: Brian J. Cardiff <bcardiff@gmail.com>
  • Loading branch information
drujensen and bcardiff committed Feb 22, 2021
1 parent af10c18 commit 64ff39f
Show file tree
Hide file tree
Showing 10 changed files with 23 additions and 132 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
@@ -1,4 +1,4 @@
FROM crystallang/crystal:0.35.1
FROM crystallang/crystal:0.36.1

ARG sqlite_version=3110000
ARG sqlite_version_year=2016
Expand Down
3 changes: 1 addition & 2 deletions docs/models.md
Expand Up @@ -169,11 +169,10 @@ end

Granite supports custom/special types via converters. Converters will convert the type into something the database can store when saving the model, and will convert the returned database value into that type on read.

Each converter has a `T` generic argument that tells the converter what type should be read from the `DB::ResultSet`. For example, if you wanted to use the `UUID` converter and your underlying database column is `BLOB`, you would use `Bytes`, if it was `TEXT`, you would use `String`.
Each converter has a `T` generic argument that tells the converter what type should be read from the `DB::ResultSet`. For example, if you wanted to use the `JSON` converter and your underlying database column is `BLOB`, you would use `Bytes`, if it was `TEXT`, you would use `String`.

Currently Granite supports various converters, each with their own supported database column types:

- `Uuid(T)` - Converts a `UUID` to/from a database column of type `T`. Supported types for `T` are: `String`, and `Bytes`.
- `Enum(E, T)` - Converts an Enum of type `E` to/from a database column of type `T`. Supported types for `T` are: `Number`, `String`, and `Bytes`.
- `Json(M, T)` - Converters an `Object` of type `M` to/from a database column of type `T.` Supported types for `T` are: `String`, `JSON::Any`, and `Bytes`.
- **NOTE:** `M` must implement `#to_json` and `.from_json` methods.
Expand Down
8 changes: 4 additions & 4 deletions shard.yml
Expand Up @@ -13,20 +13,20 @@ license: MIT
dependencies:
db:
github: crystal-lang/crystal-db
version: ~> 0.9.0
version: ~> 0.10.0

development_dependencies:
mysql:
github: crystal-lang/crystal-mysql
version: ~> 0.11.1
version: ~> 0.12.0

sqlite3:
github: crystal-lang/crystal-sqlite3
version: ~> 0.16.0
version: ~> 0.17.0

pg:
github: will/crystal-pg
version: ~> 0.21.1
version: ~> 0.23.0

ameba:
github: crystal-ameba/ameba
Expand Down
66 changes: 6 additions & 60 deletions spec/granite/converters/converters_spec.cr
Expand Up @@ -15,10 +15,6 @@ describe Granite::Converters do
model.enum_enum.should be_nil
model.binary_enum.should be_nil

# UUID
model.string_uuid.should be_nil
model.binary_uuid.should be_nil

# Numeric
model.numeric.should be_nil

Expand All @@ -29,10 +25,9 @@ describe Granite::Converters do
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid, numeric: Math::PI.round(20)
model = ConverterModel.new numeric: Math::PI.round(20)

model.binary_json = model.string_jsonb = model.string_json = obj

Expand All @@ -52,10 +47,6 @@ describe Granite::Converters do
model.enum_enum.should eq MyEnum::Three
model.binary_enum.should eq MyEnum::Four

# UUID
model.string_uuid.should eq uuid
model.binary_uuid.should eq uuid

# Numeric
model.numeric.should eq Math::PI.round(20)

Expand All @@ -81,10 +72,6 @@ describe Granite::Converters do
retrieved_model.enum_enum.should be_nil
retrieved_model.binary_enum.should be_nil

# UUID
retrieved_model.string_uuid.should be_nil
retrieved_model.binary_uuid.should be_nil

# Numeric
retrieved_model.numeric.should be_nil

Expand All @@ -95,10 +82,9 @@ describe Granite::Converters do
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid, numeric: Math::PI.round(20)
model = ConverterModel.new numeric: Math::PI.round(20)

model.binary_json = model.string_jsonb = model.string_json = obj

Expand All @@ -120,10 +106,6 @@ describe Granite::Converters do
retrieved_model.enum_enum.should eq MyEnum::Three
retrieved_model.binary_enum.should eq MyEnum::Four

# UUID
retrieved_model.string_uuid.should eq uuid
retrieved_model.binary_uuid.should eq uuid

# Numeric
retrieved_model.numeric.should eq Math::PI.round(20)

Expand All @@ -145,20 +127,15 @@ describe Granite::Converters do
model.string_enum.should be_nil
model.binary_enum.should be_nil

# UUID
model.string_uuid.should be_nil
model.binary_uuid.should be_nil

# JSON
model.string_json.should be_nil
model.binary_json.should be_nil
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid
model = ConverterModel.new

model.binary_json = model.string_json = obj

Expand All @@ -174,10 +151,6 @@ describe Granite::Converters do
model.string_enum.should eq MyEnum::Two
model.binary_enum.should eq MyEnum::Four

# UUID
model.string_uuid.should eq uuid
model.binary_uuid.should eq uuid

# JSON
model.string_json.should eq obj
model.binary_json.should eq obj
Expand All @@ -197,20 +170,15 @@ describe Granite::Converters do
retrieved_model.string_enum.should be_nil
retrieved_model.binary_enum.should be_nil

# UUID
retrieved_model.string_uuid.should be_nil
retrieved_model.binary_uuid.should be_nil

# JSON
retrieved_model.string_json.should be_nil
retrieved_model.binary_json.should be_nil
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid
model = ConverterModel.new

model.binary_json = model.string_json = obj

Expand All @@ -228,10 +196,6 @@ describe Granite::Converters do
retrieved_model.string_enum.should eq MyEnum::Two
retrieved_model.binary_enum.should eq MyEnum::Four

# UUID
retrieved_model.string_uuid.should eq uuid
retrieved_model.binary_uuid.should eq uuid

# JSON
retrieved_model.string_json.should eq obj
retrieved_model.binary_json.should eq obj
Expand All @@ -250,20 +214,15 @@ describe Granite::Converters do
model.enum_enum.should be_nil
model.binary_enum.should be_nil

# UUID
model.string_uuid.should be_nil
model.binary_uuid.should be_nil

# JSON
model.string_json.should be_nil
model.binary_json.should be_nil
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid
model = ConverterModel.new

model.binary_json = model.string_json = obj

Expand All @@ -281,10 +240,6 @@ describe Granite::Converters do
model.enum_enum.should eq MyEnum::Three
model.binary_enum.should eq MyEnum::Four

# UUID
model.string_uuid.should eq uuid
model.binary_uuid.should eq uuid

# JSON
model.string_json.should eq obj
model.binary_json.should eq obj
Expand All @@ -305,20 +260,15 @@ describe Granite::Converters do
retrieved_model.enum_enum.should be_nil
retrieved_model.binary_enum.should be_nil

# UUID
retrieved_model.string_uuid.should be_nil
retrieved_model.binary_uuid.should be_nil

# JSON
retrieved_model.string_json.should be_nil
retrieved_model.binary_json.should be_nil
end

it "should handle actual values" do
uuid = UUID.random
obj = MyType.new

model = ConverterModel.new binary_uuid: uuid, string_uuid: uuid
model = ConverterModel.new

model.binary_json = model.string_json = obj

Expand All @@ -338,10 +288,6 @@ describe Granite::Converters do
retrieved_model.enum_enum.should eq MyEnum::Three
retrieved_model.binary_enum.should eq MyEnum::Four

# UUID
retrieved_model.string_uuid.should eq uuid
retrieved_model.binary_uuid.should eq uuid

# JSON
retrieved_model.string_json.should eq obj
retrieved_model.binary_json.should eq obj
Expand Down
44 changes: 0 additions & 44 deletions spec/granite/converters/uuid_spec.cr

This file was deleted.

1 change: 0 additions & 1 deletion spec/granite/select/select_spec.cr
Expand Up @@ -35,7 +35,6 @@ describe "custom select" do
end

# TODO: `find` on this ViewModel fails because "id" is ambiguous in a complex SELECT.

# it "uses custom SQL to populate a view model - #find" do
# first = Article.new.tap do |model|
# model.articlebody = "The Article Body"
Expand Down
6 changes: 3 additions & 3 deletions spec/mocks/db_mock.cr
Expand Up @@ -31,11 +31,11 @@ class FakeConnection < DB::Connection
end

def build_unprepared_statement(query) : FakeStatement
FakeStatement.new self
FakeStatement.new self, query
end

def build_prepared_statement(query) : FakeStatement
FakeStatement.new self
FakeStatement.new self, query
end
end

Expand All @@ -55,7 +55,7 @@ class FieldEmitter < DB::ResultSet
@values = [] of EmitterType

def initialize
@statement = FakeStatement.new FakeConnection.new
@statement = FakeStatement.new FakeConnection.new, ""
end

def _set_values(values : Array(EmitterType))
Expand Down
15 changes: 3 additions & 12 deletions spec/spec_models.cr
Expand Up @@ -394,15 +394,15 @@ end
connection {{ adapter_literal }}
table uuids

column uuid : UUID?, primary: true, converter: Granite::Converters::Uuid(String)
column uuid : UUID?, primary: true
end

class UUIDNaturalModel < Granite::Base
connection {{ adapter_literal }}
table uuids

column uuid : UUID, primary: true, converter: Granite::Converters::Uuid(String), auto: false
column field_uuid : UUID?, converter: Granite::Converters::Uuid(String)
column uuid : UUID, primary: true, auto: false
column field_uuid : UUID?
end

class TodoJsonOptions < Granite::Base
Expand Down Expand Up @@ -552,9 +552,6 @@ end
column enum_enum : MyEnum?, column_type: "my_enum_type", converter: Granite::Converters::Enum(MyEnum, Bytes)
column binary_enum : MyEnum?, column_type: "BYTEA", converter: Granite::Converters::Enum(MyEnum, Bytes)

column string_uuid : UUID?, converter: Granite::Converters::Uuid(String) # Test PG native UUID type
column binary_uuid : UUID?, column_type: "BYTEA", converter: Granite::Converters::Uuid(Bytes)

column numeric : Float64?, column_type: "DECIMAL(21, 20)", converter: Granite::Converters::PgNumeric
end
ConverterModel.exec(<<-TYPE
Expand All @@ -579,9 +576,6 @@ end
column int_enum : MyEnum?, column_type: "INTEGER", converter: Granite::Converters::Enum(MyEnum, Int64)
column string_enum : MyEnum?, column_type: "TEXT", converter: Granite::Converters::Enum(MyEnum, String)
column binary_enum : MyEnum?, column_type: "BLOB", converter: Granite::Converters::Enum(MyEnum, String)

column string_uuid : UUID?, column_type: "TEXT", converter: Granite::Converters::Uuid(String)
column binary_uuid : UUID?, column_type: "BLOB", converter: Granite::Converters::Uuid(Bytes)
end
{% elsif env("CURRENT_ADAPTER") == "mysql" %}
class ConverterModel < Granite::Base
Expand All @@ -597,9 +591,6 @@ end
column string_enum : MyEnum?, column_type: "VARCHAR(5)", converter: Granite::Converters::Enum(MyEnum, String)
column enum_enum : MyEnum?, column_type: "ENUM('Zero', 'One', 'Two', 'Three', 'Four')", converter: Granite::Converters::Enum(MyEnum, String)
column binary_enum : MyEnum?, column_type: "BLOB", converter: Granite::Converters::Enum(MyEnum, Bytes)

column string_uuid : UUID?, column_type: "TEXT", converter: Granite::Converters::Uuid(String)
column binary_uuid : UUID?, column_type: "BLOB", converter: Granite::Converters::Uuid(Bytes)
end
{% end %}

Expand Down
8 changes: 4 additions & 4 deletions src/adapter/base.cr
Expand Up @@ -33,7 +33,7 @@ abstract class Granite::Adapter::Base
end

# remove all rows from a table and reset the counter on the id.
abstract def clear(table_name)
abstract def clear(table_name : String)

# select performs a query against a table. The query object contains table_name,
# fields (configured using the sql_mapping directive in your model), and an optional
Expand Down Expand Up @@ -79,16 +79,16 @@ abstract class Granite::Adapter::Base
end

# This will insert a row in the database and return the id generated.
abstract def insert(table_name, fields, params, lastval) : Int64
abstract def insert(table_name : String, fields, params, lastval) : Int64

# This will insert an array of models as one insert statement
abstract def import(table_name : String, primary_name : String, auto : Bool, fields, model_array, **options)

# This will update a row in the database.
abstract def update(table_name, primary_name, fields, params)
abstract def update(table_name : String, primary_name : String, fields, params)

# This will delete a row from the database.
abstract def delete(table_name, primary_name, value)
abstract def delete(table_name : String, primary_name : String, value)

module Schema
TYPES = {
Expand Down

0 comments on commit 64ff39f

Please sign in to comment.