easymvc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7fafc584dd1a3631b14bd63291a0b84116f15abe
4
+ data.tar.gz: e1437a7b5ec414408cda0c779c566f4a649dca21
5
+ SHA512:
6
+ metadata.gz: b66e2a57111d3adbe7a7ec0040dfab67e4b801b3c7881956b12d01977525a30f9dbc21842067cc703037001d178dda7cc1e938f5362e86b81d87d5beb10d696c
7
+ data.tar.gz: f28c7185ade7ca562416c04f254b3c73b3222ed17de7bba55a284003476a85e3ae4c38d427b8f193df63c3044b397b1cc9a8155ff844a8ad9fed08dc7a9bef6e
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in easymvc.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 afurm
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # EasyMvc
2
+
3
+ If you are going to build something small this framework for you.
4
+ See example of using in 'example' folder.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'easymvc'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install easymvc
19
+
20
+ ## Usage
21
+ 1. Go to example folder
22
+ 2. Run 'rackup'
23
+ 3. Go to http://localhost:9292
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( http://github.com/<my-github-username>/easymvc/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/easymvc.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'easymvc/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "easymvc"
8
+ spec.version = EasyMvc::VERSION
9
+ spec.authors = ["afurm"]
10
+ spec.email = ["furmanets.andriy@gmail.com"]
11
+ spec.summary = %q{EasyMvc.}
12
+ spec.description = %q{EasyMvc.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_runtime_dependency "rack"
25
+ spec.add_runtime_dependency "erubis"
26
+ spec.add_runtime_dependency "sqlite3"
27
+ end
data/example/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "easymvc"
@@ -0,0 +1,35 @@
1
+ class PostsController < EasyMvc::Controller
2
+ def new
3
+ @post = Post.new
4
+ end
5
+
6
+ def create
7
+ post_params = params["post"]
8
+ @post = Post.new
9
+ @post.title = post_params["title"]
10
+ @post.body = post_params["body"]
11
+ @post.created_at = Time.now
12
+
13
+ PostMapper.new.save(@post)
14
+ end
15
+
16
+ def index
17
+ @posts = PostMapper.find_all
18
+ end
19
+
20
+ def edit
21
+ @post = PostMapper.find(params["id"])
22
+ end
23
+
24
+ def update
25
+ @post = PostMapper.find(params["id"])
26
+ @post.title = params["post"]["title"]
27
+ @post.body = params["post"]["body"]
28
+
29
+ PostMapper.new.save(@post)
30
+ end
31
+
32
+ def delete
33
+ PostMapper.new.delete(params["id"])
34
+ end
35
+ end
@@ -0,0 +1,10 @@
1
+ class Post
2
+ attr_accessor :id, :title, :body, :created_at
3
+
4
+ def initialize
5
+ @id = nil
6
+ @title = ""
7
+ @body = ""
8
+ @created_at = nil
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ class PostMapper < EasyMvc::Mapper
2
+ @@table_name = "posts"
3
+ @@model = Post
4
+ @@mapping = {
5
+ id: :id,
6
+ header: :title,
7
+ content: :body,
8
+ created_at: :created_at
9
+ }
10
+
11
+ def created_at
12
+ @model.created_at.to_s
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ <a href="/posts/index"> Back to index </a>
@@ -0,0 +1 @@
1
+ <a href="/posts/index"> Back to index </a>
@@ -0,0 +1,8 @@
1
+ <h1>Update Post</h1>
2
+
3
+ <form action="/posts/update">
4
+ <input type="hidden" name="id" value="<%= post.id %>"/>
5
+ <input type="text" name="post[title]" value="<%= post.title %>"/><p>
6
+ <textarea rows="10" cols="30" name="post[body]" id=""><%= post.body %></textarea><p>
7
+ <button type="submit">Update</button>
8
+ </form>
@@ -0,0 +1,7 @@
1
+
2
+ <% posts.each do |post| %>
3
+ <a href="/posts/edit?id=<%= post.id %>"><%= post.title %></a> -
4
+ <a href="/posts/delete?id=<%= post.id %>"> Delete </a></br>
5
+ <% end %>
6
+
7
+ <a href="/posts/new">Create new</a>
@@ -0,0 +1,7 @@
1
+ <h1>Create new Post</h1>
2
+
3
+ <form action="/posts/create">
4
+ <input type="text" name="post[title]" value=""/><p>
5
+ <textarea rows="10" cols="30" name="post[body]" id=""></textarea><p>
6
+ <button type="submit">Create</button>
7
+ </form>
@@ -0,0 +1 @@
1
+ <a href="/posts/index"> Back to index </a>
data/example/config.ru ADDED
@@ -0,0 +1,9 @@
1
+ require './config/application.rb'
2
+ app = Blog::Application.new
3
+
4
+ app.route do
5
+ match "/", "posts#index"
6
+ match "/:controller/:action"
7
+ end
8
+
9
+ run app
@@ -0,0 +1,9 @@
1
+ require 'easymvc'
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "..", "app", "controllers")
4
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "..", "app", "models")
5
+
6
+ module Blog
7
+ class Application < EasyMvc::Application
8
+ end
9
+ end
data/example/db/app.db ADDED
Binary file
@@ -0,0 +1,12 @@
1
+ require 'sqlite3'
2
+
3
+ db = SQLite3::Database.new File.join("db", "app.db")
4
+
5
+ db.execute <<SQL
6
+ create table posts (
7
+ id integer primary key,
8
+ header varchar(250),
9
+ content text,
10
+ created_at datetime default null
11
+ )
12
+ SQL
data/lib/easymvc.rb ADDED
@@ -0,0 +1,24 @@
1
+ require "easymvc/version"
2
+ require "easymvc/controller"
3
+ require "easymvc/dependencies"
4
+ require "easymvc/utils"
5
+ require "easymvc/routing"
6
+ require "easymvc/mapper"
7
+
8
+ module EasyMvc
9
+ class Application
10
+ def call(env)
11
+ return [500, {}, []] if env["PATH_INFO"] == "/favicon.ico"
12
+ get_rack_app(env).call(env)
13
+ end
14
+
15
+ def route(&block)
16
+ @router ||= EasyMvc::Routes.new
17
+ @router.instance_eval(&block)
18
+ end
19
+
20
+ def get_rack_app(env)
21
+ @router.check_url(env["PATH_INFO"])
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,58 @@
1
+ require 'erubis'
2
+
3
+ module EasyMvc
4
+ class Controller
5
+ attr_reader :request
6
+
7
+ def initialize(env)
8
+ @request ||= Rack::Request.new(env)
9
+ end
10
+
11
+ def params
12
+ request.params
13
+ end
14
+
15
+ def response(body, status = 200, header = {})
16
+ @response = Rack::Response.new(body, status, header)
17
+ end
18
+
19
+ def get_response
20
+ @response
21
+ end
22
+
23
+ def render(*args)
24
+ response(render_template(*args))
25
+ end
26
+
27
+ def render_template(view_name, locals ={})
28
+ filename = File.join("app", "views", controller_name, "#{view_name}.erb")
29
+ template = File.read(filename)
30
+
31
+ vars = {}
32
+ instance_variables.each do |var|
33
+ key = var.to_s.gsub("@", "").to_sym
34
+ vars[key] = instance_variable_get(var)
35
+ end
36
+
37
+ Erubis::Eruby.new(template).result(locals.merge(vars))
38
+ end
39
+
40
+ def controller_name
41
+ self.class.to_s.gsub(/Controller$/, "").downcase
42
+ end
43
+
44
+ def dispatch(action)
45
+ content = self.send(action)
46
+ if get_response
47
+ get_response
48
+ else
49
+ render(action)
50
+ get_response
51
+ end
52
+ end
53
+
54
+ def self.action(action_name)
55
+ -> (env) { self.new(env).dispatch(action_name) }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def self.const_missing(const)
3
+ require const.to_s.to_snake_case
4
+ Object.const_get(const)
5
+ end
6
+ end
@@ -0,0 +1,81 @@
1
+ require 'sqlite3'
2
+
3
+ module EasyMvc
4
+ class Mapper
5
+ @@db = SQLite3::Database.new File.join "db", "app.db"
6
+ @@table_name = ""
7
+ @@model = nil
8
+ @@mapping = { }
9
+
10
+ def save(model)
11
+ @model = model
12
+ if model.id
13
+ @@db.execute %Q(
14
+ UPDATE #{@@table_name}
15
+ SET #{update_record_placeholders}
16
+ where id = ?), update_record_values
17
+ else
18
+ @@db.execute "INSERT INTO #{@@table_name} (#{get_columns}) VALUES (#{new_record_placeholders})", new_record_values
19
+ end
20
+ end
21
+
22
+ def new_record_placeholders
23
+ (["?"] * (@@mapping.size - 1)).join(",")
24
+ end
25
+
26
+ def update_record_placeholders
27
+ column = @@mapping.keys
28
+ column.delete(:id)
29
+ column.map { |col| "#{col}=?" }.join(",")
30
+ end
31
+
32
+ def get_values
33
+ attributes = @@mapping.values
34
+ attributes.delete(:id)
35
+ attributes.map { |method| self.send(method) }
36
+ end
37
+
38
+ def get_columns
39
+ column = @@mapping.keys
40
+ column.delete(:id)
41
+ column.join(",")
42
+ end
43
+
44
+ def update_record_values
45
+ get_values << self.send(:id)
46
+ end
47
+
48
+ def new_record_values
49
+ get_values
50
+ end
51
+
52
+ def method_missing(method, *args)
53
+ @model.send method
54
+ end
55
+
56
+ def self.find(id)
57
+ row = @@db.execute("SELECT #{@@mapping.keys.join(",")} FROM #{@@table_name} WHERE id=?", id).first
58
+ self.map_row_to_object(row)
59
+ end
60
+
61
+ def self.map_row_to_object(row)
62
+ model = @@model.new
63
+
64
+ @@mapping.each_value.with_index do |attribute, index|
65
+ model.send "#{attribute}=", row[index]
66
+ end
67
+ model
68
+ end
69
+
70
+ def self.find_all
71
+ data = @@db.execute "SELECT #{@@mapping.keys.join(",")} FROM #{@@table_name}"
72
+ data.map do |row|
73
+ self.map_row_to_object(row)
74
+ end
75
+ end
76
+
77
+ def delete(id)
78
+ @@db.execute "DELETE FROM #{@@table_name} WHERE id=?", id
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,62 @@
1
+ module EasyMvc
2
+ class Routes
3
+ def initialize
4
+ @routes = []
5
+ end
6
+
7
+ def match(url, *args)
8
+ target = nil
9
+ target = args.shift if args.size > 0
10
+
11
+ url_parts = url.split("/")
12
+ url_parts.select! { |part| !part.empty? }
13
+
14
+ placeholders = []
15
+ regexp_parts = url_parts.map do |part|
16
+ if part[0] == ":"
17
+ placeholders << part[1..-1]
18
+ "([A-Za-z0-9_]+)"
19
+ else
20
+ part
21
+ end
22
+ end
23
+
24
+ regexp = regexp_parts.join("/")
25
+
26
+ @routes << {
27
+ regexp: Regexp.new("^/#{regexp}$"),
28
+ target: target,
29
+ placeholders: placeholders
30
+ }
31
+ end
32
+
33
+ def check_url(url)
34
+ @routes.each do |route|
35
+ match = route[:regexp].match(url)
36
+ if match
37
+ placeholders = {}
38
+
39
+ route[:placeholders].each_with_index do |placeholder, index|
40
+ placeholders[placeholder] = match.captures[index]
41
+ end
42
+
43
+ if route[:target]
44
+ return convert_target(route[:target])
45
+ else
46
+ controller = placeholders["controller"]
47
+ action = placeholders["action"]
48
+ return convert_target("#{controller}##{action}")
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def convert_target(target)
55
+ if target =~ /^([^#]+)#([^#]+)$/
56
+ controller_name = $1.capitalize
57
+ controller = Object.const_get("#{controller_name}Controller")
58
+ controller.action($2)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,9 @@
1
+ class String
2
+ def to_snake_case
3
+ self.gsub("::", "/").
4
+ gsub(/([A-Z]+([A-Z][a-z]))/, '\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module EasyMvc
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easymvc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - afurm
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: erubis
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: EasyMvc.
84
+ email:
85
+ - furmanets.andriy@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.md
94
+ - Rakefile
95
+ - easymvc.gemspec
96
+ - example/Gemfile
97
+ - example/app/controllers/posts_controller.rb
98
+ - example/app/models/post.rb
99
+ - example/app/models/post_mapper.rb
100
+ - example/app/views/posts/create.erb
101
+ - example/app/views/posts/delete.erb
102
+ - example/app/views/posts/edit.erb
103
+ - example/app/views/posts/index.erb
104
+ - example/app/views/posts/new.erb
105
+ - example/app/views/posts/update.erb
106
+ - example/config.ru
107
+ - example/config/application.rb
108
+ - example/db/app.db
109
+ - example/db/create_post.rb
110
+ - lib/easymvc.rb
111
+ - lib/easymvc/controller.rb
112
+ - lib/easymvc/dependencies.rb
113
+ - lib/easymvc/mapper.rb
114
+ - lib/easymvc/routing.rb
115
+ - lib/easymvc/utils.rb
116
+ - lib/easymvc/version.rb
117
+ homepage: ''
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.2.1
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: EasyMvc.
141
+ test_files: []