railz_lite 0.2.7 → 0.2.8

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: e77147f68729fb2f1b68f730aa31e1e50ca822df8990e6fb35ba9eb2e02cbf5d
4
- data.tar.gz: e96ec7817513298e3899cde8d3e9d3f43cbc97589302443db38c4ec8a993258b
3
+ metadata.gz: aff7d4d6f62b5eee1669eef62895d5170f55a5d3241db179191a690bb9dc26f1
4
+ data.tar.gz: 2ab955ed52a300dcf3c614e1a0c4bcbf9f0e8ef81613e2bae9aa7324f08980db
5
5
  SHA512:
6
- metadata.gz: 5968f44535f416c2524445365be98cacfe92894e1ed1079268cb8261ea0c44bd8101ad9f7fb62d84677fb0f2e5f57937f955144046bb1c399659b61c0065acb2
7
- data.tar.gz: 958a09155c32bd8707908f4a820a2cc5e8f4116e0d90fa91c44ca24855827df3e4819ab31a410beffeb866615013418012890bab1237d105e0e9111bba4664ac
6
+ metadata.gz: 0b6b915059bf4ed2ce158b1b6eef235fb742cac8fa3a416bdd88df3d4183510c632021181cec277551e86b3142253bf09732d6aed1954cf1c92b08c820c02b2b
7
+ data.tar.gz: 7118f1462ba3e8d772d4e64bfea0304f8cae53cebd073d9b38c97e318a3129f42bf5560369c96f7edc7b916b9a1e77e22d7d713c18ed31526a189f080f00c25b
data/README.md CHANGED
@@ -1,8 +1,30 @@
1
1
  # RailzLite
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/railz_lite`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ A lite-weight Ruby gem inspired by Ruby on Rails.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
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
- TODO: Write usage instructions here
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
- require 'sqlite3'
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(db_file_name)
14
- @db = SQLite3::Database.new(db_file_name)
15
- @db.results_as_hash = true
16
- @db.type_translation = true
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
- commands = [
23
- "rm '#{DB_FILE}'",
24
- "cat '#{SQL_FILE}' | sqlite3 '#{DB_FILE}'"
25
- ]
23
+ db_uri = ENV['DATABASE_URL']
26
24
 
27
- commands.each { |command| `#{command}` }
28
- DBConnection.open(DB_FILE)
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
- def self.last_insert_row_id
48
- instance.last_insert_row_id
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.execute(<<-SQL, *attribute_values)
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 = DBConnection.last_insert_row_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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailzLite
4
- VERSION = "0.2.7"
4
+ VERSION = "0.2.8"
5
5
  end
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.7
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-03 00:00:00.000000000 Z
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