diff --git a/.github/workflows/Test_DB.yml b/.github/workflows/Test_DB.yml new file mode 100644 index 0000000..44f020f --- /dev/null +++ b/.github/workflows/Test_DB.yml @@ -0,0 +1,39 @@ +name: MySQLAdapter test +on: push + +jobs: + # Label of the container job + container-job: + # Containers must run in Linux based operating systems + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:latest + env: + MYSQL_DATABASE: searchlight_tests + MYSQL_HOST: 127.0.0.1 + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + MYSQL_ROOT_PASSWORD: rootpass + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - uses: actions/checkout@v2 + - uses: julia-actions/setup-julia@latest + with: + version: '1.7.1' + arch: 'x64' + - uses: julia-actions/julia-buildpkg@master + - name: Install SearchLight and SearchLightMySQL + run: | + pwd + julia -e 'using Pkg; Pkg.add(url="https://github.com/GenieFramework/SearchLight.jl.git")' + julia -e 'using Pkg; Pkg.add(url="https://github.com/GenieFramework/SearchLightMySQL.jl.git")' + julia -e 'import Pkg; Pkg.add("SafeTestsets")' + julia -e 'using Pkg; Pkg.activate(".")' + julia -e 'using Pkg; Pkg.resolve()' + shell: bash + - uses: julia-actions/julia-runtest@master diff --git a/Project.toml b/Project.toml index 9f51605..0d5209a 100644 --- a/Project.toml +++ b/Project.toml @@ -6,6 +6,7 @@ version = "2.0.0" [deps] DBInterface = "a10d1c49-ce27-4219-8d33-6db1a4562965" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" MySQL = "39abe10b-433b-5dbd-92d4-e302a9df00cd" SearchLight = "340e8cb6-72eb-11e8-37ce-c97ebeb32050" diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..bd6d221 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,7 @@ +[deps] +Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SearchLight = "340e8cb6-72eb-11e8-37ce-c97ebeb32050" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04" diff --git a/test/db/migrations/2019052410085235_create_table_users.jl b/test/db/migrations/2019052410085235_create_table_users.jl new file mode 100644 index 0000000..1ff4c4d --- /dev/null +++ b/test/db/migrations/2019052410085235_create_table_users.jl @@ -0,0 +1,23 @@ +module CreateTableUsers + +import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table + +function up() + create_table(:users) do + [ + primary_key() + column(:username, :string, limit = 100) + column(:password, :string, limit = 100) + column(:name, :string, limit = 100) + column(:email, :string, limit = 100) + ] + end + + add_index(:users, :username) +end + +function down() + drop_table(:users) +end + +end \ No newline at end of file diff --git a/test/db/migrations/2021061519495560_create_table_roles.jl b/test/db/migrations/2021061519495560_create_table_roles.jl new file mode 100644 index 0000000..7d32db8 --- /dev/null +++ b/test/db/migrations/2021061519495560_create_table_roles.jl @@ -0,0 +1,20 @@ +module CreateTableRoles + +import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table + +function up() + create_table(:roles) do + [ + primary_key() + column(:name, :string, limit = 100) + ] + end + + add_index(:roles, :name) +end + +function down() + drop_table(:roles) +end + +end diff --git a/test/db/migrations/2021061519503270_create_table_abilities.jl b/test/db/migrations/2021061519503270_create_table_abilities.jl new file mode 100644 index 0000000..603127d --- /dev/null +++ b/test/db/migrations/2021061519503270_create_table_abilities.jl @@ -0,0 +1,20 @@ +module CreateTableAbilities + +import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table + +function up() + create_table(:abilities) do + [ + primary_key() + column(:name, :string, limit = 100) + ] + end + + add_index(:abilities, :name) +end + +function down() + drop_table(:abilities) +end + +end diff --git a/test/db/migrations/2021061519532446_create_table_roles_users.jl b/test/db/migrations/2021061519532446_create_table_roles_users.jl new file mode 100644 index 0000000..279f57e --- /dev/null +++ b/test/db/migrations/2021061519532446_create_table_roles_users.jl @@ -0,0 +1,22 @@ +module CreateTableRolesUsers + +import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table + +function up() + create_table(:rolesusers) do + [ + primary_key() + column(:roles_id, :int) + column(:users_id, :int) + ] + end + + add_index(:rolesusers, :roles_id) + add_index(:rolesusers, :users_id) +end + +function down() + drop_table(:rolesusers) +end + +end diff --git a/test/db/migrations/2021061519540214_create_table_abilities_roles.jl b/test/db/migrations/2021061519540214_create_table_abilities_roles.jl new file mode 100644 index 0000000..b87c6b4 --- /dev/null +++ b/test/db/migrations/2021061519540214_create_table_abilities_roles.jl @@ -0,0 +1,22 @@ +module CreateTableAbilitiesRoles + +import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table + +function up() + create_table(:abilitiesroles) do + [ + primary_key() + column(:abilities_id, :int) + column(:roles_id, :int) + ] + end + + add_index(:abilitiesroles, :abilities_id) + add_index(:abilitiesroles, :roles_id) +end + +function down() + drop_table(:abilitiesroles) +end + +end diff --git a/test/models.jl b/test/models.jl new file mode 100644 index 0000000..0a1da00 --- /dev/null +++ b/test/models.jl @@ -0,0 +1,160 @@ +module TestModels + + using SearchLight + + ######## Model from Genie-Searchligth-example-app extracted ############ + export Book, BookWithInterns + using SearchLight, Dates + + ######## Model from Genie-Searchligth-example-app extracted ############ + export Callback + export seed, fields_to_store + + mutable struct Book <: AbstractModel + + ### FIELDS + id::DbId + title::String + author::String + cover::String + + ### VALIDATION + # validator::ModelValidator + + ### CALLBACKS + # before_save::Function + # after_save::Function + # on_save::Function + # on_find::Function + # after_find::Function + + ### SCOPES + # scopes::Dict{Symbol,Vector{SearchLight.SQLWhereEntity}} + + ### constructor + Book(; + ### FIELDS + id = DbId(), + title = "", + author = "", + cover = "", + + ### VALIDATION + # validator = ModelValidator([ + # ValidationRule(:title, BooksValidator.not_empty) + # ]), + + ### CALLBACKS + # before_save = (m::Todo) -> begin + # @info "Before save" + # end, + # after_save = (m::Todo) -> begin + # @info "After save" + # end, + # on_save = (m::Todo, field::Symbol, value::Any) -> begin + # @info "On save" + # end, + # on_find = (m::Todo, field::Symbol, value::Any) -> begin + # @info "On find" + # end, + # after_find = (m::Todo) -> begin + # @info "After find" + # end, + + ### SCOPES + # scopes = Dict{Symbol,Vector{SearchLight.SQLWhereEntity}}() + + ) = new(id, title, author, cover ### FIELDS + # validator, ### VALIDATION + # before_save, after_save, on_save, on_find, after_find ### CALLBACKS + # scopes ### SCOPES + ) + end + + mutable struct BookWithInterns <: AbstractModel + + ### FIELDS + id::DbId + title::String + author::String + cover::String + + ### VALIDATION + # validator::ModelValidator + + ### CALLBACKS + # before_save::Function + # after_save::Function + # on_save::Function + # on_find::Function + # after_find::Function + + ### SCOPES + # scopes::Dict{Symbol,Vector{SearchLight.SQLWhereEntity}} + + ### constructor + BookWithInterns(; + ### FIELDS + id = DbId(), + title = "", + author = "", + cover = "", + + ### VALIDATION + # validator = ModelValidator([ + # ValidationRule(:title, BooksValidator.not_empty) + # ]), + + ### CALLBACKS + # before_save = (m::Todo) -> begin + # @info "Before save" + # end, + # after_save = (m::Todo) -> begin + # @info "After save" + # end, + # on_save = (m::Todo, field::Symbol, value::Any) -> begin + # @info "On save" + # end, + # on_find = (m::Todo, field::Symbol, value::Any) -> begin + # @info "On find" + # end, + # after_find = (m::Todo) -> begin + # @info "After find" + # end, + + ### SCOPES + # scopes = Dict{Symbol,Vector{SearchLight.SQLWhereEntity}}() + + ) = new("bookwithinterns", "id", Symbol[], ### INTERNALS + id, title, author, cover ### FIELDS + # validator, ### VALIDATION + # before_save, after_save, on_save, on_find, after_find ### CALLBACKS + # scopes ### SCOPES + ) + end + + Base.@kwdef mutable struct Callback <: AbstractModel + id::DbId = DbId() + title::String = "" + indicator::Bool = true + created_at::String = string(Dates.now()) + # callbacks + before_save::Function = (m::Callback) -> begin + @info "Do something before saving" + end + after_save::Function = (m::Callback) -> begin + @info "Do something after saving" + end + end + + function seed() + BillGatesBooks = [ + ("The Best We Could Do", "Thi Bui"), + ("Evicted: Poverty and Profit in the American City", "Matthew Desmond"), + ("Believe Me: A Memoir of Love, Death, and Jazz Chickens", "Eddie Izzard"), + ("The Sympathizer!", "Viet Thanh Nguyen"), + ("Energy and Civilization, A History", "Vaclav Smil") + ] + end + +end ### End Module diff --git a/test/mysql_connection.yml b/test/mysql_connection.yml new file mode 100644 index 0000000..d216989 --- /dev/null +++ b/test/mysql_connection.yml @@ -0,0 +1,13 @@ +env: dev + +dev: + adapter: MySQL + host: 127.0.0.1 + port: 3306 + database: searchlight_tests + username: mysql + password: mysql + + config: + log_queries: true + log_level: :debug diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 0000000..8229e62 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,18 @@ +cd(@__DIR__) + +using Pkg + +using Test, TestSetExtensions, SafeTestsets +using SearchLight +using SearchLightMySQL +using Dates + +# @testset ExtendedTestSet "SearchLight PostgreSQL adapter tests" begin +# @includetests ARGS +# end + +# run a simple connect test for the first time + +@testset ExtendedTestSet "SearchLight tests" begin + @includetests ARGS +end diff --git a/test/tests_relationships.jl b/test/tests_relationships.jl new file mode 100644 index 0000000..a8cacf7 --- /dev/null +++ b/test/tests_relationships.jl @@ -0,0 +1,50 @@ +using SearchLight, SearchLight.Migrations, SearchLight.Relationships + +cd(@__DIR__) + +connection_file = joinpath(@__DIR__,"mysql_connection.yml") +conn_info_postgres = SearchLight.Configuration.load(connection_file) +const conn = SearchLight.connect(conn_info_postgres) + +try + SearchLight.Migrations.status() +catch _ + SearchLight.Migrations.create_migrations_table() +end + +isempty(SearchLight.Migrations.downed_migrations()) || SearchLight.Migrations.all_up!!() + +Base.@kwdef mutable struct User <: AbstractModel + id::DbId = DbId() + username::String = "" + password::String = "" + name::String = "" + email::String = "" +end + +Base.@kwdef mutable struct Role <: AbstractModel + id::DbId = DbId() + name::String = "" +end + +Base.@kwdef mutable struct Ability <: AbstractModel + id::DbId = DbId() + name::String = "" +end + +u1 = findone_or_create(User, username = "a") |> save! +r1 = findone_or_create(Role, name = "abcd") |> save! + +for x in 'a':'d' + findone_or_create(Ability, name = "$x") |> save! +end + +Relationships.Relationship!(u1, r1) + +for a in all(Ability) + Relationships.Relationship!(r1, a) +end + +Relationships.related(u1, Role) +Relationships.related(findone(Role, id = 1), Ability) +Relationships.related(u1, Ability, through = [Role])