From 982bfcafedfa85d3f95e185c8a8e7cbcb9905f3f Mon Sep 17 00:00:00 2001 From: Greg Heckenbach Date: Tue, 5 May 2020 11:46:35 -0700 Subject: [PATCH] Add mysql tests to ci.sh; fix mysql tests; add test to show compound PK with auto ids --- ci.sh | 1 + spec/core_model_specs.moon | 6 ++-- spec_mysql/model_spec.moon | 49 ++++++++++++++++++++++++++-- spec_mysql/models.moon | 40 ++++++++++++++++++++--- spec_openresty/resty_mysql_spec.moon | 3 +- spec_openresty/s2/app.moon | 3 +- spec_postgres/model_spec.moon | 28 +++++++++++++++- 7 files changed, 119 insertions(+), 11 deletions(-) diff --git a/ci.sh b/ci.sh index 681138e8..52302947 100755 --- a/ci.sh +++ b/ci.sh @@ -31,5 +31,6 @@ echo 'user root;' >> spec_openresty/s2/nginx.conf ./busted -o utfTerminal ./busted -o utfTerminal spec_postgres/ +./busted -o utfTerminal spec_mysql/ ./busted -o utfTerminal spec_openresty/ ./busted -o utfTerminal spec_cqueues/ diff --git a/spec/core_model_specs.moon b/spec/core_model_specs.moon index 6495127a..9910b406 100644 --- a/spec/core_model_specs.moon +++ b/spec/core_model_specs.moon @@ -17,7 +17,7 @@ assert_same_rows = (a, b) -> (models) -> import it, describe, before_each, after_each from require "busted" - import Users, Posts, Likes from models + import Users, Posts, Images, Likes from models describe "basic model", -> before_each -> @@ -182,10 +182,11 @@ assert_same_rows = (a, b) -> before_each -> Users\create_table! Posts\create_table! + Images\create_table! Likes\create_table! package.loaded.models = { - :Users, :Posts, :Likes + :Users, :Posts, :Images, :Likes } query_log = {} @@ -272,6 +273,7 @@ assert_same_rows = (a, b) -> before_each -> Users\create_table! Posts\create_table! + Images\create_table! Likes\create_table! before_each -> diff --git a/spec_mysql/model_spec.moon b/spec_mysql/model_spec.moon index b62b8b40..88d36b83 100644 --- a/spec_mysql/model_spec.moon +++ b/spec_mysql/model_spec.moon @@ -1,7 +1,7 @@ db = require "lapis.db.mysql" import setup_db, teardown_db from require "spec_mysql.helpers" -import Users, Posts, Likes from require "spec_mysql.models" +import Users, Posts, Images, Likes from require "spec_mysql.models" describe "model", -> setup -> @@ -12,7 +12,7 @@ describe "model", -> describe "core model", -> build = require "spec.core_model_specs" - build { :Users, :Posts, :Likes } + build { :Users, :Posts, :Images, :Likes } it "should get columns of model", -> Users\create_table! @@ -39,3 +39,48 @@ describe "model", -> -- this fails in postgres, but mysql gives default values Posts\create {} + describe "with compound auto_increment", -> + Users\create_table! + Posts\create_table! + Images\create_table! + + user1 = Users\create { name: "bob" } + post1 = Posts\create { user_id: user1.user_id } + post2 = Posts\create { user_id: user1.user_id } + + first = Images\create { + user_id: user1.id + post_id: post1.id + url: "first" + } + second = Images\create { + user_id: user1.id + post_id: post1.id + url: "second" + } + third = Images\create { + user_id: user1.id + post_id: post2.id + url: "third" + } + + it "should increment keys", -> + assert.truthy first.id < second.id + assert.truthy second.id < third.id + + it "should find entites", -> + assert.same first, Images\find post1.id, first.id + assert.same {first, second}, Images\find_all {post1.id}, "post_id" + assert.same {third}, Images\find_all {post2.id}, "post_id" + + it "should allow relations", -> + package.loaded.models = { + :Users, :Posts, :Images, :Likes + } + + assert.same user1, first\get_user! + assert.same post1, first\get_post! + assert.same post2, third\get_post! + + assert.same {first.id, second.id}, [v.id for v in *post1\get_images!] + assert.same {third.id}, [v.id for v in *post2\get_images!] diff --git a/spec_mysql/models.moon b/spec_mysql/models.moon index 62005aa2..d34464f0 100644 --- a/spec_mysql/models.moon +++ b/spec_mysql/models.moon @@ -16,13 +16,17 @@ class Users extends Model class Posts extends Model @timestamp: true + @relations: { + {"images", has_many: "Images"} + } + @create_table: => drop_tables @ create_table @table_name!, { {"id", types.id} {"user_id", types.integer null: true} - {"title", types.text null: false} - {"body", types.text null: false} + {"title", types.text null: true} + {"body", types.text null: true} {"created_at", types.datetime} {"updated_at", types.datetime} } @@ -30,6 +34,34 @@ class Posts extends Model @truncate: => truncate_tables @ +class Images extends Model + @primary_key: {"user_id", "id"} + @timestamp: true + + @relations: { + {"user", belongs_to: "Users"} + {"post", belongs_to: "Posts"} + } + + @create_table: => + drop_tables @ + create_table @table_name!, { + {"post_id", types.integer} + -- Can't use types.id for "id" because it specifies primary_key + {"id", types.integer auto_increment: true} + {"user_id", types.integer null: true} + {"url", types.text null: false} + {"created_at", types.datetime} + {"updated_at", types.datetime} + + "PRIMARY KEY (post_id, id)" + -- auto_increment must be a key of its own (PK or otherwise) + "KEY id (id)" + } + + @truncate: => + truncate_tables @ + class Likes extends Model @primary_key: {"user_id", "post_id"} @timestamp: true @@ -44,7 +76,7 @@ class Likes extends Model create_table @table_name!, { {"user_id", types.integer} {"post_id", types.integer} - {"count", types.integer} + {"count", types.integer default: 0} {"created_at", types.datetime} {"updated_at", types.datetime} @@ -54,4 +86,4 @@ class Likes extends Model @truncate: => truncate_tables @ -{:Users, :Posts, :Likes} +{:Users, :Posts, :Images, :Likes} diff --git a/spec_openresty/resty_mysql_spec.moon b/spec_openresty/resty_mysql_spec.moon index df9d9de4..16424ddd 100644 --- a/spec_openresty/resty_mysql_spec.moon +++ b/spec_openresty/resty_mysql_spec.moon @@ -5,7 +5,7 @@ runner = NginxRunner base_path: "spec_openresty/s2/" import SpecServer from require "lapis.spec.server" server = SpecServer runner -import Users, Posts, Likes from require "spec_mysql.models" +import Users, Posts, Images, Likes from require "spec_mysql.models" import setup_db, teardown_db from require "spec_mysql.helpers" @@ -15,6 +15,7 @@ describe "resty", -> Users\create_table! Posts\create_table! + Images\create_table! Likes\create_table! server\load_test_server! diff --git a/spec_openresty/s2/app.moon b/spec_openresty/s2/app.moon index a1942f17..e6d16904 100644 --- a/spec_openresty/s2/app.moon +++ b/spec_openresty/s2/app.moon @@ -1,7 +1,7 @@ lapis = require "lapis" db = require "lapis.db" -import Users, Posts, Likes from require "spec_mysql.models" +import Users, Posts, Images, Likes from require "spec_mysql.models" assert = require "luassert" @@ -21,6 +21,7 @@ class extends lapis.Application @before_filter -> Users\truncate! Posts\truncate! + Images\truncate! Likes\truncate! "/": => diff --git a/spec_postgres/model_spec.moon b/spec_postgres/model_spec.moon index 828f5a2b..098f56d1 100644 --- a/spec_postgres/model_spec.moon +++ b/spec_postgres/model_spec.moon @@ -22,6 +22,10 @@ class Users extends Model class Posts extends Model @timestamp: true + @relations: { + {"images", has_many: "Images"} + } + @create_table: => drop_tables @ create_table @table_name!, { @@ -37,6 +41,28 @@ class Posts extends Model @truncate: => truncate_tables @ +class Images extends Model + @timestamp: true + + @create_table: => + drop_tables @ + create_table @table_name!, { + {"post_id", types.integer} + -- TODO Can't use types.id for "id" because it specifies primary_key. + -- We could pre-process the fields and collect primary keys first, then + -- create a "PRIMARY KEY" string internally. + {"id", types.integer auto_increment: true} + {"user_id", types.integer null: true} + {"url", types.text null: false} + {"created_at", types.time} + {"updated_at", types.time} + + "PRIMARY KEY (post_id, id)" + } + + @truncate: => + truncate_tables @ + class Likes extends Model @primary_key: {"user_id", "post_id"} @timestamp: true @@ -79,7 +105,7 @@ describe "model", -> describe "core model", -> build = require "spec.core_model_specs" - build { :Users, :Posts, :Likes } + build { :Users, :Posts, :Images, :Likes } it "should get columns of model", -> Users\create_table!