makanai 0.1.0 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 045d01dcb6633aa95bb5e62f1714b477e80d9df4b29bb225f70ee22ce0b62677
4
- data.tar.gz: 66dd196776a842b881097bf686e658054e0a32377dc1fea5564f540275030763
3
+ metadata.gz: 6c81e0de73a48146dc929239f380cba64b004c3517e9efc6f005d2c6a1f29f49
4
+ data.tar.gz: be85163a11c4e40cc0f3a43b122ce6396674dccb7fcd4bc14339888c9f45ef39
5
5
  SHA512:
6
- metadata.gz: 7fbceba802f6ae1b6edd0477afa1e13dc0ca73f182527f616a013e23d32b72577eba0e42e65798b0ba3c9452c75638b47da153cd6f40aa42ff6644ca1803413d
7
- data.tar.gz: 86fd67e171f26715f21e6725e18c5d564267387334e519d6ea2f7bffa7c002ba786300b79edf61b0f96f38f6745a81748909fe5aedc13b086bf3cd6b13ae9a12
6
+ metadata.gz: ebf556b401b54ee54b7921d907e324c03f5926f780c3fe9f39881d6a59a9727cb4d742f8f8f85fe4006626b24bad64b6c262c9725cb7fc31108f0861703c2f44
7
+ data.tar.gz: 5174bf19553fd347e15b27469e63224f1552288912b150f739f5b251f63227da3f3a88a408c2e305ecde170d0ee2aa1dc60f5750a765a398c8a32b9f1a769d9a
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
 
12
12
  # rspec failure tracking
13
13
  .rspec_status
14
+ /**/.DS_Store
@@ -1,13 +1,8 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.6.3
2
+ TargetRubyVersion: 2.7.0
3
3
  Exclude:
4
4
  - './makanai.gemspec'
5
-
6
- Style/Documentation:
7
- Enabled: false
8
-
9
- Metrics/LineLength:
10
- Max: 90
5
+ - 'vendor/**/*'
11
6
 
12
7
  Metrics/ClassLength:
13
8
  Max: 120
@@ -15,9 +10,25 @@ Metrics/ClassLength:
15
10
  Metrics/BlockLength:
16
11
  Exclude:
17
12
  - 'spec/**/*'
13
+ - 'lib/makanai/rake_tasks.rb'
14
+
15
+ Style/Documentation:
16
+ Enabled: false
18
17
 
19
18
  Style/ParallelAssignment:
20
19
  Enabled: false
21
20
 
21
+ Style/HashEachMethods:
22
+ Enabled: true
23
+
24
+ Style/HashTransformKeys:
25
+ Enabled: true
26
+
27
+ Style/HashTransformValues:
28
+ Enabled: true
29
+
30
+ Layout/LineLength:
31
+ Max: 90
32
+
22
33
  Layout/EmptyLineAfterGuardClause:
23
34
  Enabled: false
@@ -0,0 +1 @@
1
+ 2.7.1
@@ -1,7 +1,20 @@
1
1
  ---
2
- sudo: false
3
2
  language: ruby
4
3
  cache: bundler
4
+ services:
5
+ - postgresql
6
+ - mysql
5
7
  rvm:
6
- - 2.6.3
7
- before_install: gem install bundler -v 2.0.2
8
+ - 2.6.6
9
+ - 2.7.1
10
+ - ruby-head
11
+ os:
12
+ - linux
13
+ before_install:
14
+ - gem install bundler -v 2.1.4
15
+ - mysql -e 'CREATE DATABASE IF NOT EXISTS makanai;'
16
+ before_script:
17
+ - psql -c 'create database makanai;' -U postgres
18
+ jobs:
19
+ allow_failures:
20
+ - rvm: ruby-head
@@ -0,0 +1,41 @@
1
+ # CHANGELOG
2
+
3
+ ## :gift: 2019/10/22 `v0.1.0` released.
4
+
5
+ * :tada: first release
6
+
7
+ ## :gift: 2019/12/28 `v0.1.1` released.
8
+
9
+ * :sparkles: add Makanai app genarator.
10
+ Added `makanai init` command for initialize makanai application.
11
+ https://github.com/Madogiwa0124/makanai/pull/5
12
+
13
+ * :sparkles: add `Makanai::Model#first`.
14
+ execute `SELECT * FROM table_name ORDER BY prymary_key asc limit 1` and return record object.
15
+ https://github.com/Madogiwa0124/makanai/commit/8949796bf7428f5e2d854041b35397ef4d442ee6
16
+
17
+ ## :gift: 2020/02/22 `v0.1.2` released.
18
+ * :sparkles: use config object by Makanai::Settings for replaceable app config.
19
+ Changed the setting so that it is retained by the Class variable, and made it configurable.
20
+ The big advantage is that you can use any web server(ex. puma) except WEBrick.
21
+ https://github.com/Madogiwa0124/makanai/pull/18/commits/e6ea10e596c685ef77c042fa1e8f0294c85166f2
22
+
23
+ ## :gift: 2020/03/04 `v0.1.3` released.
24
+ * :sparkles: Multiple DBMS available.
25
+ you can use dbms(MySQL :dolphin:, PostgreSQL :elephant:) other then SQLite.
26
+ https://github.com/Madogiwa0124/makanai/pull/19
27
+
28
+ ## :gift: 2020/04/08 `v0.1.4` released.
29
+ * :sparkles: support lastest ruby versions(2.6.6, 2.7.1)
30
+ * :sparkles: support for dynamic URL routing.
31
+
32
+ ``` ruby
33
+ router.get '/hoge/:id' do
34
+ request.params['id']
35
+ end
36
+ ```
37
+
38
+ https://github.com/Madogiwa0124/makanai/commit/e256368fd0a13f1d0d2d6c6af17caef7760e64f0
39
+
40
+ ## :gift: 2020/06/16 `v0.1.5` released.
41
+ * :package: dependency update.
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ source 'https://rubygems.org'
5
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  gemspec
8
+
9
+ gem 'codecov', :require => false
@@ -1,55 +1,76 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- makanai (0.1.0)
5
- rack (~> 2.0.7)
6
- rake (~> 10.0)
4
+ makanai (0.1.5)
5
+ rack (>= 2.0.7, < 2.3.0)
6
+ rake (>= 10, < 14)
7
7
  sqlite3 (~> 1.4.1)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
12
  ast (2.4.0)
13
+ codecov (0.1.17)
14
+ json
15
+ simplecov
16
+ url
13
17
  diff-lcs (1.3)
14
- jaro_winkler (1.5.3)
15
- parallel (1.17.0)
16
- parser (2.6.3.0)
18
+ docile (1.3.2)
19
+ json (2.3.0)
20
+ mysql2 (0.5.3)
21
+ parallel (1.19.1)
22
+ parser (2.7.1.3)
17
23
  ast (~> 2.4.0)
18
- rack (2.0.7)
24
+ pg (1.2.3)
25
+ rack (2.2.3)
19
26
  rainbow (3.0.0)
20
- rake (10.5.0)
21
- rspec (3.8.0)
22
- rspec-core (~> 3.8.0)
23
- rspec-expectations (~> 3.8.0)
24
- rspec-mocks (~> 3.8.0)
25
- rspec-core (3.8.2)
26
- rspec-support (~> 3.8.0)
27
- rspec-expectations (3.8.4)
27
+ rake (13.0.1)
28
+ regexp_parser (1.7.1)
29
+ rexml (3.2.4)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.1)
35
+ rspec-support (~> 3.9.1)
36
+ rspec-expectations (3.9.1)
28
37
  diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.8.0)
30
- rspec-mocks (3.8.1)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
31
40
  diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.8.0)
33
- rspec-support (3.8.2)
34
- rubocop (0.74.0)
35
- jaro_winkler (~> 1.5.1)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.2)
43
+ rubocop (0.85.1)
36
44
  parallel (~> 1.10)
37
- parser (>= 2.6)
45
+ parser (>= 2.7.0.1)
38
46
  rainbow (>= 2.2.2, < 4.0)
47
+ regexp_parser (>= 1.7)
48
+ rexml
49
+ rubocop-ast (>= 0.0.3)
39
50
  ruby-progressbar (~> 1.7)
40
- unicode-display_width (>= 1.4.0, < 1.7)
51
+ unicode-display_width (>= 1.4.0, < 2.0)
52
+ rubocop-ast (0.0.3)
53
+ parser (>= 2.7.0.1)
41
54
  ruby-progressbar (1.10.1)
42
- sqlite3 (1.4.1)
43
- unicode-display_width (1.6.0)
55
+ simplecov (0.18.5)
56
+ docile (~> 1.1)
57
+ simplecov-html (~> 0.11)
58
+ simplecov-html (0.12.2)
59
+ sqlite3 (1.4.2)
60
+ unicode-display_width (1.7.0)
61
+ url (0.3.2)
44
62
 
45
63
  PLATFORMS
46
64
  ruby
47
65
 
48
66
  DEPENDENCIES
49
67
  bundler (~> 2.0)
68
+ codecov
50
69
  makanai!
70
+ mysql2 (~> 0.5)
71
+ pg (~> 1.2)
51
72
  rspec (~> 3.0)
52
73
  rubocop (~> 0.74)
53
74
 
54
75
  BUNDLED WITH
55
- 2.0.2
76
+ 2.1.4
data/README.md CHANGED
@@ -1,4 +1,9 @@
1
1
  # Makanai
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/makanai.svg)](https://badge.fury.io/rb/makanai)
4
+ [![Build Status](https://travis-ci.com/Madogiwa0124/makanai.svg?branch=master)](https://travis-ci.com/Madogiwa0124/makanai)
5
+ [![codecov](https://codecov.io/gh/Madogiwa0124/makanai/branch/master/graph/badge.svg)](https://codecov.io/gh/Madogiwa0124/makanai)
6
+
2
7
  simple web application framework for learning.
3
8
 
4
9
  # Getting Start
@@ -29,26 +34,21 @@ Makanai depends on the following, so please install it in advance.
29
34
  Getting started with Makanai is easy.
30
35
 
31
36
  ```
32
- $ git clone https://github.com/Madogiwa0124/makanai.git
33
- $ bundle install
34
- $ cd makanai/sample
35
- $ be ruby app.rb
36
- [2019-09-09 23:20:05] INFO WEBrick 1.4.2
37
- [2019-09-09 23:20:05] INFO ruby 2.6.3 (2019-04-16) [x86_64-darwin18]
38
- [2019-09-09 23:20:05] INFO WEBrick::HTTPServer#start: pid=30871 port=8080
37
+ $ mkdir sample
38
+ $ cd sample
39
+ $ makanai init
40
+ $ ruby app.rb
41
+ [2019-12-28 12:27:13] INFO WEBrick 1.6.0
42
+ [2019-12-28 12:27:13] INFO ruby 2.7.0 (2019-12-25) [x86_64-darwin18]
43
+ [2019-12-28 12:27:13] INFO WEBrick::HTTPServer#start: pid=22676 port=8080
39
44
  ```
40
45
 
41
- ## How to customize
42
- You can customize the Makanai project by changing the sample directory. (You can also change the directory name from the sample.)
43
-
44
- To see what features are available, see Usage.
45
-
46
46
  # Usage
47
47
 
48
48
  create a ruby ​​file(ex. app.rb).
49
49
 
50
50
  ``` ruby
51
- require_relative '../lib/main.rb'
51
+ require 'makanai/main'
52
52
 
53
53
  router.get '/' do
54
54
  'Hello Makanai!'
@@ -59,9 +59,9 @@ start server(WEBrick) at execute `$ ruby app.rb`.
59
59
 
60
60
  ```
61
61
  $ ruby app.rb
62
- [2019-08-12 20:44:20] INFO WEBrick 1.4.2
63
- [2019-08-12 20:44:20] INFO ruby 2.6.3 (2019-04-16) [x86_64-darwin18]
64
- [2019-08-12 20:44:20] INFO WEBrick::HTTPServer#start: pid=26043 port=8080
62
+ [2019-12-28 12:27:13] INFO WEBrick 1.6.0
63
+ [2019-12-28 12:27:13] INFO ruby 2.7.0 (2019-12-25) [x86_64-darwin18]
64
+ [2019-12-28 12:27:13] INFO WEBrick::HTTPServer#start: pid=22676 port=8080
65
65
  ```
66
66
 
67
67
  When accessing root, `Hello Makanai!` is displayed.
@@ -77,10 +77,55 @@ root ┬ app.rb # main application file
77
77
  └ db # use Sqlite3 dabase file
78
78
  ```
79
79
 
80
+ ## override application config
81
+
82
+ You can overwrite the settings (`Makanai :: Settings`) with the created ruby ​​file(ex. app.rb).
83
+
84
+ ex) When overriding rack app settings.
85
+
86
+ ``` ruby
87
+ Makanai::Settings.rack_app_config = { handler: :webrick, host: '0.0.0.0', port: '8081' }
88
+ ```
89
+
90
+ ### use other application server
91
+
92
+ Add rack web server(ex. puma) gem in your Gemfile.
93
+
94
+ ``` ruby
95
+ gem 'puma'
96
+ ```
97
+
98
+ Overwrite the `handler` in `rack_app_config` with the created ruby ​​file(ex. app.rb).
99
+
100
+ ``` ruby
101
+ Makanai::Settings.rack_app_config = { handler: :puma, host: '0.0.0.0', port: '8080' }
102
+ ```
103
+
104
+ ### use other dbms
105
+
106
+ install dbms(postgresql, mysql, sqlite). And add dbms gem (ex. pg) in your Gemfile.
107
+
108
+ ``` ruby
109
+ gem 'pg'
110
+ ```
111
+
112
+ Overwrite the `databse_client` and `databse_config` with the created ruby ​​file(ex. app.rb) and Rakefile.
113
+
114
+ ``` ruby
115
+ Makanai::Settings.databse_client = :postgres
116
+ Makanai::Settings.databse_config = {
117
+ host: 'localhost',
118
+ password:'password',
119
+ dbname: 'makanai',
120
+ port: 5432
121
+ }
122
+ ```
123
+
80
124
  ## routing
125
+ Routing is searched in the order defined and call block args.
81
126
 
82
127
  ``` ruby
83
- require_relative '../lib/main.rb'
128
+ require 'makanai/main'
84
129
 
85
130
  # root path
86
131
  router.get '/' do
@@ -92,11 +137,17 @@ router.get '/hoge' do
92
137
  'Hello Hoge!'
93
138
  end
94
139
 
95
- # enable access to /params with get parameter
96
- router.get '/check' do |request|
140
+ # enable access to /hoge with get parameter(?hoge=fuga)
141
+ router.get '/hoge' do |request|
97
142
  request.params['hoge']
98
143
  end
99
144
 
145
+ # enable access to /hoge/:id with dinamic url args({ 'id' => '1'})
146
+ # NOTE: dinamics prefix is `:`.
147
+ router.get '/hoge/:id' do
148
+ request.params['id']
149
+ end
150
+
100
151
  # enable access to /resources with method post and redirect other url.
101
152
  router.post '/resources' do |request|
102
153
  Resource.new(request.params).create
@@ -123,7 +174,7 @@ end
123
174
  Define instance variables used in the routing view.
124
175
 
125
176
  ``` ruby
126
- require_relative '../lib/main.rb'
177
+ require 'makanai/main'
127
178
 
128
179
  router.get '/index' do
129
180
  @title = 'Makanai title'
@@ -149,7 +200,7 @@ Create an erb file in `src/views` with the name specified in render.
149
200
 
150
201
  ## migration
151
202
 
152
- makanai uses `sqlite3` as db. create db and migrate schema when executed `rake makanai:db:migration`.
203
+ migrate schema when executed `rake makanai:db:migration`.
153
204
 
154
205
  ```
155
206
  # execute all migraiton sql
@@ -179,7 +230,7 @@ INFO: finished migration all
179
230
  It can be used by creating a class that inherits `Makanai::Model`.
180
231
 
181
232
  ``` ruby
182
- require_relative '../../lib/model.rb'
233
+ require 'makanai/model'
183
234
 
184
235
  class Resource < Makanai::Model
185
236
  # target table when executing sql.
@@ -216,6 +267,22 @@ Resource.find(1).delete
216
267
 
217
268
  Bug reports and pull requests are welcome on GitHub at https://github.com/Madogiwa0124/makanai. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
218
269
 
270
+ ## setup develop enviroment
271
+
272
+ Use docker-compose to build `mysql` and` postgres` containers for development.
273
+
274
+ ``` sh
275
+ $ docker-compose up -d
276
+ Creating makanai_mysql_1 ... done
277
+ Creating makanai_postgres_1 ... done
278
+
279
+ $ docker-compose ps
280
+ Name Command State Ports
281
+ ----------------------------------------------------------------------------------------------
282
+ makanai_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
283
+ makanai_postgres_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
284
+ ```
285
+
219
286
  # License
220
287
 
221
288
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "makanai"
4
+ require 'bundler/setup'
5
+ require 'makanai'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "makanai"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -0,0 +1,14 @@
1
+ mysql:
2
+ image: mysql
3
+ ports:
4
+ - 3306:3306
5
+ environment:
6
+ - MYSQL_DATABASE=makanai
7
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
8
+ postgres:
9
+ image: postgres
10
+ ports:
11
+ - 5432:5432
12
+ environment:
13
+ - POSTGRES_USER=makanai
14
+ - POSTGRES_PASSWORD=password
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'makanai'
5
+ require 'makanai/rake_tasks'
6
+
7
+ Rake::Task['makanai:initialize:app'].execute if ARGV[0] == 'init'
@@ -1,6 +1,12 @@
1
- require "makanai/version"
1
+ # frozen_string_literal: true
2
+
3
+ require 'makanai/version'
2
4
 
3
5
  module Makanai
6
+ def self.root
7
+ File.dirname __dir__
8
+ end
9
+
4
10
  class Error < StandardError; end
5
11
  # Your code goes here...
6
12
  end
@@ -3,6 +3,7 @@
3
3
  require 'json'
4
4
  require 'uri'
5
5
  require 'rack'
6
+ require_relative './settings.rb'
6
7
  require_relative './request.rb'
7
8
  require_relative './response.rb'
8
9
  require_relative './router.rb'
@@ -11,13 +12,18 @@ module Makanai
11
12
  class Application
12
13
  def initialize(router:)
13
14
  @router = router
14
- @handler = Rack::Handler::WEBrick
15
+ @config = Settings
15
16
  end
16
17
 
17
- attr_reader :router, :handler, :request, :response
18
+ attr_reader :router, :config, :request, :response
18
19
 
19
20
  def run!
20
- handler.run self
21
+ app_config = config.rack_app_config
22
+ handler = Rack::Handler.get(app_config[:handler])
23
+ handler.run(self, { Host: app_config[:host], Port: app_config[:port] })
24
+ rescue Interrupt
25
+ handler.shutdown
26
+ puts '==== Goodbye! :) ===='
21
27
  end
22
28
 
23
29
  def call(env)
@@ -32,7 +38,10 @@ module Makanai
32
38
  private
33
39
 
34
40
  def execute_route
35
- router.bind!(url: request.url, method: request.method).process.call(request)
41
+ route = router.bind!(url: request.url, method: request.method)
42
+ # NOTE: merge dynamic url params (ex. /resources/1 -> { 'id' => '1' })
43
+ @request.params.merge!(route.url_args)
44
+ route.process.call(request)
36
45
  rescue Makanai::Router::NotFound
37
46
  @response.status = 404
38
47
  nil
@@ -1,27 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sqlite3'
3
+ require_relative './dbms/sqlite.rb'
4
4
  require_relative './settings.rb'
5
5
 
6
6
  module Makanai
7
7
  class Database
8
- DATABASE_PATH = "#{Settings::APP_ROOT_PATH}#{Settings::DATABASE_PATH}"
8
+ class UnsupportedException < StandardError; end
9
9
 
10
- def initialize
11
- @handler = SQLite3::Database
12
- @db = handler.new DATABASE_PATH
13
- db.tap { |db| db.results_as_hash = true }
10
+ def initialize(client: Settings.databse_client, config: Settings.databse_config)
11
+ client_class = client_class(client)
12
+ @client = client_class.new(config)
14
13
  end
15
14
 
16
- attr_reader :handler, :db
15
+ attr_reader :client
17
16
 
18
17
  def execute_sql(sql)
19
18
  puts "SQL: #{sql.gsub("\n", ' ')}"
20
- db.execute(sql).tap { close_db }
19
+ client.execute_sql(sql)
21
20
  end
22
21
 
23
- def close_db
24
- db.close
22
+ private
23
+
24
+ def client_class(client)
25
+ require_relative File.join('dbms', client.to_s)
26
+ Object.const_get("Makanai::Dbms::#{client.capitalize}")
27
+ rescue LoadError
28
+ raise UnsupportedException
25
29
  end
26
30
  end
27
31
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Makanai
4
+ module Dbms
5
+ class Base
6
+ def db
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def execute_sql
11
+ raise NotImplementedError
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mysql2'
4
+ require_relative './base.rb'
5
+ module Makanai
6
+ module Dbms
7
+ class Mysql < Base
8
+ def initialize(config)
9
+ @db = Mysql2::Client.new(config || default_config)
10
+ end
11
+
12
+ attr_reader :db
13
+
14
+ def execute_sql(sql)
15
+ db.query(sql).to_a.tap { close_db }
16
+ end
17
+
18
+ private
19
+
20
+ def default_config
21
+ {
22
+ host: '0.0.0.0',
23
+ username: 'root',
24
+ password: 'password',
25
+ database: 'makanai',
26
+ port: 3306
27
+ }
28
+ end
29
+
30
+ def close_db
31
+ db.close
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pg'
4
+ require_relative './base.rb'
5
+ module Makanai
6
+ module Dbms
7
+ class Postgres < Base
8
+ def initialize(config)
9
+ @db = PG.connect(config || default_config)
10
+ db.type_map_for_results = PG::BasicTypeMapForResults.new(db)
11
+ end
12
+
13
+ attr_reader :db
14
+
15
+ def execute_sql(sql)
16
+ db.exec(sql).each.to_a.tap { close_db }
17
+ end
18
+
19
+ private
20
+
21
+ def default_config
22
+ {
23
+ host: 'localhost',
24
+ password: nil,
25
+ dbname: 'makanai',
26
+ port: 5432
27
+ }
28
+ end
29
+
30
+ def close_db
31
+ db.finish
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sqlite3'
4
+ require_relative './base.rb'
5
+ module Makanai
6
+ module Dbms
7
+ class Sqlite < Base
8
+ def initialize(config)
9
+ @db = SQLite3::Database.new(config[:path])
10
+ db.tap { |db| db.results_as_hash = true }
11
+ end
12
+
13
+ attr_reader :db
14
+
15
+ def execute_sql(sql)
16
+ db.execute(sql).tap { close_db }
17
+ end
18
+
19
+ private
20
+
21
+ def close_db
22
+ db.close
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,8 +5,8 @@ require_relative './response.rb'
5
5
  require_relative './settings.rb'
6
6
 
7
7
  def render(path)
8
- template_root_path = "#{Dir.pwd}#{Makanai::Settings::TEMPLATE_ROOT_PATH}"
9
- full_path = "#{template_root_path}#{path}.erb"
8
+ template_root_path = Makanai::Settings.template_full_path
9
+ full_path = File.join(template_root_path, "#{path}.erb")
10
10
  Makanai::Template.new(path: full_path).render
11
11
  end
12
12
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+ require 'yaml'
5
+ require_relative '../makanai.rb'
6
+
7
+ module Makanai
8
+ class Generator
9
+ ROOT_PATH = "#{Makanai.root}/lib/makanai/generator"
10
+ DIRECTORY_NAMES = YAML.load_file("#{ROOT_PATH}/application/directories.yaml")
11
+ APP_TEMPLATE = File.read("#{ROOT_PATH}/application/templates/app.erb")
12
+ RAKEFILE_TEMPLATE = File.read("#{ROOT_PATH}/application/templates/rakefile.erb")
13
+
14
+ def initialize(path = Dir.pwd)
15
+ @path = path
16
+ end
17
+
18
+ attr_reader :path
19
+
20
+ def create_app_directories(directory_names = DIRECTORY_NAMES)
21
+ directory_names.map do |name|
22
+ dir_path = File.join(path, name)
23
+ Dir.mkdir(dir_path)
24
+ file_path = File.join(dir_path, '.keep')
25
+ create_file(file_path, nil)
26
+ file_path
27
+ end
28
+ end
29
+
30
+ def create_app_rb(template = APP_TEMPLATE)
31
+ File.join(path, 'app.rb').tap do |file_path|
32
+ create_file(file_path, ERB.new(template).result)
33
+ end
34
+ end
35
+
36
+ def create_rakefile(template = RAKEFILE_TEMPLATE)
37
+ File.join(path, 'Rakefile').tap do |file_path|
38
+ create_file(file_path, ERB.new(template).result)
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def create_file(file_path, content)
45
+ File.open(file_path, 'w') { |f| f.puts content }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,4 @@
1
+ - db
2
+ - migration
3
+ - models
4
+ - views
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'makanai/main'
4
+
5
+ router.get '/' do
6
+ 'Hello Makanai!'
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'makanai/rake_tasks.rb'
@@ -5,14 +5,14 @@ require_relative './database.rb'
5
5
 
6
6
  module Makanai
7
7
  module Migration
8
- def execute_sql(sql_path:)
8
+ def execute_sql(sql_path:, db: Makanai::Database.new)
9
9
  sql = File.read(sql_path)
10
10
  puts "execute: #{sql_path}"
11
- Makanai::Database.new.execute_sql(sql)
11
+ db.execute_sql(sql)
12
12
  end
13
13
 
14
14
  def migration_root_path
15
- "#{Settings::APP_ROOT_PATH}#{Settings::MIGRATION_ROOT_PATH}"
15
+ Settings.migration_full_path
16
16
  end
17
17
  end
18
18
  end
@@ -13,38 +13,45 @@ module Makanai
13
13
 
14
14
  attr_reader :origin_attributes
15
15
 
16
- def self.execute_sql(sql)
17
- Makanai::Database.new.execute_sql(sql)
16
+ def self.execute_sql(sql, db = Makanai::Database.new)
17
+ db.execute_sql(sql)
18
18
  end
19
19
 
20
- def self.all
21
- results = execute_sql("SELECT * FROM #{self::TABLE_NAME};")
20
+ def self.all(db = Makanai::Database.new)
21
+ results = execute_sql("SELECT * FROM #{self::TABLE_NAME};", db)
22
22
  results.map { |result| new(result) }
23
23
  end
24
24
 
25
- def self.find(key)
26
- results = execute_sql(
27
- <<~SQL
28
- SELECT *
29
- FROM #{self::TABLE_NAME}
30
- WHERE #{self::PRYMARY_KEY} = #{buid_sql_text(key)}
31
- LIMIT 1;
32
- SQL
33
- )
25
+ def self.find(key, db = Makanai::Database.new)
26
+ sql = <<~SQL
27
+ SELECT *
28
+ FROM #{self::TABLE_NAME}
29
+ WHERE #{self::PRYMARY_KEY} = #{buid_sql_text(key)}
30
+ LIMIT 1;
31
+ SQL
32
+ results = execute_sql(sql, db)
34
33
  raise Makanai::Model::NotFound if results.empty?
35
34
  new(results.pop)
36
35
  end
37
36
 
38
- def self.last
39
- results = execute_sql(
40
- <<~SQL
41
- SELECT *
42
- FROM #{self::TABLE_NAME}
43
- ORDER BY #{self::PRYMARY_KEY} DESC
44
- LIMIT 1;
45
- SQL
46
- )
47
- new(results.pop)
37
+ def self.first(db = Makanai::Database.new)
38
+ sql = <<~SQL
39
+ SELECT *
40
+ FROM #{self::TABLE_NAME}
41
+ ORDER BY #{self::PRYMARY_KEY} ASC
42
+ LIMIT 1;
43
+ SQL
44
+ new(execute_sql(sql, db).pop)
45
+ end
46
+
47
+ def self.last(db = Makanai::Database.new)
48
+ sql = <<~SQL
49
+ SELECT *
50
+ FROM #{self::TABLE_NAME}
51
+ ORDER BY #{self::PRYMARY_KEY} DESC
52
+ LIMIT 1;
53
+ SQL
54
+ new(execute_sql(sql, db).pop)
48
55
  end
49
56
 
50
57
  def self.buid_sql_text(value)
@@ -64,39 +71,36 @@ module Makanai
64
71
  origin_attributes.map { |key, _val| [key, send(key)] }.to_h
65
72
  end
66
73
 
67
- def create
68
- self.class.execute_sql(
69
- <<~SQL
70
- INSERT
71
- INTO #{self.class::TABLE_NAME}(#{clumns.join(',')})
72
- VALUES (#{insert_values.join(',')});
73
- SQL
74
- )
75
- @origin_attributes = self.class.last.attributes
74
+ def create(db = Makanai::Database.new)
75
+ sql = <<~SQL
76
+ INSERT
77
+ INTO #{self.class::TABLE_NAME}(#{clumns.join(',')})
78
+ VALUES (#{insert_values.join(',')});
79
+ SQL
80
+ self.class.execute_sql(sql, db)
81
+ @origin_attributes = attributes
76
82
  difine_attribute_methods
77
83
  self
78
84
  end
79
85
 
80
- def update
81
- self.class.execute_sql(
82
- <<~SQL
83
- UPDATE #{self.class::TABLE_NAME}
84
- SET #{update_values.join(',')}
85
- WHERE #{self.class::PRYMARY_KEY} = #{self.class.buid_sql_text(send(self.class::PRYMARY_KEY))};
86
- SQL
87
- )
86
+ def update(db = Makanai::Database.new)
87
+ sql = <<~SQL
88
+ UPDATE #{self.class::TABLE_NAME}
89
+ SET #{update_values.join(',')}
90
+ WHERE #{self.class::PRYMARY_KEY} = #{self.class.buid_sql_text(send(self.class::PRYMARY_KEY))};
91
+ SQL
92
+ self.class.execute_sql(sql, db)
88
93
  @origin_attributes = attributes
89
94
  difine_attribute_methods
90
95
  self
91
96
  end
92
97
 
93
- def delete
94
- self.class.execute_sql(
95
- <<~SQL
96
- DELETE FROM #{self.class::TABLE_NAME}
97
- WHERE #{self.class::PRYMARY_KEY} = #{self.class.buid_sql_text(send(self.class::PRYMARY_KEY))};
98
- SQL
99
- )
98
+ def delete(db = Makanai::Database.new)
99
+ sql = <<~SQL
100
+ DELETE FROM #{self.class::TABLE_NAME}
101
+ WHERE #{self.class::PRYMARY_KEY} = #{self.class.buid_sql_text(send(self.class::PRYMARY_KEY))};
102
+ SQL
103
+ self.class.execute_sql(sql, db)
100
104
  nil
101
105
  end
102
106
 
@@ -3,8 +3,21 @@
3
3
  require 'rake'
4
4
  require 'sqlite3'
5
5
  require_relative './migration.rb'
6
+ require_relative './generator.rb'
6
7
 
7
8
  namespace :makanai do
9
+ namespace :initialize do
10
+ desc 'create directies and files for makanai initialization.'
11
+ task :app do
12
+ generator = Makanai::Generator.new
13
+ puts 'INFO: start ganerate app'
14
+ puts generator.create_app_directories
15
+ puts generator.create_app_rb
16
+ puts generator.create_rakefile
17
+ puts 'INFO: finished ganerate app'
18
+ end
19
+ end
20
+
8
21
  namespace :db do
9
22
  desc 'execute migration'
10
23
  task :migration do
@@ -16,7 +29,7 @@ namespace :makanai do
16
29
  sql_paths = Dir.glob("#{migration_root_path}*")
17
30
  sql_paths.each { |sql_path| execute_sql(sql_path: sql_path) }
18
31
  else
19
- execute_sql(sql_path: "#{migration_root_path}#{target}")
32
+ execute_sql(sql_path: File.join(migration_root_path, target))
20
33
  end
21
34
  puts "INFO: finished migration #{ENV['target']}"
22
35
  end
@@ -6,7 +6,8 @@ require 'uri'
6
6
 
7
7
  module Makanai
8
8
  class Request < Rack::Request
9
- attr_reader :env, :url, :query, :origin_body, :method, :params
9
+ attr_reader :env, :url, :query, :origin_body, :method
10
+ attr_accessor :params
10
11
 
11
12
  def initialize(env)
12
13
  super
@@ -30,19 +30,50 @@ module Makanai
30
30
 
31
31
  def bind!(url:, method:)
32
32
  path = URI.parse(url).path
33
- routes.find { |route| route.path == path && route.method == method }.tap do |route|
33
+ routes.find { |route| route.match?(path: path, method: method) }.tap do |route|
34
34
  raise NotFound if route.nil?
35
35
  end
36
36
  end
37
37
 
38
38
  class Route
39
+ DYNAMIC_PREFIX = ':' # Prefix for dynamic path
40
+
39
41
  def initialize(path:, process:, method:)
40
42
  @path = path
41
43
  @process = process
42
44
  @method = method
45
+ @url_args = {}
46
+ end
47
+
48
+ attr_reader :path, :process, :method, :url_args
49
+
50
+ def match?(path:, method:)
51
+ build_url_args(path: path)
52
+ path_match?(path) && self.method == method
53
+ end
54
+
55
+ private
56
+
57
+ def dynamic_indx
58
+ @dynamic_indx ||= path.split('/').map.with_index do |val, i|
59
+ i if val.include?(DYNAMIC_PREFIX)
60
+ end.compact
43
61
  end
44
62
 
45
- attr_reader :path, :process, :method
63
+ def path_match?(path)
64
+ request_path, route_path = [path, self.path].map(&->(array) { array.split('/') })
65
+ request_path.each.with_index do |val, i|
66
+ route_path[i] = val if dynamic_indx.include?(i)
67
+ end
68
+ route_path == request_path
69
+ end
70
+
71
+ def build_url_args(path:)
72
+ request_path, route_path = [path, self.path].map(&->(array) { array.split('/') })
73
+ dynamic_indx.each do |i|
74
+ @url_args.merge!({ route_path[i].gsub(DYNAMIC_PREFIX, '') => request_path[i] })
75
+ end
76
+ end
46
77
  end
47
78
  end
48
79
  end
@@ -1,10 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rack'
4
+ require_relative './dbms/sqlite.rb'
5
+ require_relative './dbms/postgres.rb'
6
+
3
7
  module Makanai
4
8
  class Settings
5
- APP_ROOT_PATH = Dir.pwd
6
- DATABASE_PATH = '/db/makanai.db'
7
- TEMPLATE_ROOT_PATH = '/views/'
8
- MIGRATION_ROOT_PATH = '/migration/'
9
+ DEFAULT_APP_ROOT_PATH = Dir.pwd
10
+ DEFAULT_DATABASE_PATH = '/db/makanai.db'
11
+ DEFAULT_TEMPLATE_ROOT_PATH = '/views/'
12
+ DEFAULT_MIGRATION_ROOT_PATH = '/migration/'
13
+ DEFAULT_RACK_APP_CONFIG = { handler: :webrick, host: '0.0.0.0', port: '8080' }.freeze
14
+
15
+ @app_root_path = DEFAULT_APP_ROOT_PATH
16
+ @database_path = DEFAULT_DATABASE_PATH
17
+ @template_root_path = DEFAULT_TEMPLATE_ROOT_PATH
18
+ @migration_root_path = DEFAULT_MIGRATION_ROOT_PATH
19
+ @rack_app_config = DEFAULT_RACK_APP_CONFIG
20
+
21
+ # NOTE: Use Sqlite3
22
+ @databse_client = :sqlite
23
+ @databse_config = { path: File.join(@app_root_path, @database_path) }
24
+
25
+ # NOTE: Use Postgresql
26
+ # @databse_client = :postgres
27
+ # @databse_config = {
28
+ # host: 'localhost',
29
+ # password: 'password',
30
+ # dbname: 'makanai',
31
+ # port: 5432
32
+ # }.freeze
33
+
34
+ # NOTE: Use MySQL
35
+ # @databse_client = :mysql
36
+ # @databse_config = {
37
+ # host: 'localhost',
38
+ # username: 'root',
39
+ # password: 'password',
40
+ # database: 'makanai',
41
+ # port: 3306
42
+ # }.freeze
43
+
44
+ class << self
45
+ attr_accessor :app_root_path,
46
+ :database_path,
47
+ :template_root_path,
48
+ :migration_root_path,
49
+ :rack_app_config,
50
+ :databse_client,
51
+ :databse_config
52
+
53
+ def database_full_path
54
+ File.join(app_root_path, database_path)
55
+ end
56
+
57
+ def template_full_path
58
+ File.join(app_root_path, template_root_path)
59
+ end
60
+
61
+ def migration_full_path
62
+ File.join(app_root_path, migration_root_path)
63
+ end
64
+ end
9
65
  end
10
66
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Makanai
2
- VERSION = "0.1.0"
4
+ VERSION = '0.1.5'
3
5
  end
@@ -25,10 +25,12 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency "rake", "~> 10.0"
29
- spec.add_dependency "rack", "~> 2.0.7"
28
+ spec.add_dependency "rake", ">= 10", "< 14"
29
+ spec.add_dependency "rack", ">= 2.0.7", "< 2.3.0"
30
30
  spec.add_dependency "sqlite3", "~> 1.4.1"
31
31
  spec.add_development_dependency "rubocop", "~> 0.74"
32
32
  spec.add_development_dependency "bundler", "~> 2.0"
33
33
  spec.add_development_dependency "rspec", "~> 3.0"
34
+ spec.add_development_dependency "pg", "~> 1.2"
35
+ spec.add_development_dependency "mysql2", "~> 0.5"
34
36
  end
metadata CHANGED
@@ -1,43 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: makanai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Madogiwa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-22 00:00:00.000000000 Z
11
+ date: 2020-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '10'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '10.0'
22
+ version: '14'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '10'
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '10.0'
32
+ version: '14'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rack
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: 2.0.7
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 2.3.0
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - "~>"
47
+ - - ">="
39
48
  - !ruby/object:Gem::Version
40
49
  version: 2.0.7
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 2.3.0
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: sqlite3
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -94,17 +106,48 @@ dependencies:
94
106
  - - "~>"
95
107
  - !ruby/object:Gem::Version
96
108
  version: '3.0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: pg
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '1.2'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '1.2'
123
+ - !ruby/object:Gem::Dependency
124
+ name: mysql2
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '0.5'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '0.5'
97
137
  description: simple web application framework for learning.
98
138
  email:
99
139
  - madogiwa0124@gmail.com
100
- executables: []
140
+ executables:
141
+ - makanai
101
142
  extensions: []
102
143
  extra_rdoc_files: []
103
144
  files:
104
145
  - ".gitignore"
105
146
  - ".rspec"
106
147
  - ".rubocop.yml"
148
+ - ".ruby-version"
107
149
  - ".travis.yml"
150
+ - CHANGELOG.md
108
151
  - CODE_OF_CONDUCT.md
109
152
  - Gemfile
110
153
  - Gemfile.lock
@@ -113,10 +156,20 @@ files:
113
156
  - Rakefile
114
157
  - bin/console
115
158
  - bin/setup
159
+ - docker-compose.yml
160
+ - exe/makanai
116
161
  - lib/makanai.rb
117
162
  - lib/makanai/application.rb
118
163
  - lib/makanai/database.rb
164
+ - lib/makanai/dbms/base.rb
165
+ - lib/makanai/dbms/mysql.rb
166
+ - lib/makanai/dbms/postgres.rb
167
+ - lib/makanai/dbms/sqlite.rb
119
168
  - lib/makanai/dsl.rb
169
+ - lib/makanai/generator.rb
170
+ - lib/makanai/generator/application/directories.yaml
171
+ - lib/makanai/generator/application/templates/app.erb
172
+ - lib/makanai/generator/application/templates/rakefile.erb
120
173
  - lib/makanai/main.rb
121
174
  - lib/makanai/migration.rb
122
175
  - lib/makanai/model.rb
@@ -155,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
208
  - !ruby/object:Gem::Version
156
209
  version: '0'
157
210
  requirements: []
158
- rubygems_version: 3.0.3
211
+ rubygems_version: 3.1.2
159
212
  signing_key:
160
213
  specification_version: 4
161
214
  summary: simple web application framework for learning.