grimm 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +104 -0
- data/README.md +170 -1
- data/bin/grimm +3 -0
- data/circle.yml +3 -0
- data/grimm.gemspec +3 -2
- data/lib/grimm.rb +7 -7
- data/lib/grimm/controller.rb +10 -13
- data/lib/grimm/orm/database_connector.rb +5 -5
- data/lib/grimm/orm/grimm_record.rb +35 -60
- data/lib/grimm/orm/queries.rb +59 -0
- data/lib/grimm/routing.rb +27 -17
- data/lib/grimm/utilities.rb +4 -4
- data/lib/grimm/version.rb +1 -1
- data/lib/server.rb +18 -0
- metadata +28 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7465e50151eaf3c0eda4020897c796ad9d788b1
|
4
|
+
data.tar.gz: cf9c05a610368407ea558a7e1e0f268cf2b3266c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b93c5354a3cda1c073b97836041bea28c6a495c961861a21df517abb5f624a1319b1e9019188da3ac6fcd87120b7700cfa651e44f333fdba0994938f5ea86df7
|
7
|
+
data.tar.gz: c380bc378f366fd0f121f98877b6bb4ebf99f134cf9d8016b35094d31eae9cb99909ebaa1399cc5118c323136a4ff5efaf3f7f393d325f9eab5c96a0f6a1e7be
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
repo_token: RJIJT017MyKCPrtUcJ2JyY4QClIo83931
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
+
|
7
|
+
# Ignore bundler config.
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
/db/*.sqlite3-journal
|
13
|
+
|
14
|
+
# Ignore all logfiles and tempfiles.
|
15
|
+
/log/*
|
16
|
+
!/log/.keep
|
17
|
+
/tmp
|
18
|
+
|
19
|
+
# Ignore application configuration
|
20
|
+
/config/application.yml
|
21
|
+
/vendor/*
|
22
|
+
/index.html
|
23
|
+
/grimm.db
|
24
|
+
/coverage/*
|
data/.rspec
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
grimm (0.0.3)
|
5
|
+
pry
|
6
|
+
puma
|
7
|
+
rack
|
8
|
+
sqlite3
|
9
|
+
thor
|
10
|
+
tilt
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
addressable (2.4.0)
|
16
|
+
capybara (2.6.2)
|
17
|
+
addressable
|
18
|
+
mime-types (>= 1.16)
|
19
|
+
nokogiri (>= 1.3.3)
|
20
|
+
rack (>= 1.0.0)
|
21
|
+
rack-test (>= 0.5.4)
|
22
|
+
xpath (~> 2.0)
|
23
|
+
coderay (1.1.0)
|
24
|
+
coveralls (0.8.10)
|
25
|
+
json (~> 1.8)
|
26
|
+
rest-client (>= 1.6.8, < 2)
|
27
|
+
simplecov (~> 0.11.0)
|
28
|
+
term-ansicolor (~> 1.3)
|
29
|
+
thor (~> 0.19.1)
|
30
|
+
tins (~> 1.6.0)
|
31
|
+
diff-lcs (1.2.5)
|
32
|
+
docile (1.1.5)
|
33
|
+
domain_name (0.5.20160128)
|
34
|
+
unf (>= 0.0.5, < 1.0.0)
|
35
|
+
http-cookie (1.0.2)
|
36
|
+
domain_name (~> 0.5)
|
37
|
+
json (1.8.3)
|
38
|
+
method_source (0.8.2)
|
39
|
+
mime-types (2.99)
|
40
|
+
mime-types-data (3.2015.1120)
|
41
|
+
mini_portile2 (2.0.0)
|
42
|
+
minitest (5.8.4)
|
43
|
+
netrc (0.11.0)
|
44
|
+
nokogiri (1.6.7.2)
|
45
|
+
mini_portile2 (~> 2.0.0.rc2)
|
46
|
+
pry (0.10.3)
|
47
|
+
coderay (~> 1.1.0)
|
48
|
+
method_source (~> 0.8.1)
|
49
|
+
slop (~> 3.4)
|
50
|
+
puma (2.16.0)
|
51
|
+
rack (1.6.4)
|
52
|
+
rack-test (0.6.3)
|
53
|
+
rack (>= 1.0)
|
54
|
+
rake (10.5.0)
|
55
|
+
rest-client (1.8.0)
|
56
|
+
http-cookie (>= 1.0.2, < 2.0)
|
57
|
+
mime-types (>= 1.16, < 3.0)
|
58
|
+
netrc (~> 0.7)
|
59
|
+
rspec (3.4.0)
|
60
|
+
rspec-core (~> 3.4.0)
|
61
|
+
rspec-expectations (~> 3.4.0)
|
62
|
+
rspec-mocks (~> 3.4.0)
|
63
|
+
rspec-core (3.4.2)
|
64
|
+
rspec-support (~> 3.4.0)
|
65
|
+
rspec-expectations (3.4.0)
|
66
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
+
rspec-support (~> 3.4.0)
|
68
|
+
rspec-mocks (3.4.1)
|
69
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
70
|
+
rspec-support (~> 3.4.0)
|
71
|
+
rspec-support (3.4.1)
|
72
|
+
simplecov (0.11.1)
|
73
|
+
docile (~> 1.1.0)
|
74
|
+
json (~> 1.8)
|
75
|
+
simplecov-html (~> 0.10.0)
|
76
|
+
simplecov-html (0.10.0)
|
77
|
+
slop (3.6.0)
|
78
|
+
sqlite3 (1.3.11)
|
79
|
+
term-ansicolor (1.3.2)
|
80
|
+
tins (~> 1.0)
|
81
|
+
thor (0.19.1)
|
82
|
+
tilt (2.0.2)
|
83
|
+
tins (1.6.0)
|
84
|
+
unf (0.1.4)
|
85
|
+
unf_ext
|
86
|
+
unf_ext (0.0.7.1)
|
87
|
+
xpath (2.0.0)
|
88
|
+
nokogiri (~> 1.3)
|
89
|
+
|
90
|
+
PLATFORMS
|
91
|
+
ruby
|
92
|
+
|
93
|
+
DEPENDENCIES
|
94
|
+
bundler (~> 1.11)
|
95
|
+
capybara
|
96
|
+
coveralls
|
97
|
+
grimm!
|
98
|
+
minitest (~> 5.0)
|
99
|
+
rake (~> 10.0)
|
100
|
+
rspec
|
101
|
+
simplecov
|
102
|
+
|
103
|
+
BUNDLED WITH
|
104
|
+
1.11.2
|
data/README.md
CHANGED
@@ -1 +1,170 @@
|
|
1
|
-
#
|
1
|
+
# Grimm
|
2
|
+
[![Coverage Status](https://coveralls.io/repos/github/andela-aadepoju/grimm/badge.svg?branch=ch-tests-07)](https://coveralls.io/github/andela-aadepoju/grimm?branch=ch-tests-07)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/grimm.svg)](https://badge.fury.io/rb/grimm)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/andela-aadepoju/grimm/badges/gpa.svg)](https://codeclimate.com/github/andela-aadepoju/grimm)
|
5
|
+
|
6
|
+
Grimm is a mini MVC framework written in ruby. It is a look alike of Ruby on Rails. It is light weight and very easy to use.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
From your terminal run:
|
11
|
+
|
12
|
+
$ gem install grimm
|
13
|
+
|
14
|
+
if you have an existing app, just add the gem to your gem file.
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem "grimm"
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle install
|
23
|
+
|
24
|
+
### Grimm App
|
25
|
+
Grimm App is the base app for Grimm gem. Clone the app to your local machine:
|
26
|
+
|
27
|
+
$ git clone git@github.com:andela-aadepoju/grimm_todo.git
|
28
|
+
This app is a Todo app. Its will give you an insight on how Grimm can be used.
|
29
|
+
|
30
|
+
# Understanding Grimm
|
31
|
+
|
32
|
+
|
33
|
+
## Grimm Controllers
|
34
|
+
|
35
|
+
Controllers are made up of methods often called actions, that are executed on request. It either renders a template or redirects to another action among many othe functions.
|
36
|
+
|
37
|
+
For an app using Grimm, the controller class must follow the pattern below.
|
38
|
+
|
39
|
+
`ApplicationController` class inherits from `Grimm::BaseController`. Every other controller class inherits from `ApplicationController` e.g `ListsController << ApplicationController`
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class ApplicationController < Grimm::BaseController
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
class ListsController < ApplicationController
|
47
|
+
def index
|
48
|
+
@lists = List.all
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
Actions, render template in the app/views folder corresponding to the name of the controller and action after executing code in the action.
|
54
|
+
|
55
|
+
For example, the index action of the `ListsController` would render the template `app/views/lists/index.html.erb` by default after populating the `@lists` instance variable.
|
56
|
+
|
57
|
+
Also controllers should be named in their pluralized form. Controllers would render its corresponding views without the `@lists` instance.
|
58
|
+
|
59
|
+
The `redirect_to` method redirects to the specified route
|
60
|
+
|
61
|
+
|
62
|
+
## Grimm Models
|
63
|
+
|
64
|
+
Models are classes in the models folder. These classes are responsible for communications with the database.
|
65
|
+
All models should inherit from the `Grimm::GrimmRecord`. All model classes should be named as a singular object.
|
66
|
+
|
67
|
+
Example model class displaying available methods:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class List < Grimm::GrimmRecord
|
71
|
+
to_table :lists
|
72
|
+
property :id, type: :integer, primary_key: true
|
73
|
+
property :title, type: :text, nullable: false
|
74
|
+
property :body, type: :text, nullable: false
|
75
|
+
property :created_at, type: :text, nullable: false
|
76
|
+
property :done, type: :boolean, nullable: false, default: false
|
77
|
+
create_table
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
`to_table` This method is used to name the table in the database.
|
82
|
+
|
83
|
+
`property` This method is used to define the columns of a table in the database. As seen in the example above, the column type should also be defined on this method.
|
84
|
+
|
85
|
+
`created_table` This method triggers the main table creation.
|
86
|
+
|
87
|
+
## Grimm Views
|
88
|
+
|
89
|
+
`Grimm::BaseController` sends response to the views either by making use of render method declared within the controller method or by inferring the template to display from the name of the controllers. The render action looks for the corresponding views for every method in the controller. These files must be placed in a folder that has the same name as the controller.
|
90
|
+
|
91
|
+
The render method which enables rendering of ERB templates is automatically configured.
|
92
|
+
Objects can be passed from the controller to the view by either assigning them as instance variables or by passing the object as a parameter to the render method:
|
93
|
+
|
94
|
+
Having instance variable `@lists` makes `lists` object available to `views\lists\index.html.erb` and this is automatically rendered without explicitly calling the render method.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
def index
|
98
|
+
@list = List.find(params["id"])
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
This method also renders the index template
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
def index
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
## Parameters
|
110
|
+
|
111
|
+
All request parameters, whether they come from a GET or POST request, or from the URL, are available through the `params` method which returns a hash.
|
112
|
+
|
113
|
+
It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
|
114
|
+
|
115
|
+
```html
|
116
|
+
<input type="text" name="lists[title]" value="Title">
|
117
|
+
<input type="text" name="lists[body]" value="Body">
|
118
|
+
```
|
119
|
+
The params can also be extracted into a private method such as `lists_params`
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
def lists_params
|
123
|
+
params[lists]
|
124
|
+
end
|
125
|
+
```
|
126
|
+
## Routes
|
127
|
+
|
128
|
+
Routes are HTTP methods paired with a URL matching patter, the first route that matches a request is invoked.
|
129
|
+
Route patterns may include named parameters, which can be gotten from the params hash:
|
130
|
+
|
131
|
+
They are defined in the file `config/routes.rb`
|
132
|
+
|
133
|
+
The `resources` makes available all the routes written below `resources :lists`
|
134
|
+
the `resources` method sets the default routes to the `index`, `new`, `edit`, `show`, `update`, `delete` controller methods.
|
135
|
+
|
136
|
+
Where `lists` is the name of the controller, and all words behind the `#` are action methods defined in your controller.
|
137
|
+
|
138
|
+
The `root` method is used to set the root path
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
|
142
|
+
PostApplication.routes.draw do
|
143
|
+
root "mypages#index"
|
144
|
+
get "/all_posts", to: "posts#index"
|
145
|
+
resources :posts
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
In the case of a request being made to an undefined route an error message is returned.
|
150
|
+
|
151
|
+
## Running the app
|
152
|
+
From terminal, run:
|
153
|
+
|
154
|
+
$ grimm server
|
155
|
+
|
156
|
+
This will lunch the app on port 4500
|
157
|
+
## Development
|
158
|
+
|
159
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rspec spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
160
|
+
|
161
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
162
|
+
|
163
|
+
## Contributing
|
164
|
+
|
165
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/andela-aadepoju/grimm. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
166
|
+
|
167
|
+
|
168
|
+
## License
|
169
|
+
|
170
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/bin/grimm
ADDED
data/circle.yml
ADDED
data/grimm.gemspec
CHANGED
@@ -26,8 +26,8 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
27
|
f.match(%r{^(test|spec|features)/})
|
28
28
|
end
|
29
|
-
spec.bindir = "
|
30
|
-
spec.executables =
|
29
|
+
spec.bindir = "bin"
|
30
|
+
spec.executables = "grimm"
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
33
|
spec.add_development_dependency "bundler", "~> 1.11"
|
@@ -38,4 +38,5 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.add_runtime_dependency "pry"
|
39
39
|
spec.add_runtime_dependency "puma"
|
40
40
|
spec.add_runtime_dependency "sqlite3"
|
41
|
+
spec.add_runtime_dependency "thor"
|
41
42
|
end
|
data/lib/grimm.rb
CHANGED
@@ -4,31 +4,31 @@ require "grimm/utilities.rb"
|
|
4
4
|
require "grimm/dependencies.rb"
|
5
5
|
require "grimm/routing.rb"
|
6
6
|
require "pry"
|
7
|
-
require "grimm/orm/database_connector.rb"
|
8
7
|
require "grimm/orm/grimm_record.rb"
|
9
8
|
|
10
|
-
|
11
9
|
module Grimm
|
12
10
|
class Application
|
13
11
|
attr_reader :request
|
14
12
|
def call(env)
|
15
13
|
@request = Rack::Request.new(env)
|
16
14
|
if request.path_info == "/favicon.ico"
|
17
|
-
return [404,{}, []]
|
15
|
+
return [404, {}, []]
|
18
16
|
end
|
19
|
-
page = get_rack_app(
|
17
|
+
page = get_rack_app(request)
|
20
18
|
if page.nil?
|
21
|
-
return [404, {}, ["#{request.request_method.downcase} #{request.path}
|
19
|
+
return [404, {}, ["#{request.request_method.downcase} #{request.path}
|
20
|
+
was not defined in the route. Check /config/routes.rb for defined
|
21
|
+
routes"]]
|
22
22
|
else
|
23
23
|
page
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def route
|
27
|
+
def route
|
28
28
|
@router ||= Grimm::Router.new
|
29
29
|
end
|
30
30
|
|
31
|
-
def get_rack_app(
|
31
|
+
def get_rack_app(request)
|
32
32
|
@router.check_url(request)
|
33
33
|
end
|
34
34
|
end
|
data/lib/grimm/controller.rb
CHANGED
@@ -21,11 +21,12 @@ module Grimm
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def render_template(view_name, locals = {})
|
24
|
-
template = Tilt::ERBTemplate.new(File.join( "app", "views",
|
25
|
-
|
24
|
+
template = Tilt::ERBTemplate.new(File.join($:.first, "app", "views",
|
25
|
+
"layouts",
|
26
|
+
"application.html.erb"))
|
26
27
|
title = view_name.to_s.tr("_", " ").capitalize
|
27
28
|
view = "#{view_name}.html.erb"
|
28
|
-
view_template = Tilt::ERBTemplate.new(File.join( "app", "views",
|
29
|
+
view_template = Tilt::ERBTemplate.new(File.join($:.first, "app", "views",
|
29
30
|
controller_name, view))
|
30
31
|
template.render(self, title: title) do
|
31
32
|
view_template.render(self, locals.merge!(get_vars))
|
@@ -35,7 +36,7 @@ module Grimm
|
|
35
36
|
def get_vars
|
36
37
|
vars = {}
|
37
38
|
instance_variables.each do |var|
|
38
|
-
key = var.to_s.
|
39
|
+
key = var.to_s.delete("@").to_sym
|
39
40
|
vars[key] = instance_variable_get(var)
|
40
41
|
end
|
41
42
|
vars
|
@@ -50,21 +51,17 @@ module Grimm
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def redirect_to(url)
|
53
|
-
|
54
|
+
@response = Rack::Response.new({}, 302, "location" => url)
|
54
55
|
end
|
55
56
|
|
56
57
|
def dispatch(action)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
else
|
61
|
-
render(action)
|
62
|
-
get_response
|
63
|
-
end
|
58
|
+
send(action)
|
59
|
+
render(action) unless get_response
|
60
|
+
get_response
|
64
61
|
end
|
65
62
|
|
66
63
|
def self.action(request, action_name)
|
67
|
-
|
64
|
+
new(request).dispatch(action_name)
|
68
65
|
end
|
69
66
|
end
|
70
67
|
end
|
@@ -2,13 +2,13 @@ module Grimm
|
|
2
2
|
class DatabaseConnector
|
3
3
|
|
4
4
|
def self.connect_db
|
5
|
-
|
5
|
+
@db = SQLite3::Database.new File.join "grimm.db"
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.execute(query, args =
|
9
|
-
|
10
|
-
return
|
11
|
-
|
8
|
+
def self.execute(query, args = nil)
|
9
|
+
@db ||= connect_db
|
10
|
+
return @db.execute(query, args) if args
|
11
|
+
@db.execute(query)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -1,89 +1,79 @@
|
|
1
|
+
require "grimm/orm/database_connector.rb"
|
2
|
+
require "grimm/orm/queries.rb"
|
1
3
|
require "sqlite3"
|
2
4
|
|
3
5
|
module Grimm
|
4
6
|
class GrimmRecord
|
5
|
-
@@properties = {}
|
6
|
-
@@table = nil
|
7
7
|
|
8
8
|
def self.to_table(table_name)
|
9
|
-
|
9
|
+
@table = table_name
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.property(column_name, args)
|
13
|
-
|
13
|
+
@properties ||= {}
|
14
|
+
@properties[column_name] = args
|
14
15
|
end
|
15
16
|
|
16
17
|
def self.create_table
|
17
18
|
prop_array = []
|
18
|
-
|
19
|
-
properties
|
20
|
-
properties <<
|
19
|
+
@properties.each do |key, value|
|
20
|
+
properties ||= []
|
21
|
+
properties << key.to_s
|
21
22
|
value.each do |name, type|
|
22
|
-
|
23
|
-
if name == "primary_key" && type
|
24
|
-
properties << "PRIMARY KEY AUTOINCREMENT"
|
25
|
-
elsif name == "autoincrement" && type
|
26
|
-
properties << "AUTOINCREMENT"
|
27
|
-
elsif name == "nullable" && !type
|
28
|
-
properties << "NOT NULL"
|
29
|
-
elsif name == "type"
|
30
|
-
properties << type.to_s
|
31
|
-
end
|
23
|
+
properties << send("#{name.downcase}_query", type)
|
32
24
|
end
|
33
25
|
prop_array << properties.join(" ")
|
34
26
|
end
|
35
|
-
query = "CREATE TABLE IF NOT EXISTS #{
|
27
|
+
query = "CREATE TABLE IF NOT EXISTS #{@table} (#{prop_array.join(', ')})"
|
36
28
|
DatabaseConnector.execute(query)
|
37
29
|
make_methods
|
38
30
|
end
|
39
31
|
|
40
32
|
def self.make_methods
|
41
|
-
mtds =
|
42
|
-
|
43
|
-
mtds.each { |mtd| attr_accessor mtd }
|
44
|
-
end
|
33
|
+
mtds = @properties.keys.map(&:to_sym)
|
34
|
+
mtds.each { |mtd| attr_accessor mtd }
|
45
35
|
end
|
46
36
|
|
47
|
-
def
|
48
|
-
if
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
VALUES (#{new_record_placeholders})", new_record_value
|
54
|
-
end
|
37
|
+
def self.primary_key_query(value = false)
|
38
|
+
"PRIMARY KEY AUTOINCREMENT" if value
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.autoincrement_query(value = false)
|
42
|
+
"AUTOINCREMENT" if value
|
55
43
|
end
|
56
44
|
|
57
|
-
def
|
45
|
+
def self.nullable_query(value = true)
|
46
|
+
"NOT NULL" unless value
|
47
|
+
end
|
58
48
|
|
49
|
+
def self.type_query(value)
|
50
|
+
value.to_s
|
59
51
|
end
|
60
52
|
|
61
|
-
def self.
|
62
|
-
|
63
|
-
FROM #{@@table} WHERE id = ?", id).first
|
64
|
-
self.map_object(row)
|
53
|
+
def self.properties_keys
|
54
|
+
@properties.keys
|
65
55
|
end
|
66
56
|
|
67
57
|
def get_values
|
68
|
-
attributes =
|
58
|
+
attributes = self.class.properties_keys
|
69
59
|
attributes.delete(:id)
|
70
|
-
attributes.map { |method|
|
60
|
+
attributes.map { |method| send(method) }
|
71
61
|
end
|
72
62
|
|
73
63
|
def update_records_placeholders
|
74
|
-
columns =
|
64
|
+
columns = self.class.properties_keys
|
75
65
|
columns.delete(:id)
|
76
66
|
columns.map { |col| "#{col}=?" }.join(",")
|
77
67
|
end
|
78
68
|
|
79
69
|
def get_columns
|
80
|
-
columns =
|
70
|
+
columns = self.class.properties_keys
|
81
71
|
columns.delete(:id)
|
82
72
|
columns.join(",")
|
83
73
|
end
|
84
74
|
|
85
75
|
def update_records
|
86
|
-
get_values <<
|
76
|
+
get_values << send(:id)
|
87
77
|
end
|
88
78
|
|
89
79
|
def new_record_value
|
@@ -91,31 +81,16 @@ module Grimm
|
|
91
81
|
end
|
92
82
|
|
93
83
|
def new_record_placeholders
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
def method_missing(method, *args)
|
98
|
-
@model.send(method)
|
84
|
+
properties = self.class.properties_keys
|
85
|
+
(["?"] * (properties.size - 1)).join(",")
|
99
86
|
end
|
100
87
|
|
101
88
|
def self.map_object(row)
|
102
|
-
model_name =
|
103
|
-
|
89
|
+
model_name = new
|
90
|
+
@properties.each_key.with_index do |value, index|
|
104
91
|
model_name.send("#{value}=", row[index])
|
105
92
|
end
|
106
|
-
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.findAll
|
110
|
-
data = DatabaseConnector.execute "SELECT #{@@properties.keys.join(',')}
|
111
|
-
FROM #{@@table}"
|
112
|
-
data.map do |row|
|
113
|
-
self.map_object(row)
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.delete(id)
|
118
|
-
DatabaseConnector.execute "DELETE FROM #{@@table} WHERE id = ?", id
|
93
|
+
model_name
|
119
94
|
end
|
120
95
|
end
|
121
96
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Grimm
|
2
|
+
class GrimmRecord
|
3
|
+
|
4
|
+
def self.find(id)
|
5
|
+
row = DatabaseConnector.execute("SELECT #{properties_keys.join(',')}
|
6
|
+
FROM #{@table} WHERE id = ?", id).first
|
7
|
+
map_object(row)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.all
|
11
|
+
data = DatabaseConnector.execute "SELECT #{properties_keys.join(',')}
|
12
|
+
FROM #{@table}"
|
13
|
+
data.map do |row|
|
14
|
+
map_object(row)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.latest
|
19
|
+
data = DatabaseConnector.execute "SELECT #{properties_keys.join(',')}
|
20
|
+
FROM #{@table} ORDER BY created_at DESC"
|
21
|
+
data.map do |row|
|
22
|
+
map_object(row)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.delete(id)
|
27
|
+
DatabaseConnector.execute "DELETE FROM #{@table} WHERE id = ?", id
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.delete_all
|
31
|
+
DatabaseConnector.execute "DELETE FROM #{@table}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.last
|
35
|
+
query = "SELECT * FROM #{@table} ORDER BY id DESC LIMIT 1"
|
36
|
+
(DatabaseConnector.execute query).first
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.first
|
40
|
+
query = "SELECT * FROM #{@table} ORDER BY id LIMIT 1"
|
41
|
+
(DatabaseConnector.execute query).first
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.table_name
|
45
|
+
@table
|
46
|
+
end
|
47
|
+
|
48
|
+
def save
|
49
|
+
table_name = self.class.table_name
|
50
|
+
if id
|
51
|
+
DatabaseConnector.execute "UPDATE #{table_name} SET
|
52
|
+
#{update_records_placeholders} WHERE id = ?", update_records
|
53
|
+
else
|
54
|
+
DatabaseConnector.execute "INSERT INTO #{table_name} (#{get_columns})
|
55
|
+
VALUES (#{new_record_placeholders})", new_record_value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/grimm/routing.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
module Grimm
|
2
|
-
|
3
2
|
class Router
|
4
3
|
attr_reader :routes
|
5
4
|
def initialize
|
6
|
-
@routes = Hash.new { |hash, key| hash[key] =
|
5
|
+
@routes = Hash.new { |hash, key| hash[key] = [] }
|
7
6
|
end
|
8
7
|
|
9
8
|
def self.match_verbs(*verbs)
|
@@ -13,24 +12,32 @@ module Grimm
|
|
13
12
|
url_parts.select! { |part| !part.empty? }
|
14
13
|
placeholder = []
|
15
14
|
regexp_parts = url_parts.map do |part|
|
16
|
-
|
17
|
-
placeholder << part[1..-1]
|
18
|
-
"([A-Za-z0-9_]+)"
|
19
|
-
else
|
20
|
-
part
|
21
|
-
end
|
15
|
+
check_part(placeholder, part)
|
22
16
|
end
|
23
|
-
|
24
|
-
routes[verb] << [Regexp.new("^/#{regexp}$"),
|
25
|
-
parse_to(options[:to]), placeholder]
|
17
|
+
save_routes(regexp_parts, verb, placeholder, options)
|
26
18
|
end
|
27
19
|
end
|
28
20
|
end
|
29
21
|
|
22
|
+
def check_part(placeholder, part)
|
23
|
+
if part[0] == ":"
|
24
|
+
placeholder << part[1..-1]
|
25
|
+
"([A-Za-z0-9_]+)"
|
26
|
+
else
|
27
|
+
part
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def save_routes(regexp_parts, verb, placeholder, options)
|
32
|
+
regexp = regexp_parts.join("/")
|
33
|
+
routes[verb] << [Regexp.new("^/#{regexp}$"),
|
34
|
+
parse_to(options[:to]), placeholder]
|
35
|
+
end
|
36
|
+
|
30
37
|
match_verbs :get, :post, :put, :patch, :delete
|
31
38
|
|
32
39
|
def draw(&block)
|
33
|
-
|
40
|
+
instance_eval(&block)
|
34
41
|
end
|
35
42
|
|
36
43
|
def root(address)
|
@@ -43,9 +50,8 @@ module Grimm
|
|
43
50
|
get("/#{args}/new", to: "#{args}#new")
|
44
51
|
get("/#{args}/:id", to: "#{args}#show")
|
45
52
|
get("/#{args}/edit/:id", to: "#{args}#edit")
|
46
|
-
|
53
|
+
delete("/#{args}/:id", to: "#{args}#destroy")
|
47
54
|
post("/#{args}/", to: "#{args}#create")
|
48
|
-
post("/#{args}/:id", to: "#{args}#update")
|
49
55
|
put("/#{args}/:id", to: "#{args}#update")
|
50
56
|
end
|
51
57
|
|
@@ -53,8 +59,12 @@ module Grimm
|
|
53
59
|
url = request.path_info
|
54
60
|
verb = request.request_method.downcase.to_sym
|
55
61
|
route_match = routes[verb].detect do |route|
|
56
|
-
|
62
|
+
route.first.match(url)
|
57
63
|
end
|
64
|
+
find_match(route_match, url, request)
|
65
|
+
end
|
66
|
+
|
67
|
+
def find_match(route_match, url, request)
|
58
68
|
if route_match
|
59
69
|
placeholder = {}
|
60
70
|
match = route_match.first.match(url)
|
@@ -70,8 +80,8 @@ module Grimm
|
|
70
80
|
|
71
81
|
def convert_target(request, route)
|
72
82
|
controller_name = route[:controller].camelcase
|
73
|
-
controller = Object.
|
74
|
-
|
83
|
+
controller = Object.const_get("#{controller_name}Controller")
|
84
|
+
controller.action(request, route[:target])
|
75
85
|
end
|
76
86
|
|
77
87
|
private
|
data/lib/grimm/utilities.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
class String
|
2
2
|
def snake_case
|
3
|
-
|
3
|
+
gsub("::", "/")
|
4
4
|
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
5
|
-
|
6
|
-
|
5
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
6
|
+
tr("-", "_").downcase
|
7
7
|
end
|
8
8
|
|
9
9
|
def camelcase
|
10
10
|
return self if self !~ /_/ && self =~ /[A-Z]+.*/
|
11
|
-
split("_").map
|
11
|
+
split("_").map(&:capitalize).join
|
12
12
|
end
|
13
13
|
end
|
data/lib/grimm/version.rb
CHANGED
data/lib/server.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "thor"
|
2
|
+
module Grimm
|
3
|
+
class Server < Thor
|
4
|
+
|
5
|
+
desc "server", "This starts the app server"
|
6
|
+
def server
|
7
|
+
start_server
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def start_server
|
13
|
+
exec "bundle exec rackup"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Grimm::Server.start(ARGV)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grimm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mradeybee
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,31 +122,54 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: thor
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: This is a mini framework built with ruby.
|
126
140
|
email:
|
127
141
|
- mradeybee@gmail.com
|
128
|
-
executables:
|
142
|
+
executables:
|
143
|
+
- grimm
|
129
144
|
extensions: []
|
130
145
|
extra_rdoc_files: []
|
131
146
|
files:
|
147
|
+
- ".coveralls.yml"
|
148
|
+
- ".gitignore"
|
149
|
+
- ".rspec"
|
132
150
|
- ".rubocop.yml"
|
133
151
|
- ".travis.yml"
|
134
152
|
- CODE_OF_CONDUCT.md
|
135
153
|
- Gemfile
|
154
|
+
- Gemfile.lock
|
136
155
|
- LICENSE.txt
|
137
156
|
- README.md
|
138
157
|
- Rakefile
|
139
158
|
- bin/console
|
159
|
+
- bin/grimm
|
140
160
|
- bin/setup
|
161
|
+
- circle.yml
|
141
162
|
- grimm.gemspec
|
142
163
|
- lib/grimm.rb
|
143
164
|
- lib/grimm/controller.rb
|
144
165
|
- lib/grimm/dependencies.rb
|
145
166
|
- lib/grimm/orm/database_connector.rb
|
146
167
|
- lib/grimm/orm/grimm_record.rb
|
168
|
+
- lib/grimm/orm/queries.rb
|
147
169
|
- lib/grimm/routing.rb
|
148
170
|
- lib/grimm/utilities.rb
|
149
171
|
- lib/grimm/version.rb
|
172
|
+
- lib/server.rb
|
150
173
|
homepage: https://github.com/andela-aadepoju/grimm
|
151
174
|
licenses:
|
152
175
|
- MIT
|
@@ -168,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
191
|
version: '0'
|
169
192
|
requirements: []
|
170
193
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.5.
|
194
|
+
rubygems_version: 2.5.2
|
172
195
|
signing_key:
|
173
196
|
specification_version: 4
|
174
197
|
summary: A ruby framework
|