blazer 2.4.7 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
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