railz_lite 0.2.7 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +104 -3
- data/lib/railz_lite/models/db_connection.rb +24 -13
- data/lib/railz_lite/models/sql_object.rb +2 -2
- data/lib/railz_lite/models/wrappers/pg_wrapper.rb +46 -0
- data/lib/railz_lite/models/wrappers/sqlite3_wrapper.rb +30 -0
- data/lib/railz_lite/version.rb +1 -1
- data/railz_lite.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aff7d4d6f62b5eee1669eef62895d5170f55a5d3241db179191a690bb9dc26f1
|
4
|
+
data.tar.gz: 2ab955ed52a300dcf3c614e1a0c4bcbf9f0e8ef81613e2bae9aa7324f08980db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b6b915059bf4ed2ce158b1b6eef235fb742cac8fa3a416bdd88df3d4183510c632021181cec277551e86b3142253bf09732d6aed1954cf1c92b08c820c02b2b
|
7
|
+
data.tar.gz: 7118f1462ba3e8d772d4e64bfea0304f8cae53cebd073d9b38c97e318a3129f42bf5560369c96f7edc7b916b9a1e77e22d7d713c18ed31526a189f080f00c25b
|
data/README.md
CHANGED
@@ -1,8 +1,30 @@
|
|
1
1
|
# RailzLite
|
2
2
|
|
3
|
-
|
3
|
+
A lite-weight Ruby gem inspired by Ruby on Rails.
|
4
4
|
|
5
|
-
|
5
|
+
To get started with a new project, execute the command
|
6
|
+
|
7
|
+
```
|
8
|
+
$ railz_lite new MyWebApp
|
9
|
+
```
|
10
|
+
|
11
|
+
This will generate controllers/, views/, models/, and other necessary directories.
|
12
|
+
|
13
|
+
After changing into the root project directory, run the server command to get the Rack server running
|
14
|
+
|
15
|
+
```
|
16
|
+
$ cd MyWebApp && railz_lite server
|
17
|
+
```
|
18
|
+
|
19
|
+
To create a new sqlite3 database file, write your desired SQL code in app.sql then execute
|
20
|
+
|
21
|
+
```
|
22
|
+
$ railz_lite reset_db
|
23
|
+
```
|
24
|
+
|
25
|
+
An example web app can be found at the following repo:
|
26
|
+
|
27
|
+
https://github.com/bryanqb07/trash_films
|
6
28
|
|
7
29
|
## Installation
|
8
30
|
|
@@ -22,7 +44,86 @@ Or install it yourself as:
|
|
22
44
|
|
23
45
|
## Usage
|
24
46
|
|
25
|
-
|
47
|
+
### Controllers
|
48
|
+
|
49
|
+
All controllers should inherit from the RailzLite::ControllerBase class. An example is as follows:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
class FilmsController < RailzLite::ControllerBase
|
53
|
+
def index
|
54
|
+
@films = Film.all
|
55
|
+
end
|
56
|
+
|
57
|
+
def show
|
58
|
+
@film = Film.find(params['id'])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
### Models
|
64
|
+
|
65
|
+
Models inherit from RailzLite::SQLObject. Please note that any class declaration must be ended with a finalize! statement
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class Film < RailzLite::SQLObject
|
69
|
+
has_many :reviews, foreign_key: :film_id
|
70
|
+
def average_rating
|
71
|
+
ratings = reviews.map(&:rating)
|
72
|
+
return 0 if ratings.empty?
|
73
|
+
|
74
|
+
ratings.reduce(:+) / reviews.length
|
75
|
+
end
|
76
|
+
finalize!
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
### Views
|
81
|
+
|
82
|
+
Views use the rails convention for path-resolution. Also, they are required to end in a .erb extension, even if no embedded ruby is used.
|
83
|
+
|
84
|
+
ex. FilmsController#index corresponds to /views/films/index.html.erb
|
85
|
+
|
86
|
+
### Server + Routes
|
87
|
+
|
88
|
+
The server file can be found in config/server.
|
89
|
+
|
90
|
+
Routes are configured in the following structure
|
91
|
+
|
92
|
+
```
|
93
|
+
http_method, regex to match route, controller, action
|
94
|
+
```
|
95
|
+
|
96
|
+
Below is an example route config:
|
97
|
+
```ruby
|
98
|
+
router.draw do
|
99
|
+
# add routes here
|
100
|
+
get Regexp.new('^/films$'), FilmsController, :index
|
101
|
+
get Regexp.new("^/films/(?<id>\\d+)$"), FilmsController, :show
|
102
|
+
|
103
|
+
get Regexp.new("^/films/(?<film_id>\\d+)/reviews/new$"), ReviewsController, :new
|
104
|
+
post Regexp.new("^/films/(?<film_id>\\d+)/reviews$"), ReviewsController, :create
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
### Assets
|
109
|
+
|
110
|
+
Assets are served via the static middleware included within the framework. The default load paths for assets are "/public" and "/assets".
|
111
|
+
Any file within these two folders can be accessed in the app by specifying the root folder + the file name.
|
112
|
+
|
113
|
+
ex.) MyProject/public/balloons.jpg
|
114
|
+
|
115
|
+
```html
|
116
|
+
<h1>Congratulations!!! <img src="public/balloons.jpg" /></h1>
|
117
|
+
```
|
118
|
+
|
119
|
+
ex.) MyProject/assets/home.css
|
120
|
+
|
121
|
+
```html
|
122
|
+
<head>
|
123
|
+
<title>My Project</title>
|
124
|
+
<link rel="stylesheet" href="assets/application.css">
|
125
|
+
</head>
|
126
|
+
```
|
26
127
|
|
27
128
|
## Development
|
28
129
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
require_relative 'wrappers/pg_wrapper'
|
2
|
+
require_relative 'wrappers/sqlite3_wrapper'
|
2
3
|
|
3
4
|
class DBConnection
|
4
5
|
PRINT_QUERIES = ENV['PRINT_QUERIES'] == 'true'
|
@@ -10,22 +11,27 @@ class DBConnection
|
|
10
11
|
DBConnection.open(DB_FILE)
|
11
12
|
end
|
12
13
|
|
13
|
-
def self.open(
|
14
|
-
|
15
|
-
|
16
|
-
@db
|
14
|
+
def self.open(db_name) # for sqlite3 we need file.db, for postgresql we need database name
|
15
|
+
db_uri = ENV['DATABASE_URL']
|
16
|
+
|
17
|
+
@db = db_uri.nil? ? SQLite3Wrapper.new(db_name) : PGWrapper.new(db_uri)
|
17
18
|
|
18
19
|
@db
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.reset
|
22
|
-
|
23
|
-
"rm '#{DB_FILE}'",
|
24
|
-
"cat '#{SQL_FILE}' | sqlite3 '#{DB_FILE}'"
|
25
|
-
]
|
23
|
+
db_uri = ENV['DATABASE_URL']
|
26
24
|
|
27
|
-
|
28
|
-
|
25
|
+
if db_uri.nil? # sqlite
|
26
|
+
commands = ["rm '#{DB_FILE}'", "cat '#{SQL_FILE}' | sqlite3 '#{DB_FILE}'"]
|
27
|
+
|
28
|
+
commands.each { |command| `#{command}` }
|
29
|
+
DBConnection.open(DB_FILE)
|
30
|
+
else # postgres
|
31
|
+
DBConnection.open(db_uri)
|
32
|
+
sql = File.read(SQL_FILE)
|
33
|
+
instance.execute(sql)
|
34
|
+
end
|
29
35
|
end
|
30
36
|
|
31
37
|
def self.instance
|
@@ -34,20 +40,25 @@ class DBConnection
|
|
34
40
|
@db
|
35
41
|
end
|
36
42
|
|
43
|
+
# results hash of results [{id: 1, name: 'Bob'}...]
|
37
44
|
def self.execute(*args)
|
38
45
|
print_query(*args)
|
39
46
|
instance.execute(*args)
|
40
47
|
end
|
41
48
|
|
49
|
+
# returns result with header fields [['id', 'name'...], { id: 1, name: 'Bob' ... }
|
42
50
|
def self.execute2(*args)
|
43
51
|
print_query(*args)
|
44
52
|
instance.execute2(*args)
|
45
53
|
end
|
46
54
|
|
47
|
-
|
48
|
-
|
55
|
+
# used to insert data into tables
|
56
|
+
def self.insert(*args)
|
57
|
+
print_query(*args)
|
58
|
+
instance.insert(*args)
|
49
59
|
end
|
50
60
|
|
61
|
+
|
51
62
|
private
|
52
63
|
|
53
64
|
def self.print_query(query, *interpolation_args)
|
@@ -82,13 +82,13 @@ module RailzLite
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def insert
|
85
|
-
DBConnection.
|
85
|
+
last_row_id = DBConnection.insert(<<-SQL, *attribute_values)
|
86
86
|
INSERT INTO
|
87
87
|
#{self.class.table_name}(#{self.class.columns.join(',')})
|
88
88
|
VALUES
|
89
89
|
(#{(["?"] * attribute_values.length).join(',')})
|
90
90
|
SQL
|
91
|
-
self.id =
|
91
|
+
self.id = last_row_id
|
92
92
|
end
|
93
93
|
|
94
94
|
def update
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'pg'
|
2
|
+
|
3
|
+
class PGWrapper
|
4
|
+
def initialize(db_uri)
|
5
|
+
@db = PG::Connection.new(db_uri)
|
6
|
+
@db.type_map_for_results = PG::BasicTypeMapForResults.new(@db) # converts pgsql strings to ruby type
|
7
|
+
@db
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute(sql, *args)
|
11
|
+
converted_sql = convert_escaped_question_marks(sql)
|
12
|
+
@db.exec_params(converted_sql, args).to_a
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute2(sql, *args)
|
16
|
+
converted_sql = convert_escaped_question_marks(sql)
|
17
|
+
result = @db.exec_params(converted_sql, args)
|
18
|
+
[result.fields, result.to_a]
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert(sql, *args)
|
22
|
+
sql.insert(sql.index(';'), ' RETURNING ID')
|
23
|
+
converted_sql = convert_escaped_question_marks(sql)
|
24
|
+
result = @db.exec_params(converted_sql, *args)
|
25
|
+
result.to_a.first['id']
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# for pgsql, SELECT * FROM films WHERE x = ?; must be converted to SELECT * FROM films WHERE x = $1;
|
32
|
+
def convert_escaped_question_marks(sql)
|
33
|
+
converted_sql = ""
|
34
|
+
index = 1
|
35
|
+
sql.each_char do |char|
|
36
|
+
if char == '?'
|
37
|
+
converted_sql += "$#{index}"
|
38
|
+
index += 1
|
39
|
+
else
|
40
|
+
converted_sql += char
|
41
|
+
end
|
42
|
+
end
|
43
|
+
converted_sql
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
|
3
|
+
class SQLite3Wrapper
|
4
|
+
def initialize(db_file_name)
|
5
|
+
@db = SQLite3::Database.new(db_file_name)
|
6
|
+
@db.results_as_hash = true
|
7
|
+
@db.type_translation = true
|
8
|
+
|
9
|
+
@db
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(*args)
|
13
|
+
@db.execute(*args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute2(*args)
|
17
|
+
@db.execute2(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def insert(*args)
|
21
|
+
execute(*args)
|
22
|
+
last_insert_row_id
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def self.last_insert_row_id
|
28
|
+
@db.last_insert_row_id
|
29
|
+
end
|
30
|
+
end
|
data/lib/railz_lite/version.rb
CHANGED
data/railz_lite.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_dependency "activesupport", '~> 6.1.4'
|
34
34
|
spec.add_dependency "puma", '~> 5.3.2'
|
35
35
|
spec.add_dependency "sqlite3", '~> 1.4.2'
|
36
|
+
spec.add_dependency "pg", '~> 1.2.3'
|
36
37
|
spec.add_dependency "thor", '~> 1.1.0'
|
37
38
|
spec.add_dependency "loofah", '~> 2.10.0'
|
38
39
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: railz_lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bryan lynch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.4.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pg
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.2.3
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.2.3
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: thor
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +206,8 @@ files:
|
|
192
206
|
- lib/railz_lite/models/searchable.rb
|
193
207
|
- lib/railz_lite/models/sql_object.rb
|
194
208
|
- lib/railz_lite/models/validatable.rb
|
209
|
+
- lib/railz_lite/models/wrappers/pg_wrapper.rb
|
210
|
+
- lib/railz_lite/models/wrappers/sqlite3_wrapper.rb
|
195
211
|
- lib/railz_lite/version.rb
|
196
212
|
- railz_lite.gemspec
|
197
213
|
homepage: https://github.com/bryanqb07/my_rails
|