Code Monkey home page Code Monkey logo

blazer's Introduction

Blazer

Explore your data with SQL. Easily create charts and dashboards, and share them with your team.

Try it out

Screenshot

Blazer is also available as a Docker image.

🍊 Battle-tested at Instacart

Build Status

Features

  • Multiple data sources - PostgreSQL, MySQL, Redshift, and many more
  • Variables - run the same queries with different values
  • Checks & alerts - get emailed when bad data appears
  • Audits - all queries are tracked
  • Security - works with your authentication system

Docs

Installation

Add this line to your application’s Gemfile:

gem "blazer"

Run:

rails generate blazer:install
rails db:migrate

And mount the dashboard in your config/routes.rb:

mount Blazer::Engine, at: "blazer"

For production, specify your database:

ENV["BLAZER_DATABASE_URL"] = "postgres://user:password@hostname:5432/database"

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.

Checks (optional)

Be sure to set a host in config/environments/production.rb for emails to work.

config.action_mailer.default_url_options = {host: "blazer.dokkuapp.com"}

Schedule checks to run (with cron, Heroku Scheduler, etc). The default options are every 5 minutes, 1 hour, or 1 day, which you can customize. For each of these options, set up a task to run.

rake blazer:run_checks SCHEDULE="5 minutes"
rake blazer:run_checks SCHEDULE="1 hour"
rake blazer:run_checks SCHEDULE="1 day"

You can also set up failing checks to be sent once a day (or whatever you prefer).

rake blazer:send_failing_checks

Here’s what it looks like with cron.

*/5 * * * * rake blazer:run_checks SCHEDULE="5 minutes"
0   * * * * rake blazer:run_checks SCHEDULE="1 hour"
30  7 * * * rake blazer:run_checks SCHEDULE="1 day"
0   8 * * * rake blazer:send_failing_checks

For Slack notifications, create an incoming webhook and set:

BLAZER_SLACK_WEBHOOK_URL=https://hooks.slack.com/...

Name the webhook “Blazer” and add a cool icon.

Authentication

Don’t forget to protect the dashboard in production.

Basic Authentication

Set the following variables in your environment or an initializer.

ENV["BLAZER_USERNAME"] = "andrew"
ENV["BLAZER_PASSWORD"] = "secret"

Devise

authenticate :user, ->(user) { user.admin? } do
  mount Blazer::Engine, at: "blazer"
end

Other

Specify a before_action method to run in blazer.yml.

before_action_method: require_admin

You can define this method in your ApplicationController.

def require_admin
  # depending on your auth, something like...
  redirect_to root_path unless current_user && current_user.admin?
end

Be sure to render or redirect for unauthorized users.

Permissions

PostgreSQL

Create a user with read-only permissions:

BEGIN;
CREATE ROLE blazer LOGIN PASSWORD 'secret';
GRANT CONNECT ON DATABASE dbname TO blazer;
GRANT USAGE ON SCHEMA public TO blazer;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO blazer;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO blazer;
COMMIT;

MySQL

Create a user with read-only permissions:

CREATE USER 'blazer'@'127.0.0.1' IDENTIFIED BY 'secret';
GRANT SELECT, SHOW VIEW ON dbname.* TO 'blazer'@'127.0.0.1';
FLUSH PRIVILEGES;

Sensitive Data

If your database contains sensitive or personal data, check out Hypershield to shield it.

Encrypted Data

If you need to search encrypted data, use blind indexing.

You can have Blazer transform specific variables with:

Blazer.transform_variable = lambda do |name, value|
  value = User.generate_email_bidx(value) if name == "email_bidx"
  value
end

Queries

Variables

Create queries with variables.

SELECT * FROM users WHERE gender = {gender}

Use {start_time} and {end_time} for time ranges. Example

SELECT * FROM ratings WHERE rated_at >= {start_time} AND rated_at <= {end_time}

Smart Variables

Example

Suppose you have the query:

SELECT * FROM users WHERE occupation_id = {occupation_id}

Instead of remembering each occupation’s id, users can select occupations by name.

Add a smart variable with:

smart_variables:
  occupation_id: "SELECT id, name FROM occupations ORDER BY name ASC"

The first column is the value of the variable, and the second column is the label.

You can also use an array or hash for static data and enums.

smart_variables:
  period: ["day", "week", "month"]
  status: {0: "Active", 1: "Archived"}

Linked Columns

Example - title column

Link results to other pages in your apps or around the web. Specify a column name and where it should link to. You can use the value of the result with {value}.

linked_columns:
  user_id: "/admin/users/{value}"
  ip_address: "https://www.infosniper.net/index.php?ip_address={value}"

Smart Columns

Example - occupation_id column

Suppose you have the query:

SELECT name, city_id FROM users

See which city the user belongs to without a join.

smart_columns:
  city_id: "SELECT id, name FROM cities WHERE id IN {value}"

You can also use a hash for static data and enums.

smart_columns:
  status: {0: "Active", 1: "Archived"}

Caching

Blazer can automatically cache results to improve speed. It can cache slow queries:

cache:
  mode: slow
  expires_in: 60 # min
  slow_threshold: 15 # sec

Or it can cache all queries:

cache:
  mode: all
  expires_in: 60 # min

Of course, you can force a refresh at any time.

Charts

Blazer will automatically generate charts based on the types of the columns returned in your query.

Note: The order of columns matters.

Line Chart

There are two ways to generate line charts.

2+ columns - timestamp, numeric(s) - Example

SELECT date_trunc('week', created_at), COUNT(*) FROM users GROUP BY 1

3 columns - timestamp, string, numeric - Example

SELECT date_trunc('week', created_at), gender, COUNT(*) FROM users GROUP BY 1, 2

Column Chart

There are also two ways to generate column charts.

2+ columns - string, numeric(s) - Example

SELECT gender, COUNT(*) FROM users GROUP BY 1

3 columns - string, string, numeric - Example

SELECT gender, zip_code, COUNT(*) FROM users GROUP BY 1, 2

Scatter Chart

2 columns - both numeric - Example

SELECT x, y FROM table

Pie Chart

2 columns - string, numeric - and last column named pie - Example

SELECT gender, COUNT(*) AS pie FROM users GROUP BY 1

Maps

Columns named latitude and longitude or lat and lon or lat and lng - Example

SELECT name, latitude, longitude FROM cities

or a column named geojson

SELECT name, geojson FROM counties

To enable, get an access token from Mapbox and set ENV["MAPBOX_ACCESS_TOKEN"].

Targets

Use the column name target to draw a line for goals. Example

SELECT date_trunc('week', created_at), COUNT(*) AS new_users, 100000 AS target FROM users GROUP BY 1

Dashboards

Create a dashboard with multiple queries. Example

If the query has a chart, the chart is shown. Otherwise, you’ll see a table.

If any queries have variables, they will show up on the dashboard.

Checks

Checks give you a centralized place to see the health of your data. Example

Create a query to identify bad rows.

SELECT * FROM ratings WHERE user_id IS NULL /* all ratings should have a user */

Then create check with optional emails if you want to be notified. Emails are sent when a check starts failing, and when it starts passing again.

Cohorts

Create a cohort analysis from a simple SQL query. Example

Create a query with the comment /* cohort analysis */. The result should have columns named user_id and conversion_time and optionally cohort_time.

You can generate cohorts from the first conversion time:

/* cohort analysis */
SELECT user_id, created_at AS conversion_time FROM orders

(the first conversion isn’t counted in the first time period with this format)

Or from another time, like sign up:

/* cohort analysis */
SELECT users.id AS user_id, orders.created_at AS conversion_time, users.created_at AS cohort_time
FROM users LEFT JOIN orders ON orders.user_id = users.id

This feature requires PostgreSQL or MySQL 8.

Anomaly Detection

Blazer supports three different approaches to anomaly detection.

Prophet

Add prophet-rb to your Gemfile:

gem "prophet-rb"

And add to config/blazer.yml:

anomaly_checks: prophet

Trend

Trend uses an external service by default, but you can run it on your own infrastructure as well.

Add trend to your Gemfile:

gem "trend"

And add to config/blazer.yml:

anomaly_checks: trend

For the self-hosted API, create an initializer with:

Trend.url = "http://localhost:8000"

AnomalyDetection.rb

Add anomaly_detection to your Gemfile:

gem "anomaly_detection"

And add to config/blazer.yml:

anomaly_checks: anomaly_detection

Forecasting

Blazer supports for two different forecasting methods. Example

A forecast link will appear for queries that return 2 columns with types timestamp and numeric.

Prophet

Add prophet-rb to your Gemfile:

gem "prophet-rb", ">= 0.2.1"

And add to config/blazer.yml:

forecasting: prophet

Trend

Trend uses an external service by default, but you can run it on your own infrastructure as well.

Add trend to your Gemfile:

gem "trend"

And add to config/blazer.yml:

forecasting: trend

For the self-hosted API, create an initializer with:

Trend.url = "http://localhost:8000"

Uploads

Create database tables from CSV files. Example

Run:

rails generate blazer:uploads
rails db:migrate

And add to config/blazer.yml:

uploads:
  url: postgres://...
  schema: uploads
  data_source: main

This feature requires PostgreSQL. Create a new schema just for uploads.

CREATE SCHEMA uploads;

Data Sources

Blazer supports multiple data sources 🎉

Add additional data sources in config/blazer.yml:

data_sources:
  main:
    url: <%= ENV["BLAZER_DATABASE_URL"] %>
    # timeout, smart_variables, linked_columns, smart_columns
  catalog:
    url: <%= ENV["CATALOG_DATABASE_URL"] %>
    # ...
  redshift:
    url: <%= ENV["REDSHIFT_DATABASE_URL"] %>
    # ...

Full List

You can also create an adapter for any other data store.

Note: In the examples below, we recommend using environment variables for urls.

data_sources:
  my_source:
    url: <%= ENV["BLAZER_MY_SOURCE_URL"] %>

Amazon Athena

Add aws-sdk-athena and aws-sdk-glue to your Gemfile and set:

data_sources:
  my_source:
    adapter: athena
    database: database

    # optional settings
    output_location: s3://some-bucket/
    workgroup: primary
    access_key_id: ...
    secret_access_key: ...
    region: ...

Here’s an example IAM policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:GetQueryExecution",
                "athena:GetQueryResults",
                "athena:StartQueryExecution"
            ],
            "Resource": [
                "arn:aws:athena:region:account-id:workgroup/primary"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "glue:GetTable",
                "glue:GetTables"
            ],
            "Resource": [
                "arn:aws:glue:region:account-id:catalog",
                "arn:aws:glue:region:account-id:database/default",
                "arn:aws:glue:region:account-id:table/default/*"
            ]
        }
    ]
}

You also need to configure S3 permissions.

Amazon Redshift

Add activerecord6-redshift-adapter or activerecord5-redshift-adapter to your Gemfile and set:

data_sources:
  my_source:
    url: redshift://user:password@hostname:5439/database

Use a read-only user.

Apache Drill

Add drill-sergeant to your Gemfile and set:

data_sources:
  my_source:
    adapter: drill
    url: http://hostname:8047

Use a read-only user.

Apache Hive

Add hexspace to your Gemfile and set:

data_sources:
  my_source:
    adapter: hive
    url: sasl://user:password@hostname:10000/database

Use a read-only user. Requires HiveServer2.

Apache Ignite

Add ignite-client to your Gemfile and set:

data_sources:
  my_source:
    url: ignite://user:password@hostname:10800

Use a read-only user (requires a third-party plugin).

Apache Spark

Add hexspace to your Gemfile and set:

data_sources:
  my_source:
    adapter: spark
    url: sasl://user:password@hostname:10000/database

Use a read-only user. Requires the Thrift server.

Cassandra

Add cassandra-driver (and sorted_set for Ruby 3+) to your Gemfile and set:

data_sources:
  my_source:
    url: cassandra://user:password@hostname:9042/keyspace

Use a read-only role.

Druid

Enable SQL support on the broker and set:

data_sources:
  my_source:
    adapter: druid
    url: http://hostname:8082

Use a read-only role.

Elasticsearch

Add elasticsearch to your Gemfile and set:

data_sources:
  my_source:
    adapter: elasticsearch
    url: http://user:password@hostname:9200

Use a read-only role.

Google BigQuery

Add google-cloud-bigquery to your Gemfile and set:

data_sources:
  my_source:
    adapter: bigquery
    project: your-project
    keyfile: path/to/keyfile.json

IBM DB2 and Informix

Add ibm_db to your Gemfile and set:

data_sources:
  my_source:
    url: ibm-db://user:password@hostname:50000/database

Use a read-only user.

InfluxDB

Add influxdb to your Gemfile and set:

data_sources:
  my_source:
    adapter: influxdb
    url: http://user:password@hostname:8086/database

Use a read-only user. Supports InfluxQL.

MySQL

Add mysql2 to your Gemfile (if it’s not there) and set:

data_sources:
  my_source:
    url: mysql2://user:password@hostname:3306/database

Use a read-only user.

Neo4j

Add neo4j-core to your Gemfile and set:

data_sources:
  my_source:
    adapter: neo4j
    url: http://user:password@hostname:7474

Use a read-only user.

OpenSearch

Add opensearch-ruby to your Gemfile and set:

data_sources:
  my_source:
    adapter: opensearch
    url: http://user:password@hostname:9200

Use a read-only user.

Oracle

Add activerecord-oracle_enhanced-adapter and ruby-oci8 to your Gemfile and set:

data_sources:
  my_source:
    url: oracle-enhanced://user:password@hostname:1521/database

Use a read-only user.

PostgreSQL

Add pg to your Gemfile (if it’s not there) and set:

data_sources:
  my_source:
    url: postgres://user:password@hostname:5432/database

Use a read-only user.

Presto

Add presto-client to your Gemfile and set:

data_sources:
  my_source:
    url: presto://user@hostname:8080/catalog

Use a read-only user.

Salesforce

Add restforce to your Gemfile and set:

data_sources:
  my_source:
    adapter: salesforce

And set the appropriate environment variables:

SALESFORCE_USERNAME="username"
SALESFORCE_PASSWORD="password"
SALESFORCE_SECURITY_TOKEN="security token"
SALESFORCE_CLIENT_ID="client id"
SALESFORCE_CLIENT_SECRET="client secret"
SALESFORCE_API_VERSION="41.0"

Use a read-only user. Supports SOQL.

Socrata Open Data API (SODA)

Set:

data_sources:
  my_source:
    adapter: soda
    url: https://soda.demo.socrata.com/resource/4tka-6guv.json
    app_token: ...

Supports SoQL.

Snowflake

First, install ODBC. For Homebrew, use:

brew install unixodbc

For Ubuntu, use:

sudo apt-get install unixodbc-dev

For Heroku, use the Apt buildpack and create an Aptfile with:

unixodbc-dev
https://sfc-repo.snowflakecomputing.com/odbc/linux/2.21.5/snowflake-odbc-2.21.5.x86_64.deb

This installs the driver at /app/.apt/usr/lib/snowflake/odbc/lib/libSnowflake.so

Then, download the Snowflake ODBC driver. Add odbc_adapter to your Gemfile and set:

data_sources:
  my_source:
    adapter: snowflake
    conn_str: Driver=/path/to/libSnowflake.so;uid=user;pwd=password;server=host.snowflakecomputing.com

Use a read-only role.

SQLite

Add sqlite3 to your Gemfile and set:

data_sources:
  my_source:
    url: sqlite3:path/to/database.sqlite3

SQL Server

Add tiny_tds and activerecord-sqlserver-adapter to your Gemfile and set:

data_sources:
  my_source:
    url: sqlserver://user:password@hostname:1433/database

Use a read-only user.

Creating an Adapter

Create an adapter for any data store with:

class FooAdapter < Blazer::Adapters::BaseAdapter
  # code goes here
end

Blazer.register_adapter "foo", FooAdapter

See the Presto adapter for a good example. Then use:

data_sources:
  my_source:
    adapter: foo
    url: http://user:password@hostname:9200/

Query Permissions

Blazer supports a basic permissions model.

  1. Queries without a name are unlisted
  2. Queries whose name starts with # are only listed to the creator
  3. Queries whose name starts with * can only be edited by the creator

Learn SQL

Have team members who want to learn SQL? Here are a few great, free resources.

Useful Tools

For an easy way to group by day, week, month, and more with correct time zones, check out Groupdate.sql.

Standalone Version

Looking for a standalone version? Check out Ghost Blazer.

Performance

By default, queries take up a request while they are running. To run queries asynchronously, add to your config:

async: true

Note: Requires caching to be enabled. If you have multiple web processes, your app must use a centralized cache store like Memcached or Redis.

config.cache_store = :mem_cache_store

Archiving

Archive queries that haven’t been viewed in over 90 days.

rake blazer:archive_queries

Content Security Policy

If views are stuck with a Loading... message, there might be a problem with strict CSP settings in your app. This can be checked with Firefox or Chrome dev tools. You can allow Blazer to override these settings for its controllers with:

override_csp: true

Upgrading

3.0

Maps now use Mapbox GL JS v1 instead of Mapbox.js, which affects Mapbox billing.

2.6

Custom adapters now need to specify how to quote variables in queries (there is no longer a default)

class FooAdapter < Blazer::Adapters::BaseAdapter
  def quoting
    :backslash_escape # single quote strings and convert ' to \' and \ to \\
    # or
    :single_quote_escape # single quote strings and convert ' to ''
    # or
    ->(value) { ... } # custom method
  end
end

2.3

To archive queries, create a migration

rails g migration add_status_to_blazer_queries

with:

add_column :blazer_queries, :status, :string
Blazer::Query.update_all(status: "active")

2.0

To use Slack notifications, create a migration

rails g migration add_slack_channels_to_blazer_checks

with:

add_column :blazer_checks, :slack_channels, :text

History

View the changelog

Thanks

Blazer uses a number of awesome open source projects, including Rails, Vue.js, jQuery, Bootstrap, Selectize, StickyTableHeaders, Stupid jQuery Table Sort, and Date Range Picker.

Demo data from MovieLens.

Want to Make Blazer Better?

That’s awesome! Here are a few ways you can help:

Check out the dev app to get started.

blazer's People

Contributors

aki77 avatar ankane avatar atul9 avatar basilkhan05 avatar bastire avatar bernardolm avatar cannikin avatar cycomachead avatar ermolaev avatar ilstar avatar markrebec avatar masa331 avatar maxmullen avatar nickelser avatar pandu-49-zz avatar paultyng avatar pedrocarmona avatar pjb3 avatar popcorn4dinner avatar preetsethi avatar readmecritic avatar righi avatar ryninho avatar sausyn avatar starchow avatar stevenbeeckman avatar til avatar trevororeilly avatar ts-3156 avatar ttilberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blazer's Issues

Error while running user accounts query

Hi, I am running blazer BI and all queries are running except when i want to pull user accounts data i get an internal server error here is the log

Blazer::Check Load (0.3ms)  SELECT "blazer_checks".* FROM "blazer_checks" WHERE "blazer_checks"."query_id" = $1  [["query_id", 17]]
  Rendered /home/jmunyi/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/blazer-1.1.0/app/views/blazer/queries/run.html.erb (4.3ms)
Completed 500 Internal Server Error in 416ms (ActiveRecord: 259.7ms)

ActionView::Template::Error (invalid address):
     98:                     <% end %>
     99: 
    100:                     <% unless v.nil? %>
    101:                       <% if v == "" %>
    102:                         <div class="text-muted">empty string</div>
    103:                       <% elsif @linked_columns[k] %>
    104:                         <%= link_to blazer_format_value(k, v), @linked_columns[k].gsub("{value}", u(v.to_s)), target: "_blank" %>

the query is a very basic ans simple one

SELECT * FROM users WHERE team_id = {team_id}

any ideas

[noob] Blaze crashes after creating a new query

The following is probably due to me not knowing Rails and not doing something obvious, but if I create a new blank Rails project with only Blaze as per readme, Blaze ostensibly works, but after I save any query, going to the index page crashes with:

NameError in Blazer::Queries#index
Showing /Library/Ruby/Gems/2.0.0/gems/blazer-0.0.5/app/views/blazer/queries/index.html.erb where line #17 raised:

uninitialized constant Blazer::Query::User

This is on a completely vanilla install and happens regardless of being run in production or development or what I set for the db connection (which works fine).

Environment:

Rails version   4.2.1
Ruby version    2.0.0-p481 (universal.x86_64-darwin13)
RubyGems version    2.0.14
Rack version    1.6.1
JavaScript Runtime  JavaScriptCore
Middleware  
Rack::Sendfile
ActionDispatch::Static
Rack::Lock
#<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ff76b71a218>
Rack::Runtime
Rack::MethodOverride
ActionDispatch::RequestId
Rails::Rack::Logger
ActionDispatch::ShowExceptions
WebConsole::Middleware
ActionDispatch::DebugExceptions
ActionDispatch::RemoteIp
ActionDispatch::Reloader
ActionDispatch::Callbacks
ActiveRecord::Migration::CheckPending
ActiveRecord::ConnectionAdapters::ConnectionManagement
ActiveRecord::QueryCache
ActionDispatch::Cookies
ActionDispatch::Session::CookieStore
ActionDispatch::Flash
ActionDispatch::ParamsParser
Rack::Head
Rack::ConditionalGet
Rack::ETag
Application root    /Users/sb/******************************
Environment development
Database adapter    sqlite3
Database schema version 20150511195721

(have also tested on an Ubuntu AWS instance with same results)

Full stacktrace:

Application Trace | Framework Trace | Full Trace
activerecord (4.2.1) lib/active_record/inheritance.rb:158:in `compute_type'
activerecord (4.2.1) lib/active_record/reflection.rb:271:in `compute_class'
activerecord (4.2.1) lib/active_record/reflection.rb:267:in `klass'
activerecord (4.2.1) lib/active_record/associations/association.rb:118:in `klass'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:158:in `block in grouped_records'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:154:in `each'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:154:in `grouped_records'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:143:in `preloaders_for_one'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:115:in `preloaders_on'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:103:in `block in preload'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:102:in `each'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:102:in `flat_map'
activerecord (4.2.1) lib/active_record/associations/preloader.rb:102:in `preload'
activerecord (4.2.1) lib/active_record/relation.rb:644:in `block in exec_queries'
activerecord (4.2.1) lib/active_record/relation.rb:643:in `each'
activerecord (4.2.1) lib/active_record/relation.rb:643:in `exec_queries'
activerecord (4.2.1) lib/active_record/relation.rb:514:in `load'
activerecord (4.2.1) lib/active_record/relation.rb:243:in `to_a'
activerecord (4.2.1) lib/active_record/relation/delegation.rb:46:in `each'
blazer (0.0.5) app/views/blazer/queries/index.html.erb:17:in `___ibrary__uby__ems_______gems_blazer_______app_views_blazer_queries_index_html_erb__2193773787389831153_70190750348020'
actionview (4.2.1) lib/action_view/template.rb:145:in `block in render'
activesupport (4.2.1) lib/active_support/notifications.rb:166:in `instrument'
actionview (4.2.1) lib/action_view/template.rb:333:in `instrument'
actionview (4.2.1) lib/action_view/template.rb:143:in `render'
actionview (4.2.1) lib/action_view/renderer/template_renderer.rb:54:in `block (2 levels) in render_template'
actionview (4.2.1) lib/action_view/renderer/abstract_renderer.rb:39:in `block in instrument'
activesupport (4.2.1) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.1) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.1) lib/active_support/notifications.rb:164:in `instrument'
actionview (4.2.1) lib/action_view/renderer/abstract_renderer.rb:39:in `instrument'
actionview (4.2.1) lib/action_view/renderer/template_renderer.rb:53:in `block in render_template'
actionview (4.2.1) lib/action_view/renderer/template_renderer.rb:61:in `render_with_layout'
actionview (4.2.1) lib/action_view/renderer/template_renderer.rb:52:in `render_template'
actionview (4.2.1) lib/action_view/renderer/template_renderer.rb:14:in `render'
actionview (4.2.1) lib/action_view/renderer/renderer.rb:42:in `render_template'
actionview (4.2.1) lib/action_view/renderer/renderer.rb:23:in `render'
actionview (4.2.1) lib/action_view/rendering.rb:100:in `_render_template'
actionpack (4.2.1) lib/action_controller/metal/streaming.rb:217:in `_render_template'
actionview (4.2.1) lib/action_view/rendering.rb:83:in `render_to_body'
actionpack (4.2.1) lib/action_controller/metal/rendering.rb:32:in `render_to_body'
actionpack (4.2.1) lib/action_controller/metal/renderers.rb:37:in `render_to_body'
actionpack (4.2.1) lib/abstract_controller/rendering.rb:25:in `render'
actionpack (4.2.1) lib/action_controller/metal/rendering.rb:16:in `render'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
activesupport (4.2.1) lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/benchmark.rb:296:in `realtime'
activesupport (4.2.1) lib/active_support/core_ext/benchmark.rb:12:in `ms'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:44:in `block in render'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:87:in `cleanup_view_runtime'
activerecord (4.2.1) lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:43:in `render'
actionpack (4.2.1) lib/action_controller/metal/implicit_render.rb:10:in `default_render'
actionpack (4.2.1) lib/action_controller/metal/implicit_render.rb:5:in `send_action'
actionpack (4.2.1) lib/abstract_controller/base.rb:198:in `process_action'
actionpack (4.2.1) lib/action_controller/metal/rendering.rb:10:in `process_action'
actionpack (4.2.1) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
activesupport (4.2.1) lib/active_support/callbacks.rb:117:in `call'
activesupport (4.2.1) lib/active_support/callbacks.rb:117:in `call'
activesupport (4.2.1) lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
activesupport (4.2.1) lib/active_support/callbacks.rb:505:in `call'
activesupport (4.2.1) lib/active_support/callbacks.rb:505:in `call'
activesupport (4.2.1) lib/active_support/callbacks.rb:92:in `_run_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:776:in `_run_process_action_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.1) lib/abstract_controller/callbacks.rb:19:in `process_action'
actionpack (4.2.1) lib/action_controller/metal/rescue.rb:29:in `process_action'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
activesupport (4.2.1) lib/active_support/notifications.rb:164:in `block in instrument'
activesupport (4.2.1) lib/active_support/notifications/instrumenter.rb:20:in `instrument'
activesupport (4.2.1) lib/active_support/notifications.rb:164:in `instrument'
actionpack (4.2.1) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
actionpack (4.2.1) lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
activerecord (4.2.1) lib/active_record/railties/controller_runtime.rb:18:in `process_action'
actionpack (4.2.1) lib/abstract_controller/base.rb:137:in `process'
actionview (4.2.1) lib/action_view/rendering.rb:30:in `process'
actionpack (4.2.1) lib/action_controller/metal.rb:196:in `dispatch'
actionpack (4.2.1) lib/action_controller/metal/rack_delegation.rb:13:in `dispatch'
actionpack (4.2.1) lib/action_controller/metal.rb:237:in `block in action'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:in `call'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:74:in `dispatch'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:43:in `serve'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `each'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:819:in `call'
railties (4.2.1) lib/rails/engine.rb:518:in `call'
railties (4.2.1) lib/rails/railtie.rb:194:in `public_send'
railties (4.2.1) lib/rails/railtie.rb:194:in `method_missing'
actionpack (4.2.1) lib/action_dispatch/routing/mapper.rb:51:in `serve'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:43:in `block in serve'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `each'
actionpack (4.2.1) lib/action_dispatch/journey/router.rb:30:in `serve'
actionpack (4.2.1) lib/action_dispatch/routing/route_set.rb:819:in `call'
rack (1.6.1) lib/rack/etag.rb:24:in `call'
rack (1.6.1) lib/rack/conditionalget.rb:25:in `call'
rack (1.6.1) lib/rack/head.rb:13:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/flash.rb:260:in `call'
rack (1.6.1) lib/rack/session/abstract/id.rb:225:in `context'
rack (1.6.1) lib/rack/session/abstract/id.rb:220:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/cookies.rb:560:in `call'
activerecord (4.2.1) lib/active_record/query_cache.rb:36:in `call'
activerecord (4.2.1) lib/active_record/connection_adapters/abstract/connection_pool.rb:649:in `call'
activerecord (4.2.1) lib/active_record/migration.rb:378:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.2.1) lib/active_support/callbacks.rb:88:in `call'
activesupport (4.2.1) lib/active_support/callbacks.rb:88:in `_run_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:776:in `_run_call_callbacks'
activesupport (4.2.1) lib/active_support/callbacks.rb:81:in `run_callbacks'
actionpack (4.2.1) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/reloader.rb:73:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/remote_ip.rb:78:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
web-console (2.1.2) lib/web_console/middleware.rb:37:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.2.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.1) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.1) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.1) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.1) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.6.1) lib/rack/methodoverride.rb:22:in `call'
rack (1.6.1) lib/rack/runtime.rb:18:in `call'
activesupport (4.2.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
rack (1.6.1) lib/rack/lock.rb:17:in `call'
actionpack (4.2.1) lib/action_dispatch/middleware/static.rb:113:in `call'
rack (1.6.1) lib/rack/sendfile.rb:113:in `call'
railties (4.2.1) lib/rails/engine.rb:518:in `call'
railties (4.2.1) lib/rails/application.rb:164:in `call'
rack (1.6.1) lib/rack/lock.rb:17:in `call'
rack (1.6.1) lib/rack/content_length.rb:15:in `call'
rack (1.6.1) lib/rack/handler/webrick.rb:89:in `service'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'

Random Improvements

  • better search
  • cancel query when a new query is run
  • remember variables
  • make editor larger

Attempting to generate a URL from non-sanitized request parameters!

If i add smart variables to blazer configuration i get this error.
This is the partial stack trace of the error

Blazer::Query Load (0.3ms)  SELECT  "blazer_queries".* FROM "blazer_queries" WHERE "blazer_queries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
   (0.2ms)  BEGIN
   (0.2ms)  SELECT id, title FROM posts ORDER BY title ASC /*blazer*/
   (0.2ms)  ROLLBACK
  Rendering vendor/bundle/gems/blazer-1.4.0/app/views/blazer/queries/show.html.erb within layouts/blazer/application
  Rendered vendor/bundle/gems/blazer-1.4.0/app/views/blazer/_nav.html.erb (1.1ms)
  Rendered vendor/bundle/gems/blazer-1.4.0/app/views/blazer/queries/show.html.erb within layouts/blazer/application (11.4ms)
Completed 500 Internal Server Error in 23ms (ActiveRecord: 0.8ms)

ArgumentError - Attempting to generate a URL from non-sanitized request parameters! An attacker can inject malicious data into the generated URL, such as changing the host. Whitelist and sanitize passed parameters to be secure.:
  actionpack (5.0.0.beta4) lib/action_dispatch/routing/url_for.rb:176:in `url_for'
  actionview (5.0.0.beta4) lib/action_view/routing_url_for.rb:96:in `url_for'
  blazer (1.4.0) app/views/blazer/queries/show.html.erb:55:in `_vendor_bundle_gems_blazer_______app_views_blazer_queries_show_html_erb___1963724263189473542_70206828597120'
...

Could you help me?

Chart Axes

Since chart.js supports axes, would you be interested in something that either:

  • automatically adds axes based on column names / chart type
  • has two text fields (one X and one Y)

I might try to hack an initial pass on this, since I'm using blazer for some images for a thesis and have been asked to redo all the charts.

Audit only stores user if current_user is defined

Right now the audit user is only stored if current_user is defined within the ApplicationController. It would be ideal to configure the method that returns the user object for use with auditing (especially given that you can configure the user model in the association definitions).

Ideas

Done

  • customize order to user (last 20 queries viewed or use data science to determine)
  • treat smart column as string for chart generation
  • show error message on server error
  • metrics on query runtime (add to audits?)
  • save as / fork option on edit page
  • support long queries (over 30 sec)
  • speed up home page when thousands of queries
  • raise error when url is blank in production
  • add indexes to template
  • cache option (under advanced)
  • treat smart column / id field as string for charts
  • keep params when editing dashboard

Query Won't Run If Variable Dropdown Is Left Blank

Now that queries auto-submit when a value from a variable dropdown is changed, queries don't seem to run if one of those values is left unselected. Previously, unselected values were used to indicate that those values should be NULL.

ActionView::Template::Error (undefined method `back_url'.....

Anyone seen this before? I searched through all issues and couldn't find anything.

ActionView::Template::Error (undefined method back_url' for #Blazer::QueriesController:0x007fa96c1efd08):`

Not sure what's causing it. I might just fork the gem and take that <%= link_to "Back", :back %> out.

Read Only Database User

Dummy question...

The docs recommend making the database user a read-only user. How can the app save queries if the database user is read only?

Autocomplete tables and columns

Autocomplete tables and columns in the query editor. Ace.js provides this functionality, but it gets in the way more than it helps. Something as smooth as Sublime Text would be great.

Blazer is overriding Devise path

Hi, I just figured that blazer is overriding devise gem in my app. Everything works fine in development but in production here is the error when I clicked on the login button undefined method 'session_path' and when I click on the signup button, I get undefined method 'registration_path' error.

After installing and uninstalling blazer gem, I figured out that was the reason. How do I solve this.

Blazer 2.0

For 2.0

  • raise error for unknown data sources
  • adapters out of beta
  • migration to get everyone on same schema - check timeouts, etc
  • release async: true option - requires a centralized cache store, so shouldn't make default

Before 2.0

  • cancel all queries on page nav
  • show schema
  • cancelable queries

Possibly

  • better organization (maybe tags)
  • verified queries (on verify_archive branch)
  • advanced permission model (locking queries, etc)
  • move to Vue

Creating Public / Sharable Pages

This one comes from Heroku's "Dataclips" feature.

I'd like to optionally be able to designate a dashboard / query as 'public' which would allow the page to be visited even if there's a before_filter active. This would make sharing some analysis easy, without needing to give users full admin access.

Bonus points that'd be cool:

  • The CSV export URL could be public. (This would allow embedding CSV data in a Google Sheet, which is also a neat little trick. Heroku Dataclips does this.)
  • Make the public pages read only if not logged in.
  • Make the public pages not indexable by google

Javascript breaks in queries/show

After I save a simple query and then try to view it, it doesn't show any data. Instead it displayes 'loading...'.

Reason is a breaking js error:

Uncaught SyntaxError: Unexpected identifier

Then on that line I see:

    $.post("/tt-queries/queries/run?subaccount=experience", {statement:select * from users limit 1,query_id:1}, function (data) {

Seems like the statement is missing quotes.

We're using rails 4.0.13.

Everything is ok in development mode , But I got error on Production

I use nginx on my server, When I add blazer into my gemfile and execute 'bundle' command and then restart my 'nginx' Server , I got error in my passenger log file and my website doesn't work anymore

my nginx error log file is:

[ 2016-05-08 12:18:21.3869 6103/7ff65c471700 age/Cor/App/Implementation.cpp:304 ]: Could not spawn process for application /home/deploy/www/tagisland: An e$
  Error ID: 2dbc4b07
  Error details saved to: /tmp/passenger-error-vf2NHV.html
  Message from application: Unknown key: :required. Valid keys are: :class_name, :class, :foreign_key, :validate, :autosave, :remote, :dependent, :primary_$
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/core_ext/hash/keys.rb:71:in `block in assert_valid_key$
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/core_ext/hash/keys.rb:69:in `each_key'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/core_ext/hash/keys.rb:69:in `assert_valid_keys'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations/builder/association.rb:81:in `validate_opti$
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations/builder/association.rb:61:in `initialize'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations/builder/association.rb:46:in `new'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations/builder/association.rb:46:in `create_builde$
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations/builder/association.rb:35:in `build'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activerecord-4.1.2/lib/active_record/associations.rb:1433:in `belongs_to'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/blazer-1.3.2/app/models/blazer/audit.rb:3:in `<class:Audit>'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/blazer-1.3.2/app/models/blazer/audit.rb:2:in `<module:Blazer>'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/blazer-1.3.2/app/models/blazer/audit.rb:1:in `<top (required)>'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:247:in `require'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:247:in `block in require'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:232:in `load_dependency'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:247:in `require'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:348:in `require_or_load'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:307:in `depend_on'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/activesupport-4.1.2/lib/active_support/dependencies.rb:225:in `require_dependency'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:468:in `block (2 levels) in eager_load!'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:467:in `each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:467:in `block in eager_load!'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:465:in `each'
/home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:465:in `each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:465:in `eager_load!'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/engine.rb:346:in `eager_load!'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/application/finisher.rb:58:in `each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/application/finisher.rb:58:in `block in <module:Finisher>'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/initializable.rb:30:in `instance_exec'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/initializable.rb:30:in `run'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/initializable.rb:55:in `block in run_initializers'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:226:in `block in tsort_each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:348:in `block (2 levels) in each_strongly_connected_component'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:429:in `each_strongly_connected_component_from'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:347:in `block in each_strongly_connected_component'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:345:in `each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:345:in `call'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:345:in `each_strongly_connected_component'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:224:in `tsort_each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/2.2.0/tsort.rb:203:in `tsort_each'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/initializable.rb:54:in `run_initializers'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/railties-4.1.2/lib/rails/application.rb:300:in `initialize!'
  /home/deploy/www/tagisland/config/environment.rb:7:in `<top (required)>'
  config.ru:3:in `require'
  config.ru:3:in `block in <main>'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `instance_eval'
  /home/deploy/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in `initialize'
  config.ru:1:in `new'
  config.ru:1:in `<main>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `eval'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:110:in `preload_app'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:156:in `<module:App>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:30:in `<module:PhusionPassenger>'
  /usr/share/passenger/helper-scripts/rack-preloader.rb:29:in `<main>'

PLEASE HELP ME

smart_column not working

I have a column gender with values (NULL, 1, 2) - 1 is Male, 2 is Female, and NULL is Unknown and I want the string versions outputted. In blazer.yml I've tried making many gender smart variables but they all just show blank, 1, or 2 - none will show the string. below are some examples - instead of IN (1) etc I tried = 1 nothing works.

gender: "SELECT gender, (CASE WHEN {value} IN (1) THEN 'Male'
WHEN {value} IN (2) THEN 'Female'
ELSE 'Unknown'
END)"

gender_id: "SELECT (CASE WHEN {value} IN (1) THEN 'Male'
WHEN {value} IN (2) THEN 'Female'
ELSE 'Unknown'
END)"

gender_id: "(CASE WHEN {value} IN (1) THEN 'Male'
WHEN {value} IN (2) THEN 'Female'
ELSE 'Unknown'
END)"

Blazer doesn't update data_source url

On production, i updated data_source url in env variable but Blazer still uses old one, and redeploy does not help, checking this variable in rails console shown that the variable was updated in rails environment, more of that Blazer.settings.dig('data_sources', 'main', 'url') shows new url, but when i try to connect to db it still uses the old one

Vertica Support

We currently use PeriscopeData so I love the direction this project is taking. The only thing holding me back from introducing Blazer to a broader group is that we use Vertica instead of Redshift as our data warehouse. Are there any plans to add support for Vertica?

deploying blazer into production

Hi I have blazer running locally, but in production despite adding blazer.yml into my Capistrano linked files folder is still BLAZER_DATABASE_URL required

i already have this in my yml file

ENV["BLAZER_DATABASE_URL"] = "postgres://att_tra: att_tra@localhost/att_tra_production"

whats missing

JS error when loading charts after saving

The chart preview screen is working, but after saving and trying to load the charts I get this JS error and the chart doesn't load:
screenshot 2015-10-09 16 57 28

If the SQL query is put in single quotes (eg: 'select created_at, count(*) from user_tickets GROUP BY YEAR(created_at), MONTH(created_at)') it fixes this error (but messes up the preview page since it tries to execute the quotes).

Adding multiple, different (SQL / MySQL) data sources breaks smart variables.

Previously, I had set up Blazer with a single MySQL data source. I had several smart variables set up and working. Here's an excerpt:

smart_variables:
      company_id: "SELECT id, name FROM companies ORDER BY name ASC"
      product_id: "SELECT id, name FROM products ORDER BY name ASC"
      team_id: "SELECT id, name FROM teams ORDER BY name ASC"

However, once I added an additional data source (this time an MS SQL database), the existing MySQL smart variables no longer displayed as select boxes. I only get inputs now.

Oddly enough, smart variables that pull from tables in the MS SQL database appear to be working.

I think the issue may stem from conflicting table names in the MySQL and MS SQL databases, eg. both database might have a products table, and the smart variable doesn't know which database to pull from. However, attempting to modify my blazer queries to include use mysqldatabase haven't fixed the issue. Thanks!

Unable to sign-in after installing

I have been unable to sign up and login in my app's production after installing blazer gem.

Here was the process I followed to install blazer:

1. add gem 'blazer' to Gemfile
2. bundle installed
3. ran rails g blazer:install
4. rake db:migrate
5.heroku run rake db:migrate
6. add BLAZER_DATABASE_URL: "postgres://user:password@hostname:5432/database" in my application.yml file
7. add BLAZER_USERNAME: "andrew" and BLAZER_PASSWORD: = "secret" in my application.yml file

Here is the screenshot of the error log (basicaly, Device's session_path could not be found)
image

uninitialized constant #{candidates.first}", candidates.first

I've recently upgraded to blazer 1.0.3; previously I was on version 0.0.7.

I first ran into an issue where I couldn't save any new queries because we don't have a User class... I fixed that with the following addition to blazer.yml:

user_clas: nil

Now, I can save new queries but I'm getting an error when I'm trying to view the default home page which lists all of the queries. Here's a snippet of the error message:

NameError in Blazer::Queries#home
Showing /Users/crystal/.rvm/gems/ruby-2.2.0/gems/blazer-1.0.3/app/views/blazer/queries/_index.html.erb where line #1 raised:

uninitialized constant Blazer::Query::nil
       end
          raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
        end
      end


Trace of template inclusion: /Users/crystal/.rvm/gems/ruby-2.2.0/gems/blazer-1.0.3/app/views/blazer/queries/home.html.erb

Rails.root: /Users/crystal/workspace/mvln/reporter2

Application Trace | Framework Trace | Full Trace
activerecord (4.2.4) lib/active_record/inheritance.rb:158:in `compute_type'
activerecord (4.2.4) lib/active_record/reflection.rb:271:in `compute_class'
activerecord (4.2.4) lib/active_record/reflection.rb:267:in `klass'
activerecord (4.2.4) lib/active_record/associations/association.rb:118:in `klass'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:158:in `block in grouped_records'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:154:in `each'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:154:in `grouped_records'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:143:in `preloaders_for_one'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:115:in `preloaders_on'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:103:in `block in preload'
activerecord (4.2.4) lib/active_record/associations/preloader.rb:102:in `each'

Any thoughts of what's going on here? I haven't worked with Ruby/Rails much so if there's some expectation on how to set up Users for the tool, I've missed it (I haven't seen any details about it in the README). Getting users set up is a secondary concern though... first we just want to get the homepage backup and running. Thanks!

Colour palette

each one of my queries with grouping is showing a very flat colour palette, usually first 2 are blue, and the rest are grey shades.

screenshot from 2016-10-20 22-44-02

Is this a bug or intentional?

Thanks!

Add Materialized Views to the Preview Tables

First off, thanks for a great library

One thing that I think would be useful would be to preview any materialized views in /queries/new in the Preview Tables drop down.

I'm not sure off the top of my head if all SQL databases support Materialized Views (we use Postgres) but for the ones that do, I think would be useful. If this is something you would be interested in having in this library, I'd be happy to help out with it anyway I can or create a PR and any suggestions on how you would go about it or at least a starting point would be appreciate.

Thanks again!

NameError: uninitialized constant Blazer::YAML while deploying in production

I get this error while deploying on production (unicorn) works fine in development (webrix).
Tried setting the BLAZER_DATABASE_URL environment through profile file as well as environment.rb

NameError: uninitialized constant Blazer::YAML
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/blazer-1.0.4/lib/blazer.rb:30:in settings' /var/www/dashboard/shared/bundle/ruby/2.2.0/gems/blazer-1.0.4/lib/blazer/engine.rb:9:inblock in class:Engine'
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/initializable.rb:30:in instance_exec' /var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/initializable.rb:30:inrun'
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/initializable.rb:55:in block in run_initializers' /var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/initializable.rb:54:inrun_initializers'
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:352:in initialize!' /var/www/dashboard/releases/20151215121328/config/environment.rb:5:in<top (required)>'
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:328:in require' /var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:328:inrequire_environment!'
/var/www/dashboard/shared/bundle/ruby/2.2.0/gems/railties-4.2.2/lib/rails/application.rb:457:in block in run_tasks_blocks' /var/www/dashboard/shared/bundle/ruby/2.2.0/gems/sprockets-rails-2.3.2/lib/sprockets/rails/task.rb:64:inblock (2 levels) in define'
Tasks: TOP => environment
(See full trace by running task with --trace)

Dropdown in 'edit query' view is never populated

I would like to get some advice to fix my problem.

The dropdown under the query textarea on the edit query view is never populated, nor can I execute any queries. Every query results in:

relation "table_name" does not exist LINE 1: select * from table_name; /*blazer*/ ^ :
select * from table_name; /*blazer*/

Example query which fails using Blazer, but works when executed in psql:

select * from products;

select * from "public"."products";

I created a blazer role, tried with the admin user, ... and am basically out of options.

Thank you.

search "me" to get my queries

Currently I can search "You" to get my queries. however, i think it might make more sense to get them by searching "me".

Error with smart variables and regular expressions

First off, awesome project, thanks!

Using the blazer example app on heroku - https://blazerme.herokuapp.com/queries/new

If we wanted to find a movie with the word 'yao' in the title, we can do

SELECT * FROM movies
WHERE title ~ 'yao';

Works and returns the movie with the title "Shanghai Triad (Yao a yao yao dao waipo qiao) (1995)"

But if we use a regex to find 'yao yao ' in the title using a bound (http://www.postgresql.org/docs/current/static/functions-matching.html)

SELECT * FROM movies
WHERE title ~ '(yao ){2}';

We should get the same result as above but instead we get "Can’t preview queries with variables...yet!" message

I think that the extract_vars method in the base_controller is looking for any left curly brace (https://github.com/ankane/blazer/blob/master/app/controllers/blazer/base_controller.rb#L46)

Not really sure the best way to deal with that. Our hack was just add some code that ignores smart variables in a line if they come after a the tilde but we'd like to be able to use smart variables everywhere. What about maybe using double instead of single curly braces so extract_vars method can know it's supposed to be a smart variable? Or whatever other suggestions you all might have

Thanks again!

Emails being sent from list tracking.domain.com

I've specified the from address in blazer.yml. When checks are run and they fail, the email generated is from a mailing list according to gmail.

The problem I am trying to solve is why other people in my organization are getting these emails that are addressed to me and me only. Some of these people are in the catchall email group, but not all.

image

The from is an alias for me. My email address it the to.

If you need any more information, please let me know. I've never seen this before and I don't really know where to check.

EDIT: Logs if this helps.

I, [2016-05-02T12:00:10.327543 #14867]  INFO -- : [ActiveJob] [ActionMailer::DeliveryJob] [6bf0317e-1e84-42fc-a32c-2b36e576ec83] Performing ActionMailer::DeliveryJob from Inline(mailers) with arguments: "Blazer::CheckMailer", "failing_checks", "deliver_now", "[email protected]", [#<Blazer::Check id: 1, query_id: 3, state: "failing", emails: "[email protected]", created_at: "2016-04-30 18:53:25", updated_at: "2016-04-30 20:17:01">, #<Blazer::Check id: 2, query_id: 5, state: "failing", emails: "[email protected]", created_at: "2016-05-01 21:06:35", updated_at: "2016-05-01 21:06:37">]
I, [2016-05-02T12:00:10.376703 #14878]  INFO -- : [blazer check] query=Users Without Passwords state=failing rows=16 error=
I, [2016-05-02T12:00:10.383712 #14878]  INFO -- : [blazer check] query=Users who should be Supply Side state=failing rows=26 error=
I, [2016-05-02T12:00:10.394852 #14867]  INFO -- : [ActiveJob] [ActionMailer::DeliveryJob] [6bf0317e-1e84-42fc-a32c-2b36e576ec83]   Rendered /home/deploy/OppSites/shared/bundle/ruby/2.2.0/gems/blazer-1.2.1/app/views/blazer/check_mailer/failing_checks.html.erb (24.7ms)
I, [2016-05-02T12:00:11.719367 #14867]  INFO -- : [ActiveJob] [ActionMailer::DeliveryJob] [6bf0317e-1e84-42fc-a32c-2b36e576ec83] 
Sent mail to [email protected] (1046.1ms)
I, [2016-05-02T12:00:11.719796 #14867]  INFO -- : [ActiveJob] [ActionMailer::DeliveryJob] [6bf0317e-1e84-42fc-a32c-2b36e576ec83] Performed ActionMailer::DeliveryJob from Inline(mailers) in 1391.67ms
I, [2016-05-02T12:00:11.721661 #14867]  INFO -- : [ActiveJob] Enqueued ActionMailer::DeliveryJob (Job ID: 6bf0317e-1e84-42fc-a32c-2b36e576ec83) to Inline(mailers) with arguments: "Blazer::CheckMailer", "failing_checks", "deliver_now", "[email protected]", [#<Blazer::Check id: 1, query_id: 3, state: "failing", emails: "[email protected]", created_at: "2016-04-30 18:53:25", updated_at: "2016-04-30 20:17:01">, #<Blazer::Check id: 2, query_id: 5, state: "failing", emails: "[email protected]", created_at: "2016-05-01 21:06:35", updated_at: "2016-05-01 21:06:37">]

rails g blazer:install looking for blazer.yml

The install process is looking for the blazer.yml file before it exists: /lib/blazer.rb:26

Repro: Run rails g blazer:install without the config/blazer.yml file

/Users/dj/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/blazer-1.0.1/lib/blazer.rb:26:in `read': No such file or directory - /Users/dj/Code/getfixed/config/blazer.yml (Errno::ENOENT)
    from /Users/dj/.rbenv/versions/2.0.0-p353/lib/ruby/gems/2.0.0/gems/blazer-1.0.1/lib/blazer.rb:26:in `settings'

Easy work around, but not ideal so thought you guys should know. Project looks cool btw!

Index page not showing all queries

Just upgraded to Blazer 1.3.3 from 1.1. Some queries are no longer showing on the main page even though they exist. Also just made a new query it doesn't show up either. Everything shows up in the /queries json though.

Easier overriding of Blazer templates

@ankane

What are your thoughts on extracting the various navs (Dashboards#show and Queries#show) into partials so that they can be more easily overridden by a parent application. This is something that I've been wanting to be able to do and it appears that others do as well (#49).

Currently if we override the layout in Blazer::BaseController, these navs still sit on top of whatever navigation was introduced by the parent application's layout file.

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken)

For API only app, I get the error above. The culprit is this:

protect_from_forgery with: :exception

In https://github.com/ankane/blazer/blob/master/app/controllers/blazer/base_controller.rb#L6

Why is blazer overwriting the default protect_from_forgery from the ApplicationController. Doesn't seem like it should be the case. I reopened and removed the line and everything is working. Happy to submit a PR if this makes sense.

PS absolutely love Blazer, saves us a lot of headache.

Blazer unexpectedly hijacks popular keyboard shortcut Cmd+L

Cmd+L is a popular browser keyboard shortcut to move focus to the URL bar. Currently blazer hijacks this to help you navigate to a specific line. Perhaps we could use an alternate keyboard shortcut like Ctrl+g (like Sublime) for this?

Error on new Query: ActionView::Template::Error (Empty url)

I am trying ot use blazer in prod, but I have this error as when trying to create a new query:

Started GET "/admin/reports/queries/new" for 192.168.99.1 at 2016-10-14 16:48:28 +0000
Processing by Blazer::QueriesController#new as HTML
  Rendering /usr/local/bundle/gems/blazer-1.7.0views/layouts/blazer/application.html.erb
  Rendering /usr/local/bundle/gems/blazer-1.7.0views/blazer/queries/new.html.erb within layouts/blazer/application
  Rendered /usr/local/bundle/gems/blazer-1.7.0views/blazer/queries/_form.html.erb (12.5ms)
  Rendered /usr/local/bundle/gems/blazer-1.7.0views/blazer/queries/new.html.erb within layouts/blazer/application (13.2ms)
  Rendered /usr/local/bundle/gems/blazer-1.7.0views/layouts/blazer/application.html.erb (13.6ms)
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.0ms)

ActionView::Template::Error (Empty url):
    15:         <div class="pull-left" style="margin-top: 6px;">
    16:           <%= link_to "Back", :back %>
    17:         </div>
    18:         <%= f.select :data_source, Blazer.data_sources.values.map { |ds| [ds.name, ds.id] }, {}, class: ("hide" if Blazer.data_sources.size == 1), style: "width: 140px;" %>
    19:         <div id="tables" style="display: inline-block; width: 250px; margin-right: 10px;" class="hide">
    20:           <%= render partial: "tables" %>
    21:         </div>

blazer (1.7.0) lib/blazer/data_source.rb:16:in `initialize'
blazer (1.7.0) lib/blazer.rb:73:in `new'
blazer (1.7.0) lib/blazer.rb:73:in `block in data_sources'

Creating dashboards works, so DB access seems right, looks liek the link_to is failling somehow

Blazer app colliding with my main ApplicationController and app's routes

Hi, I'm trying to install blazer to try it out. I'm running into a few weird issues where Blazer is colliding with my main app.

My core question is: Is Blazer supposed to be mounted as an entire separate app, similar to Sidekiq's web interface? Or is Blazer supposed to inherit code (controller, routes) from my main app?

Environment:

  • Ruby 2.3.1
  • Rails 4.2.6
  • Blazer 1.4.0

I followed the README very directly...

  • Default blazer.yml generated by rails g blazer:install
  • mount Blazer::Engine, at: "blazer" in config/routes.rb

The first problem I run into is this error when loading /blazer:

You must activate the Authlogic::Session::Base.controller with a
controller object before creating objects

My main app uses the authlogic gem. The traceback for this error leads to a method in app/controllers/application_controller.rb (my main application controller). Blazer::BaseController subclasses ApplicationController, and it's using my main app's ApplicationController. Is this intentional?

When I comment out the offending authentication function in ApplicationController, the /blazer path loads, but all URL generation on the page fails and none of the links work (i.e. can't a new dashboard). The log says:

DEPRECATION WARNING: You are trying to generate the URL for a named route called "new_query"
but no such route was found. In the future, this will result in an `ActionController::UrlGenerationError`
exception.` `rake routes` shows the routes like this:

rake routes shows:

(my apps routes, where there is no new_query route)

Routes for Blazer::Engine:
      run_queries POST   /queries/run(.:format)            blazer/queries#run
    refresh_query POST   /queries/:id/refresh(.:format)    blazer/queries#refresh
   tables_queries GET    /queries/tables(.:format)         blazer/queries#tables
   new_query GET    /queries/new(.:format)            blazer/queries#new
...

Somehow, it seems like Blazer is again, when looking for routes, looking in the routes for my app, not the Blazer Engine routes. From reading about Rails Engines, it seems like the intention is for none of Blazer's code to use my ApplicationController or routes, but that's not happening.

It's too bad, I wish I could get this working to test. I'm happy to do some extra work around here if you guide me on where to look. Thanks for the time you spend working on this gem, it looks awesome, I hope I can get it working somehow.

Adding a menu link to the main App

Hi,

I have implemented the reporting tool and everything so far is almost running fine, but i am wondering how to add a menu which can lead users back to the main app without having to manually edit the browser link or using the back button

Update to 1.7.2 crashes the query overview and query editor

Our blazer updated automatically on heroku from 1.7.0 to 1.7.2 The result was all our blazer queries were in accessible, the dashboards were visible but the stats on the dashboards were all not found. And the query editor broke. The results were the following pictures:

blazer_bug2

blazer_bug1

Creating Charts with Non-String X-Axis

From my understanding of the current views, it seems like I can only create bar charts if the type for the column is a string? Is there a reason this couldn't work for integers or other numbers?

I'm currently using Postgres' to_char() functions, which seem to work OK. Was this the intention?
If not, I could look into making a PR. Otherwise, I think a bit of documentation in the README would be good. I'd really appreciate a table of Column Types vs Graph Types.

Thanks for the awesome work though! 👍

How to add a SQLite db as a data source?

Hey, the doc does mention SQLite but can you please provide an example?

I just want to use blazer on a .sqlite3 file which is not my rails database ; is it possible?

ActiveJob

I noticed that the async mode is bound to sucker_punch and not documented.

Does it work? Any reason a PR refactoring to use active job instead of suckerpunch directly might not be a good idea? We use sidekiq in our environment and would like to avoid adding another library.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.