dossier 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +1 -1
- data/README.markdown +43 -26
- data/app/controllers/dossier/reports_controller.rb +1 -1
- data/lib/dossier/version.rb +1 -1
- data/spec/dossier_spec.rb +3 -3
- data/spec/dummy/app/views/dossier/reports/{suspended_employee.html.haml → employee_with_custom_view.html.haml} +0 -0
- data/spec/dummy/config/database.yml +13 -0
- data/spec/dummy/config/environment.rb +0 -4
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +33 -0
- data/spec/dummy/log/test.log +24248 -0
- data/spec/fixtures/db/mysql2.yml +5 -0
- data/spec/fixtures/db/mysql2.yml.example +1 -0
- data/spec/fixtures/db/sqlite3.yml +2 -0
- data/spec/fixtures/{employee_report.csv → reports/employee.csv} +0 -0
- data/spec/fixtures/{employee_report.html → reports/employee.html} +0 -0
- data/spec/fixtures/{employee_with_custom_client.html → reports/employee_with_custom_client.html} +0 -0
- data/spec/fixtures/reports/employee_with_custom_view.html +15 -0
- data/spec/fixtures/{employee_report_with_footer.html → reports/employee_with_footer.html} +0 -0
- data/spec/fixtures/{customized_employee_report.html → reports/employee_with_parameters.html} +0 -0
- data/spec/requests/{employee_report_spec.rb → employee_spec.rb} +6 -6
- data/spec/requests/employee_with_custom_client_spec.rb +2 -2
- data/spec/support/reports/{employee_report.rb → employee.rb} +0 -0
- data/spec/support/reports/employee_with_custom_view.rb +8 -0
- data/spec/support/reports/{test_report.rb → test.rb} +0 -2
- metadata +38 -30
- data/spec/dummy/app/views/dossier/reports/total.html.haml +0 -11
- data/spec/support/reports/sqlite_employee_report.rb +0 -15
- data/spec/support/reports/supended_employee_report.rb +0 -7
- data/spec/support/reports/total_report.rb +0 -35
data/MIT-LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# Dossier
|
2
2
|
|
3
|
-
Dossier is a Rails engine that turns SQL into reports. Reports can be easily rendered in various formats, like HTML, CSV, and JSON.
|
3
|
+
Dossier is a Rails engine that turns SQL into reports. Reports can be easily rendered in various formats, like HTML, CSV, and JSON.
|
4
|
+
|
5
|
+
- If you **hate** SQL, you can use whatever tool you like to generate it; for example, ActiveRecord's `to_sql`.
|
6
|
+
- If you **love** SQL, you can use every feature feature your database supports.
|
7
|
+
|
8
|
+
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/adamhunter/dossier)
|
4
9
|
|
5
10
|
## Setup
|
6
11
|
|
@@ -19,29 +24,34 @@ For example:
|
|
19
24
|
```ruby
|
20
25
|
# app/reports/fancy_ketchup_report.rb
|
21
26
|
class FancyKetchupReport < Dossier::Report
|
22
|
-
def sql
|
27
|
+
def sql
|
23
28
|
'SELECT * FROM ketchups WHERE fancy = true'
|
24
29
|
end
|
25
30
|
|
26
31
|
# Or, if you're using ActiveRecord and hate writing SQL:
|
27
|
-
def sql
|
32
|
+
def sql
|
28
33
|
Ketchup.where(fancy: true).to_sql
|
29
34
|
end
|
30
35
|
|
31
36
|
end
|
32
37
|
```
|
33
38
|
|
34
|
-
If you need dynamic values that may be influenced by the user, [do not interpolate them directly](http://xkcd.com/327/)
|
35
|
-
|
39
|
+
If you need dynamic values that may be influenced by the user, **[do not interpolate them directly](http://xkcd.com/327/)**. Dossier provides a safer way to add them: any symbols in the query will be replaced by calling methods of the same name in the report. Return values will be **escaped by the database connection**. Arrays will have all of their contents escaped, joined with a "," and wrapped in parentheses.
|
40
|
+
|
36
41
|
```ruby
|
37
42
|
# app/reports/fancy_ketchup_report.rb
|
38
43
|
class FancyKetchupReport < Dossier::Report
|
39
44
|
def sql
|
40
|
-
|
45
|
+
"SELECT * FROM ketchups WHERE price <= :max_price and brand IN :brands"
|
46
|
+
# => "SELECT * FROM ketchups WHERE price <= 7 and brand IN ('Acme', 'Generic', 'SoylentRed')"
|
47
|
+
end
|
48
|
+
|
49
|
+
def max_price
|
50
|
+
7
|
41
51
|
end
|
42
52
|
|
43
|
-
def
|
44
|
-
|
53
|
+
def brands
|
54
|
+
%w[Acme Generic SoylentRed]
|
45
55
|
end
|
46
56
|
end
|
47
57
|
```
|
@@ -65,7 +75,7 @@ Dossier also provides a `formatter` with access to all the standard Rails format
|
|
65
75
|
class MoneyLaunderingReport < Dossier::Report
|
66
76
|
#...
|
67
77
|
def format_payment(value)
|
68
|
-
formatter.number_to_currency
|
78
|
+
formatter.number_to_currency(value)
|
69
79
|
end
|
70
80
|
end
|
71
81
|
```
|
@@ -73,14 +83,19 @@ end
|
|
73
83
|
In addition, the formatter provides Rails' URL helpers for use in your reports. For example, in a report of your least profitable accounts, you might want to add a link to change the salesperson assigned to that account.
|
74
84
|
|
75
85
|
```ruby
|
76
|
-
|
86
|
+
class LeastProfitableAccountsReport < Dossier::Report
|
87
|
+
#...
|
88
|
+
def format_account_id(value)
|
89
|
+
formatter.link_to value, formatter.url_helpers.edit_accounts_path(value)
|
90
|
+
end
|
91
|
+
end
|
77
92
|
```
|
78
93
|
|
79
94
|
The built-in `ReportsController` uses this formatting when rendering the HTML and JSON representations, but not when rendering the CSV.
|
80
95
|
|
81
96
|
## Report Options and Footers
|
82
97
|
|
83
|
-
You may want to specify parameters for a report: which columns to show, a range of dates, etc. Dossier supports this via URL parameters,
|
98
|
+
You may want to specify parameters for a report: which columns to show, a range of dates, etc. Dossier supports this via URL parameters, anything in `params[:options]` will be passed into your report's `initialize` method and made available via the `options` reader.
|
84
99
|
|
85
100
|
You can pass these options by hardcoding them into a link, or you can allow users to customize a report with a form. For example:
|
86
101
|
|
@@ -88,7 +103,6 @@ You can pass these options by hardcoding them into a link, or you can allow user
|
|
88
103
|
# app/views/dossier/reports/employee.html.haml
|
89
104
|
|
90
105
|
= form_for report, as: :options, url: url_for, html: {method: :get} do |f|
|
91
|
-
|
92
106
|
= f.label "Salary greater than:"
|
93
107
|
= f.text_field :salary_greater_than
|
94
108
|
= f.label "In Division:"
|
@@ -98,7 +112,7 @@ You can pass these options by hardcoding them into a link, or you can allow user
|
|
98
112
|
= render template: 'dossier/dossier/reports/show', locals: {report: report}
|
99
113
|
```
|
100
114
|
|
101
|
-
It's up to you to use these options in generating your SQL query.
|
115
|
+
It's up to you to use these options in generating your SQL query.
|
102
116
|
|
103
117
|
However, Dossier does support one URL parameter natively: if you supply a `footer` parameter with an integer value, the last N rows will be accesible via `report.results.footers` instead of `report.results.body`. The built-in `show` view renders those rows inside an HTML footer. This is an easy way to display a totals row or something similar.
|
104
118
|
|
@@ -154,7 +168,11 @@ end
|
|
154
168
|
|
155
169
|
## Advanced Usage
|
156
170
|
|
157
|
-
To see a report with all the bells and whistles, check out `spec/support/reports/employee_report.rb`.
|
171
|
+
To see a report with all the bells and whistles, check out `spec/support/reports/employee_report.rb` or other reports in `spec/support/reports`.
|
172
|
+
|
173
|
+
## Compatibility
|
174
|
+
|
175
|
+
Dossier currently supports all databases supported by ActiveRecord; it comes with `Dossier::Adapter::ActiveRecord`, which uses ActiveRecord connections for escaping and executing queries. However, as the `Dossier::Adapter` namespace implies, it was written to allow for other connection adapters. See `CONTRIBUTING.md` if you'd like to add one.
|
158
176
|
|
159
177
|
## Running the Tests
|
160
178
|
|
@@ -162,20 +180,19 @@ Note: when you run the tests, Dossier will **make and/or truncate** some tables
|
|
162
180
|
|
163
181
|
- Run `bundle`
|
164
182
|
- `cp spec/dummy/config/database.yml{.example,}` and edit it so that it can connect to the test database.
|
183
|
+
- `cp spec/fixtures/db/mysql2.yml{.example,}`
|
184
|
+
- `cp spec/fixtures/db/sqlite3.yml{.example,}`
|
165
185
|
- `rspec spec`
|
166
186
|
|
167
|
-
##
|
168
|
-
|
169
|
-
### Features
|
170
|
-
|
171
|
-
- Support more databases
|
172
|
-
|
173
|
-
### Moar Dokumentationz pleaze
|
187
|
+
## Moar Dokumentationz pleaze
|
174
188
|
|
189
|
+
- How Dossier uses ORM adapters to connect to databases, currently only AR's are used.
|
190
|
+
- Examples of connecting to different databases, of the same type or a different one
|
175
191
|
- Document using hooks and what methods are available in them
|
176
|
-
-
|
177
|
-
-
|
178
|
-
-
|
179
|
-
-
|
180
|
-
-
|
192
|
+
- Callbacks, eg:
|
193
|
+
- Stored procedures
|
194
|
+
- Reformat results
|
195
|
+
- Linking
|
196
|
+
- To other reports
|
197
|
+
- To other formats
|
181
198
|
- Extending the formatter
|
data/lib/dossier/version.rb
CHANGED
data/spec/dossier_spec.rb
CHANGED
@@ -16,11 +16,11 @@ describe Dossier do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "allows configuration via a block" do
|
19
|
-
|
19
|
+
some_client = Object.new
|
20
20
|
Dossier.configure do |config|
|
21
|
-
config.client =
|
21
|
+
config.client = some_client
|
22
22
|
end
|
23
|
-
Dossier.configuration.client.should eq(
|
23
|
+
Dossier.configuration.client.should eq(some_client)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "exposes the configurations client via Dossier.client" do
|
File without changes
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Connecting to database specified by database.yml
|
2
|
+
[1m[36m (45.0ms)[0m [1mCREATE TABLE `employees` (`id` int(11) DEFAULT NULL auto_increment PRIMARY KEY, `name` varchar(255), `hired_on` date, `suspended` tinyint(1)) ENGINE=InnoDB[0m
|
3
|
+
[1m[35m (217.3ms)[0m CREATE TABLE `schema_migrations` (`version` varchar(255) NOT NULL) ENGINE=InnoDB
|
4
|
+
[1m[36m (141.9ms)[0m [1mCREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)[0m
|
5
|
+
[1m[35m (0.2ms)[0m SELECT version FROM `schema_migrations`
|
6
|
+
[1m[36m (0.3ms)[0m [1mINSERT INTO `schema_migrations` (version) VALUES ('20130110141950')[0m
|
7
|
+
Connecting to database specified by database.yml
|
8
|
+
Connecting to database specified by database.yml
|
9
|
+
Connecting to database specified by database.yml
|
10
|
+
[1m[36m (1.5ms)[0m [1mSELECT `schema_migrations`.`version` FROM `schema_migrations` [0m
|
11
|
+
Migrating to CreateEmployees (20130110141950)
|
12
|
+
Migrating to AddDivisionToEmployees (20130110221932)
|
13
|
+
[1m[35m (109.6ms)[0m ALTER TABLE `employees` ADD `division` varchar(255)
|
14
|
+
[1m[36m (0.5ms)[0m [1mINSERT INTO `schema_migrations` (`version`) VALUES ('20130110221932')[0m
|
15
|
+
[1m[35m (0.2ms)[0m SELECT `schema_migrations`.`version` FROM `schema_migrations`
|
16
|
+
Connecting to database specified by database.yml
|
17
|
+
[1m[36m (1.7ms)[0m [1mSELECT `schema_migrations`.`version` FROM `schema_migrations` [0m
|
18
|
+
[1m[35m (0.3ms)[0m SELECT `schema_migrations`.`version` FROM `schema_migrations`
|
19
|
+
Migrating to AddDivisionToEmployees (20130110221932)
|
20
|
+
[1m[36m (85.8ms)[0m [1mALTER TABLE `employees` DROP `division`[0m
|
21
|
+
[1m[35m (0.6ms)[0m DELETE FROM `schema_migrations` WHERE `schema_migrations`.`version` = '20130110221932'
|
22
|
+
[1m[36m (0.1ms)[0m [1mSELECT `schema_migrations`.`version` FROM `schema_migrations` [0m
|
23
|
+
Connecting to database specified by database.yml
|
24
|
+
[1m[36m (1.6ms)[0m [1mSELECT `schema_migrations`.`version` FROM `schema_migrations` [0m
|
25
|
+
Migrating to CreateEmployees (20130110141950)
|
26
|
+
Migrating to AddDivisionToEmployees (20130110221932)
|
27
|
+
[1m[35m (50.1ms)[0m ALTER TABLE `employees` ADD `division` varchar(255)
|
28
|
+
[1m[36m (238.4ms)[0m [1mALTER TABLE `employees` ADD `salary` int(11)[0m
|
29
|
+
[1m[35m (0.4ms)[0m INSERT INTO `schema_migrations` (`version`) VALUES ('20130110221932')
|
30
|
+
[1m[36m (0.3ms)[0m [1mSELECT `schema_migrations`.`version` FROM `schema_migrations` [0m
|
31
|
+
Connecting to database specified by database.yml
|
32
|
+
Connecting to database specified by database.yml
|
33
|
+
Connecting to database specified by database.yml
|