blazer 2.4.7 → 2.6.0

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +89 -49
  4. data/app/assets/stylesheets/blazer/application.css +1 -0
  5. data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +10 -0
  6. data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +10 -0
  7. data/app/assets/stylesheets/blazer/{bootstrap.css.erb → bootstrap.css} +0 -6
  8. data/app/controllers/blazer/base_controller.rb +45 -45
  9. data/app/controllers/blazer/dashboards_controller.rb +4 -11
  10. data/app/controllers/blazer/queries_controller.rb +28 -48
  11. data/app/models/blazer/query.rb +8 -2
  12. data/app/views/blazer/_variables.html.erb +5 -4
  13. data/app/views/blazer/dashboards/_form.html.erb +1 -1
  14. data/app/views/blazer/dashboards/show.html.erb +4 -4
  15. data/app/views/blazer/queries/_caching.html.erb +1 -1
  16. data/app/views/blazer/queries/_form.html.erb +3 -3
  17. data/app/views/blazer/queries/run.html.erb +1 -1
  18. data/app/views/blazer/queries/show.html.erb +12 -7
  19. data/app/views/layouts/blazer/application.html.erb +7 -2
  20. data/lib/blazer/adapters/athena_adapter.rb +51 -15
  21. data/lib/blazer/adapters/base_adapter.rb +16 -1
  22. data/lib/blazer/adapters/bigquery_adapter.rb +13 -2
  23. data/lib/blazer/adapters/cassandra_adapter.rb +15 -4
  24. data/lib/blazer/adapters/drill_adapter.rb +10 -0
  25. data/lib/blazer/adapters/druid_adapter.rb +36 -1
  26. data/lib/blazer/adapters/elasticsearch_adapter.rb +19 -4
  27. data/lib/blazer/adapters/hive_adapter.rb +10 -0
  28. data/lib/blazer/adapters/ignite_adapter.rb +12 -2
  29. data/lib/blazer/adapters/influxdb_adapter.rb +22 -10
  30. data/lib/blazer/adapters/mongodb_adapter.rb +4 -0
  31. data/lib/blazer/adapters/neo4j_adapter.rb +17 -2
  32. data/lib/blazer/adapters/opensearch_adapter.rb +52 -0
  33. data/lib/blazer/adapters/presto_adapter.rb +9 -0
  34. data/lib/blazer/adapters/salesforce_adapter.rb +5 -0
  35. data/lib/blazer/adapters/snowflake_adapter.rb +9 -0
  36. data/lib/blazer/adapters/soda_adapter.rb +9 -0
  37. data/lib/blazer/adapters/spark_adapter.rb +5 -0
  38. data/lib/blazer/adapters/sql_adapter.rb +34 -4
  39. data/lib/blazer/data_source.rb +85 -5
  40. data/lib/blazer/engine.rb +1 -4
  41. data/lib/blazer/result.rb +4 -0
  42. data/lib/blazer/run_statement.rb +7 -3
  43. data/lib/blazer/run_statement_job.rb +4 -2
  44. data/lib/blazer/slack_notifier.rb +19 -4
  45. data/lib/blazer/statement.rb +75 -0
  46. data/lib/blazer/version.rb +1 -1
  47. data/lib/blazer.rb +27 -8
  48. data/lib/generators/blazer/templates/config.yml.tt +1 -1
  49. data/lib/tasks/blazer.rake +5 -5
  50. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 001d5a72253bcf62b525854064c1242e7569cc139b8263f54fade4536772de0a
4
- data.tar.gz: 9bf14d133dec31e413fa37390cadcd24bf9e0ae965dee208fc7fe7acca0f9111
3
+ metadata.gz: 8bdfc1e428f7e01bf9a06461a5f0143a6e940cd1e3d708ba2bd504132bbaa1db
4
+ data.tar.gz: 729e9a408e7f4fa5203ab4c133800e49087fccf634efcf7c9dd6ca80a610a861
5
5
  SHA512:
6
- metadata.gz: d0406c619b9f6ab242d7dd8d6dcca2341876ee9b5326638a57c590a5a95ecffccc9082b6323dca929487c8d55d5961b93e53788d323866c3d97d06aa846de21a
7
- data.tar.gz: 8841aaf8abbedd623b355fac0dd455a1c437abf297748ca847df15c895ba8ff59bda8c536e48da0c1e3fd882e10dbe449f6ba9c7916f0ac3caa882d822339b00
6
+ metadata.gz: e6c7a7be80246c1030170a5df95656947b2431cf908bb6d37d668cbe3f57006ef096d63186976c63c683f0e2511873cabb5d2be56e389de331487666ba297dc3
7
+ data.tar.gz: 9feb70216244f77d37357376cd68b9ec85a6d3eeb3c89f3e58196688e81618ca2ae38372e5491e0811bdd7d9e0082317a711040f5782cc54f5d9f99ec57d624a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ ## 2.6.0 (2022-04-20)
2
+
3
+ - Fixed quoting issue with variables
4
+ - Custom adapters now need to specify how to quote variables in queries
5
+ - Added experimental support for Propshaft
6
+ - Fixed error with empty results with InfluxDB
7
+
8
+ ## 2.5.0 (2022-01-04)
9
+
10
+ - Added support for Slack OAuth tokens
11
+ - Added experimental support for AnomalyDetection.rb
12
+ - Improved table preview for MySQL
13
+ - Fixed cohort analysis for MySQL
14
+
15
+ ## 2.4.8 (2021-12-07)
16
+
17
+ - Added support for OpenSearch
18
+ - Removed `elasticsearch-xpack` dependency for Elasticsearch
19
+
1
20
  ## 2.4.7 (2021-09-25)
2
21
 
3
22
  - Made Action Mailer optional
data/README.md CHANGED
@@ -10,6 +10,8 @@ Blazer is also available as a [Docker image](https://github.com/ankane/blazer-do
10
10
 
11
11
  :tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
12
12
 
13
+ [![Build Status](https://github.com/ankane/blazer/workflows/build/badge.svg?branch=master)](https://github.com/ankane/blazer/actions)
14
+
13
15
  ## Features
14
16
 
15
17
  - **Multiple data sources** - PostgreSQL, MySQL, Redshift, and [many more](#full-list)
@@ -37,7 +39,7 @@ Blazer is also available as a [Docker image](https://github.com/ankane/blazer-do
37
39
  Add this line to your application’s Gemfile:
38
40
 
39
41
  ```ruby
40
- gem 'blazer'
42
+ gem "blazer"
41
43
  ```
42
44
 
43
45
  Run:
@@ -59,7 +61,7 @@ For production, specify your database:
59
61
  ENV["BLAZER_DATABASE_URL"] = "postgres://user:password@hostname:5432/database"
60
62
  ```
61
63
 
62
- Blazer tries to protect against queries which modify data (by running each query in a transaction and rolling it back), but a safer approach is to use a read-only user. [See how to create one](#permissions).
64
+ When possible, Blazer tries to protect against queries which modify data by running each query in a transaction and rolling it back, but a safer approach is to use a read-only user. [See how to create one](#permissions).
63
65
 
64
66
  #### Checks (optional)
65
67
 
@@ -142,11 +144,9 @@ Be sure to render or redirect for unauthorized users.
142
144
 
143
145
  ## Permissions
144
146
 
145
- Blazer runs each query in a transaction and rolls it back to prevent queries from modifying data. As an additional line of defense, we recommend using a read only user.
146
-
147
147
  ### PostgreSQL
148
148
 
149
- Create a user with read only permissions:
149
+ Create a user with read-only permissions:
150
150
 
151
151
  ```sql
152
152
  BEGIN;
@@ -160,7 +160,7 @@ COMMIT;
160
160
 
161
161
  ### MySQL
162
162
 
163
- Create a user with read only permissions:
163
+ Create a user with read-only permissions:
164
164
 
165
165
  ```sql
166
166
  GRANT SELECT, SHOW VIEW ON database_name.* TO blazer@’127.0.0.1′ IDENTIFIED BY ‘secret123‘;
@@ -169,7 +169,7 @@ FLUSH PRIVILEGES;
169
169
 
170
170
  ### MongoDB
171
171
 
172
- Create a user with read only permissions:
172
+ Create a user with read-only permissions:
173
173
 
174
174
  ```
175
175
  db.createUser({user: "blazer", pwd: "password", roles: ["read"]})
@@ -412,7 +412,7 @@ SELECT users.id AS user_id, orders.created_at AS conversion_time, users.created_
412
412
  FROM users LEFT JOIN orders ON orders.user_id = users.id
413
413
  ```
414
414
 
415
- This feature requires PostgreSQL or MySQL.
415
+ This feature requires PostgreSQL or MySQL 8.
416
416
 
417
417
  ## Anomaly Detection
418
418
 
@@ -423,7 +423,7 @@ Blazer supports three different approaches to anomaly detection.
423
423
  Add [prophet-rb](https://github.com/ankane/prophet) to your Gemfile:
424
424
 
425
425
  ```ruby
426
- gem 'prophet-rb'
426
+ gem "prophet-rb"
427
427
  ```
428
428
 
429
429
  And add to `config/blazer.yml`:
@@ -439,7 +439,7 @@ anomaly_checks: prophet
439
439
  Add [trend](https://github.com/ankane/trend) to your Gemfile:
440
440
 
441
441
  ```ruby
442
- gem 'trend'
442
+ gem "trend"
443
443
  ```
444
444
 
445
445
  And add to `config/blazer.yml`:
@@ -454,46 +454,20 @@ For the [self-hosted API](https://github.com/ankane/trend-api), create an initia
454
454
  Trend.url = "http://localhost:8000"
455
455
  ```
456
456
 
457
- ### R
457
+ ### AnomalyDetection.rb (experimental)
458
458
 
459
- R uses Twitter’s [AnomalyDetection](https://github.com/twitter/AnomalyDetection) library.
459
+ Add [anomaly_detection](https://github.com/ankane/AnomalyDetection.rb) to your Gemfile:
460
460
 
461
- First, [install R](https://cloud.r-project.org/). Then, run:
462
-
463
- ```R
464
- install.packages("remotes")
465
- remotes::install_github("twitter/AnomalyDetection")
461
+ ```ruby
462
+ gem "anomaly_detection"
466
463
  ```
467
464
 
468
465
  And add to `config/blazer.yml`:
469
466
 
470
467
  ```yml
471
- anomaly_checks: r
472
- ```
473
-
474
- If upgrading from version 1.4 or below, also follow the [upgrade instructions](#15).
475
-
476
- If you’re on Heroku, follow the additional instructions below.
477
-
478
- ### R on Heroku
479
-
480
- Add the [R buildpack](https://github.com/virtualstaticvoid/heroku-buildpack-r) to your app.
481
-
482
- ```sh
483
- heroku buildpacks:add --index 1 https://github.com/virtualstaticvoid/heroku-buildpack-r.git
484
- ```
485
-
486
- And create an `init.R` with:
487
-
488
- ```r
489
- if (!"AnomalyDetection" %in% installed.packages()) {
490
- install.packages("remotes")
491
- remotes::install_github("twitter/AnomalyDetection")
492
- }
468
+ anomaly_checks: anomaly_detection
493
469
  ```
494
470
 
495
- Commit and deploy away. The first deploy may take a few minutes.
496
-
497
471
  ## Forecasting
498
472
 
499
473
  Blazer supports for two different forecasting methods. [Example](https://blazer.dokkuapp.com/queries/18-forecast?forecast=t)
@@ -502,10 +476,10 @@ A forecast link will appear for queries that return 2 columns with types timesta
502
476
 
503
477
  ### Prophet
504
478
 
505
- Add [prophet](https://github.com/ankane/prophet) to your Gemfile:
479
+ Add [prophet-rb](https://github.com/ankane/prophet) to your Gemfile:
506
480
 
507
481
  ```ruby
508
- gem 'prophet-rb', '>= 0.2.1'
482
+ gem "prophet-rb", ">= 0.2.1"
509
483
  ```
510
484
 
511
485
  And add to `config/blazer.yml`:
@@ -516,12 +490,12 @@ forecasting: prophet
516
490
 
517
491
  ### Trend
518
492
 
519
- [Trend](https://trendapi.org/) uses an external service.
493
+ [Trend](https://trendapi.org/) uses an external service by default, but you can run it on your own infrastructure as well.
520
494
 
521
495
  Add [trend](https://github.com/ankane/trend) to your Gemfile:
522
496
 
523
497
  ```ruby
524
- gem 'trend'
498
+ gem "trend"
525
499
  ```
526
500
 
527
501
  And add to `config/blazer.yml`:
@@ -530,6 +504,12 @@ And add to `config/blazer.yml`:
530
504
  forecasting: trend
531
505
  ```
532
506
 
507
+ For the [self-hosted API](https://github.com/ankane/trend-api), create an initializer with:
508
+
509
+ ```ruby
510
+ Trend.url = "http://localhost:8000"
511
+ ```
512
+
533
513
  ## Uploads
534
514
 
535
515
  Creating database tables from CSV files. [Example](https://blazer.dokkuapp.com/uploads)
@@ -592,6 +572,7 @@ data_sources:
592
572
  - [MongoDB](#mongodb-1)
593
573
  - [MySQL](#mysql-1)
594
574
  - [Neo4j](#neo4j)
575
+ - [OpenSearch](#opensearch)
595
576
  - [Oracle](#oracle)
596
577
  - [PostgreSQL](#postgresql-1)
597
578
  - [Presto](#presto)
@@ -673,6 +654,8 @@ data_sources:
673
654
  url: redshift://user:password@hostname:5439/database
674
655
  ```
675
656
 
657
+ Use a [read-only user](https://docs.aws.amazon.com/redshift/latest/dg/r_GRANT.html).
658
+
676
659
  ### Apache Drill
677
660
 
678
661
  Add [drill-sergeant](https://github.com/ankane/drill-sergeant) to your Gemfile and set:
@@ -684,6 +667,8 @@ data_sources:
684
667
  url: http://hostname:8047
685
668
  ```
686
669
 
670
+ Use a [read-only user](https://drill.apache.org/docs/roles-and-privileges/).
671
+
687
672
  ### Apache Hive
688
673
 
689
674
  Add [hexspace](https://github.com/ankane/hexspace) to your Gemfile and set:
@@ -707,6 +692,8 @@ data_sources:
707
692
  url: ignite://user:password@hostname:10800
708
693
  ```
709
694
 
695
+ Use a [read-only user](https://www.gridgain.com/docs/latest/administrators-guide/security/authorization-permissions) (requires a third-party plugin).
696
+
710
697
  ### Apache Spark
711
698
 
712
699
  Add [hexspace](https://github.com/ankane/hexspace) to your Gemfile and set:
@@ -730,6 +717,8 @@ data_sources:
730
717
  url: cassandra://user:password@hostname:9042/keyspace
731
718
  ```
732
719
 
720
+ Use a [read-only role](https://docs.datastax.com/en/cql-oss/3.3/cql/cql_using/useSecurePermission.html).
721
+
733
722
  ### Druid
734
723
 
735
724
  Enable [SQL support](http://druid.io/docs/latest/querying/sql.html#configuration) on the broker and set:
@@ -741,9 +730,11 @@ data_sources:
741
730
  url: http://hostname:8082
742
731
  ```
743
732
 
733
+ Use a [read-only role](https://druid.apache.org/docs/latest/development/extensions-core/druid-basic-security.html).
734
+
744
735
  ### Elasticsearch
745
736
 
746
- Add [elasticsearch](https://github.com/elastic/elasticsearch-ruby) and [elasticsearch-xpack](https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch-xpack) to your Gemfile and set:
737
+ Add [elasticsearch](https://github.com/elastic/elasticsearch-ruby) to your Gemfile and set:
747
738
 
748
739
  ```yml
749
740
  data_sources:
@@ -752,6 +743,8 @@ data_sources:
752
743
  url: http://user:password@hostname:9200
753
744
  ```
754
745
 
746
+ Use a [read-only role](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-privileges.html).
747
+
755
748
  ### Google BigQuery
756
749
 
757
750
  Add [google-cloud-bigquery](https://github.com/GoogleCloudPlatform/google-cloud-ruby/tree/master/google-cloud-bigquery) to your Gemfile and set:
@@ -774,6 +767,8 @@ data_sources:
774
767
  url: ibm-db://user:password@hostname:50000/database
775
768
  ```
776
769
 
770
+ Use a [read-only user](https://www.ibm.com/support/pages/creating-read-only-database-permissions-user).
771
+
777
772
  ### InfluxDB
778
773
 
779
774
  Add [influxdb](https://github.com/influxdata/influxdb-ruby) to your Gemfile and set:
@@ -785,7 +780,7 @@ data_sources:
785
780
  url: http://user:password@hostname:8086/database
786
781
  ```
787
782
 
788
- Supports [InfluxQL](https://docs.influxdata.com/influxdb/v1.8/query_language/explore-data/)
783
+ Use a [read-only user](https://docs.influxdata.com/influxdb/v1.8/administration/authentication_and_authorization/). Supports [InfluxQL](https://docs.influxdata.com/influxdb/v1.8/query_language/explore-data/).
789
784
 
790
785
  ### MongoDB
791
786
 
@@ -799,6 +794,8 @@ data_sources:
799
794
  url: mongodb://user:password@hostname:27017/database
800
795
  ```
801
796
 
797
+ Use a [read-only user](#mongodb).
798
+
802
799
  ### MySQL
803
800
 
804
801
  Add [mysql2](https://github.com/brianmario/mysql2) to your Gemfile (if it’s not there) and set:
@@ -809,6 +806,8 @@ data_sources:
809
806
  url: mysql2://user:password@hostname:3306/database
810
807
  ```
811
808
 
809
+ Use a [read-only user](#mysql).
810
+
812
811
  ### Neo4j
813
812
 
814
813
  Add [neo4j-core](https://github.com/neo4jrb/neo4j-core) to your Gemfile and set:
@@ -820,6 +819,21 @@ data_sources:
820
819
  url: http://user:password@hostname:7474
821
820
  ```
822
821
 
822
+ Use a [read-only user](https://neo4j.com/docs/cypher-manual/current/access-control/manage-privileges/).
823
+
824
+ ### OpenSearch
825
+
826
+ Add [opensearch-ruby](https://github.com/opensearch-project/opensearch-ruby) to your Gemfile and set:
827
+
828
+ ```yml
829
+ data_sources:
830
+ my_source:
831
+ adapter: opensearch
832
+ url: http://user:password@hostname:9200
833
+ ```
834
+
835
+ Use a [read-only user](https://opensearch.org/docs/latest/security-plugin/access-control/permissions/).
836
+
823
837
  ### Oracle
824
838
 
825
839
  Add [activerecord-oracle_enhanced-adapter](https://github.com/rsim/oracle-enhanced) and [ruby-oci8](https://github.com/kubo/ruby-oci8) to your Gemfile and set:
@@ -830,6 +844,8 @@ data_sources:
830
844
  url: oracle-enhanced://user:password@hostname:1521/database
831
845
  ```
832
846
 
847
+ Use a [read-only user](https://docs.oracle.com/cd/B19306_01/network.102/b14266/authoriz.htm).
848
+
833
849
  ### PostgreSQL
834
850
 
835
851
  Add [pg](https://github.com/ged/ruby-pg) to your Gemfile (if it’s not there) and set:
@@ -840,6 +856,8 @@ data_sources:
840
856
  url: postgres://user:password@hostname:5432/database
841
857
  ```
842
858
 
859
+ Use a [read-only user](#postgresql).
860
+
843
861
  ### Presto
844
862
 
845
863
  Add [presto-client](https://github.com/treasure-data/presto-client-ruby) to your Gemfile and set:
@@ -850,6 +868,8 @@ data_sources:
850
868
  url: presto://user@hostname:8080/catalog
851
869
  ```
852
870
 
871
+ Use a [read-only user](https://prestodb.io/docs/current/security/built-in-system-access-control.html).
872
+
853
873
  ### Salesforce
854
874
 
855
875
  Add [restforce](https://github.com/restforce/restforce) to your Gemfile and set:
@@ -871,7 +891,7 @@ SALESFORCE_CLIENT_SECRET="client secret"
871
891
  SALESFORCE_API_VERSION="41.0"
872
892
  ```
873
893
 
874
- Supports [SOQL](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm)
894
+ Use a read-only user. Supports [SOQL](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql.htm).
875
895
 
876
896
  ### Socrata Open Data API (SODA)
877
897
 
@@ -885,7 +905,7 @@ data_sources:
885
905
  app_token: ...
886
906
  ```
887
907
 
888
- Supports [SoQL](https://dev.socrata.com/docs/functions/)
908
+ Supports [SoQL](https://dev.socrata.com/docs/functions/).
889
909
 
890
910
  ### Snowflake
891
911
 
@@ -919,6 +939,8 @@ data_sources:
919
939
  conn_str: Driver=/path/to/libSnowflake.so;uid=user;pwd=password;server=host.snowflakecomputing.com
920
940
  ```
921
941
 
942
+ Use a [read-only role](https://docs.snowflake.com/en/user-guide/security-access-control-configure.html).
943
+
922
944
  ### SQLite
923
945
 
924
946
  Add [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) to your Gemfile and set:
@@ -939,6 +961,8 @@ data_sources:
939
961
  url: sqlserver://user:password@hostname:1433/database
940
962
  ```
941
963
 
964
+ Use a [read-only user](https://docs.microsoft.com/en-us/sql/relational-databases/security/authentication-access/getting-started-with-database-engine-permissions?view=sql-server-ver15).
965
+
942
966
  ## Creating an Adapter
943
967
 
944
968
  Create an adapter for any data store with:
@@ -1015,6 +1039,22 @@ override_csp: true
1015
1039
 
1016
1040
  ## Upgrading
1017
1041
 
1042
+ ### 2.6
1043
+
1044
+ Custom adapters now need to specify how to quote variables in queries (there is no longer a default)
1045
+
1046
+ ```ruby
1047
+ class FooAdapter < Blazer::Adapters::BaseAdapter
1048
+ def quoting
1049
+ :backslash_escape # single quote strings and convert ' to \' and \ to \\
1050
+ # or
1051
+ :single_quote_escape # single quote strings and convert ' to ''
1052
+ # or
1053
+ ->(value) { ... } # custom method
1054
+ end
1055
+ end
1056
+ ```
1057
+
1018
1058
  ### 2.3
1019
1059
 
1020
1060
  To archive queries, create a migration
@@ -1,4 +1,5 @@
1
1
  /*
2
+ *= require ./bootstrap-sprockets
2
3
  *= require ./bootstrap
3
4
  *= require ./selectize
4
5
  *= require ./github
@@ -0,0 +1,10 @@
1
+ /*!
2
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+ @font-face {
7
+ font-family: "Glyphicons Halflings";
8
+ src: url('/blazer/glyphicons-halflings-regular.eot');
9
+ src: url('/blazer/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('/blazer/glyphicons-halflings-regular.woff2') format('woff2'), url('/blazer/glyphicons-halflings-regular.woff') format('woff'), url('/blazer/glyphicons-halflings-regular.ttf') format('truetype'), url('/blazer/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
10
+ }
@@ -0,0 +1,10 @@
1
+ /*!
2
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
3
+ * Copyright 2011-2019 Twitter, Inc.
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5
+ */
6
+ @font-face {
7
+ font-family: "Glyphicons Halflings";
8
+ src: url('<%= font_path("blazer/glyphicons-halflings-regular.eot") %>');
9
+ src: url('<%= font_path("blazer/glyphicons-halflings-regular.eot?#iefix") %>') format('embedded-opentype'), url('<%= font_path("blazer/glyphicons-halflings-regular.woff2") %>') format('woff2'), url('<%= font_path("blazer/glyphicons-halflings-regular.woff") %>') format('woff'), url('<%= font_path("blazer/glyphicons-halflings-regular.ttf") %>') format('truetype'), url('<%= font_path("blazer/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") %>') format('svg');
10
+ }
@@ -263,11 +263,6 @@ th {
263
263
  border: 1px solid #ddd !important;
264
264
  }
265
265
  }
266
- @font-face {
267
- font-family: "Glyphicons Halflings";
268
- src: url('<%= font_path("blazer/glyphicons-halflings-regular.eot") %>');
269
- src: url('<%= font_path("blazer/glyphicons-halflings-regular.eot?#iefix") %>') format('embedded-opentype'), url('<%= font_path("blazer/glyphicons-halflings-regular.woff2") %>') format('woff2'), url('<%= font_path("blazer/glyphicons-halflings-regular.woff") %>') format('woff'), url('<%= font_path("blazer/glyphicons-halflings-regular.ttf") %>') format('truetype'), url('<%= font_path("blazer/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") %>') format('svg');
270
- }
271
266
  .glyphicon {
272
267
  position: relative;
273
268
  top: 1px;
@@ -6831,4 +6826,3 @@ button.close {
6831
6826
  display: none !important;
6832
6827
  }
6833
6828
  }
6834
- /*# sourceMappingURL=bootstrap.css.map */
@@ -32,45 +32,34 @@ module Blazer
32
32
 
33
33
  private
34
34
 
35
- def process_vars(statement, data_source)
36
- (@bind_vars ||= []).concat(Blazer.extract_vars(statement)).uniq!
35
+ def process_vars(statement, var_params = nil)
36
+ var_params ||= request.query_parameters
37
+ (@bind_vars ||= []).concat(statement.variables).uniq!
38
+ # update in-place so populated in view and consistent across queries on dashboard
37
39
  @bind_vars.each do |var|
38
- params[var] ||= Blazer.data_sources[data_source].variable_defaults[var]
39
- end
40
- @success = @bind_vars.all? { |v| params[v] }
41
-
42
- if @success
43
- @bind_vars.each do |var|
44
- value = params[var].presence
45
- if value
46
- if ["start_time", "end_time"].include?(var)
47
- value = value.to_s.gsub(" ", "+") # fix for Quip bug
48
- end
49
-
50
- if var.end_with?("_at")
51
- begin
52
- value = Blazer.time_zone.parse(value)
53
- rescue
54
- # do nothing
55
- end
56
- end
57
-
58
- if value =~ /\A\d+\z/
59
- value = value.to_i
60
- elsif value =~ /\A\d+\.\d+\z/
61
- value = value.to_f
62
- end
63
- end
64
- value = Blazer.transform_variable.call(var, value) if Blazer.transform_variable
65
- statement.gsub!("{#{var}}", ActiveRecord::Base.connection.quote(value))
40
+ if !var_params[var]
41
+ default = statement.data_source.variable_defaults[var]
42
+ # only add if default exists
43
+ var_params[var] = default if default
66
44
  end
67
45
  end
46
+ runnable = @bind_vars.all? { |v| var_params[v] }
47
+ statement.add_values(var_params) if runnable
48
+ runnable
49
+ end
50
+
51
+ def refresh_query(query)
52
+ statement = query.statement_object
53
+ runnable = process_vars(statement)
54
+ cohort_analysis_statement(statement) if statement.cohort_analysis?
55
+ statement.clear_cache if runnable
68
56
  end
69
57
 
70
58
  def add_cohort_analysis_vars
71
59
  @bind_vars << "cohort_period" unless @bind_vars.include?("cohort_period")
72
- @smart_vars["cohort_period"] = ["day", "week", "month"]
73
- params[:cohort_period] ||= "week"
60
+ @smart_vars["cohort_period"] = ["day", "week", "month"] if @smart_vars
61
+ # TODO create var_params method
62
+ request.query_parameters["cohort_period"] ||= "week"
74
63
  end
75
64
 
76
65
  def parse_smart_variables(var, data_source)
@@ -94,22 +83,33 @@ module Blazer
94
83
  [smart_var, error]
95
84
  end
96
85
 
97
- # don't pass to url helpers
98
- #
99
- # some are dangerous when passed as symbols
100
- # root_url({host: "evilsite.com"})
101
- #
102
- # certain ones (like host) only affect *_url and not *_path
103
- #
104
- # when permitted parameters are passed in Rails 6,
105
- # they appear to be added as GET parameters
106
- # root_url(params.permit(:host))
86
+ def cohort_analysis_statement(statement)
87
+ @cohort_period = params["cohort_period"] || "week"
88
+ @cohort_period = "week" unless ["day", "week", "month"].include?(@cohort_period)
89
+
90
+ # for now
91
+ @conversion_period = @cohort_period
92
+ @cohort_days =
93
+ case @cohort_period
94
+ when "day"
95
+ 1
96
+ when "week"
97
+ 7
98
+ when "month"
99
+ 30
100
+ end
101
+
102
+ statement.apply_cohort_analysis(period: @cohort_period, days: @cohort_days)
103
+ end
104
+
105
+ # TODO allow all keys
106
+ # or show error message for disallowed keys
107
107
  UNPERMITTED_KEYS = [:controller, :action, :id, :host, :query, :dashboard, :query_id, :query_ids, :table_names, :authenticity_token, :utf8, :_method, :commit, :statement, :data_source, :name, :fork_query_id, :blazer, :run_id, :script_name, :original_script_name]
108
108
 
109
- # remove unpermitted keys from both params and permitted keys for better sleep
110
- def variable_params(resource)
109
+ def variable_params(resource, var_params = nil)
111
110
  permitted_keys = resource.variables - UNPERMITTED_KEYS.map(&:to_s)
112
- params.except(*UNPERMITTED_KEYS).slice(*permitted_keys).permit!
111
+ var_params ||= request.query_parameters
112
+ var_params.slice(*permitted_keys)
113
113
  end
114
114
  helper_method :variable_params
115
115
 
@@ -21,11 +21,8 @@ module Blazer
21
21
 
22
22
  def show
23
23
  @queries = @dashboard.dashboard_queries.order(:position).preload(:query).map(&:query)
24
- @statements = []
25
24
  @queries.each do |query|
26
- statement = query.statement.dup
27
- process_vars(statement, query.data_source)
28
- @statements << statement
25
+ @success = process_vars(query.statement_object)
29
26
  end
30
27
  @bind_vars ||= []
31
28
 
@@ -48,7 +45,7 @@ module Blazer
48
45
 
49
46
  def update
50
47
  if update_dashboard(@dashboard)
51
- redirect_to dashboard_path(@dashboard, variable_params(@dashboard))
48
+ redirect_to dashboard_path(@dashboard, params: variable_params(@dashboard))
52
49
  else
53
50
  render_errors @dashboard
54
51
  end
@@ -61,13 +58,9 @@ module Blazer
61
58
 
62
59
  def refresh
63
60
  @dashboard.queries.each do |query|
64
- data_source = Blazer.data_sources[query.data_source]
65
- statement = query.statement.dup
66
- process_vars(statement, query.data_source)
67
- Blazer.transform_statement.call(data_source, statement) if Blazer.transform_statement
68
- data_source.clear_cache(statement)
61
+ refresh_query(query)
69
62
  end
70
- redirect_to dashboard_path(@dashboard, variable_params(@dashboard))
63
+ redirect_to dashboard_path(@dashboard, params: variable_params(@dashboard))
71
64
  end
72
65
 
73
66
  private