Merge branch 'master' into 512

This commit is contained in:
Phil Freeman 2020-09-08 10:23:31 -07:00 committed by GitHub
commit 34c80f2a8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 335 additions and 37 deletions

119
docs/_static/scripts/mysql-subscribe.js vendored Normal file
View File

@ -0,0 +1,119 @@
const mysql_email_input = document.getElementById('mysql-EMAIL');
const mysql_submit_btn = document.getElementById('mysql-embedded-subscribe');
const mysql_success_status = document.getElementById('mysql-success-response');
const mysql_status_error = document.getElementById('mysql-error-response');
mysql_email_input.addEventListener('input', function() {
mysql_submit_btn.value = 'Subscribe';
mysql_submit_btn.disabled = false;
mysql_status_error.innerHTML = '';
mysql_status_error.classList.add('hide');
});
const showMySQLErrorMsg = () => {
mysql_submit_btn.value = 'Subscribe';
mysql_submit_btn.disabled = false;
mysql_status_error.innerHTML = 'Please enter a valid email';
mysql_status_error.classList.remove('hide');
clearMySQLMsg();
};
const clearMySQLMsg = () => {
setTimeout(function(){
mysql_success_status.innerHTML = '';
mysql_status_error.innerHTML = '';
mysql_success_status.classList.add('hide');
mysql_status_error.classList.add('hide');
mysql_submit_btn.disabled = true;
//reset input
mysql_email_input.value = '';
}, 3000);
}
const submitMySQLForm = function (form) {
let gqlEndpoint = 'https://graphql-engine-website.hasura.io/v1/graphql';
if(window.location.host !== "hasura.io") {
gqlEndpoint = 'https://graphql-engine-website.hasura-stg.hasura-app.io/v1/graphql';
}
// change button state
mysql_submit_btn.value = 'Subscribing...';
mysql_submit_btn.disabled = true;
const email = form.elements["EMAIL"].value;
const hbs_context = {
"hutk": readCookie("hubspotutk"), // include this parameter and set it to the hubspotutk cookie value to enable cookie tracking on your submission
"pageUri": window.location.host + window.location.pathname,
"pageName": document.title,
};
const gqlMutation = `mutation notifyDatabaseSupport($object: databaseSupportInput!) {
notifyDatabaseSupport(object: $object) {
id
}
}`;
const object = {
"category": "docs",
"database": "MySQL",
"email": email,
"hbs_context": hbs_context
};
fetch(gqlEndpoint, {
method: 'POST',
body: JSON.stringify({
query: gqlMutation,
variables: { object: object }
}),
})
.then(response => response.json())
.then(data => {
// change button state
mysql_submit_btn.value = 'Subscribe';
mysql_submit_btn.disabled = false;
if (data && data.data && data.data.notifyDatabaseSupport.id) {
mysql_success_status.innerHTML = 'Subscribed!';
mysql_success_status.classList.remove('hide');
} else {
if(data.errors && data.errors[0].message.includes('Uniqueness violation')) {
mysql_status_error.innerHTML = 'You have already subscribed';
} else {
mysql_status_error.innerHTML = 'Something went wrong';
}
mysql_status_error.classList.remove('hide');
}
clearMySQLMsg();
})
.catch((error) => {
console.error('Error:', error);
mysql_submit_btn.value = 'Subscribe';
mysql_submit_btn.disabled = false;
});
};
document.addEventListener('submit', function (event) {
// Only run on forms flagged for mysql-subscribe-form validation
if (!event.target.classList.contains('mysql-subscribe-form')) return;
// Prevent form from submitting
event.preventDefault();
// email validation
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if(!emailPattern.test(mysql_email_input.value)) {
showMySQLErrorMsg();
return;
}
// Otherwise, let the form submit normally
submitMySQLForm(event.target);
}, false);

View File

@ -1,7 +1,7 @@
const email_input = document.getElementById('mce-EMAIL');
const submit_btn = document.getElementById('mc-embedded-subscribe');
const mcStatusSuccess = document.querySelector('.mce-success-response');
const mcStatusError = document.querySelector('.mce-error-response');
const mcStatusSuccess = document.getElementById('mce-success-response');
const mcStatusError = document.getElementById('mce-error-response');
email_input.addEventListener('input', function() {
submit_btn.value = 'Subscribe';
@ -60,16 +60,19 @@ const submitNewsletterForm = function (form) {
"pageUri": window.location.host + window.location.pathname,
"pageName": document.title,
};
const gqlMutation = `mutation docsNewsletterSignup($objects: [newsletterSignupInput!]! ) {
signupNewsletter(objects: $objects) {
affected_rows
}
}`;
const objects = [{
"email": email,
"hbs_context": hbs_context,
"category": "docs"
}]
}];
fetch(gqlEndpoint, {
method: 'POST',
body: JSON.stringify({

View File

@ -99,16 +99,16 @@ p {
}
/* Newsletter */
#mc_embed_signup {
.mc_embed_signup {
display: flex;
align-items: center;
}
#mc_embed_signup .subscribe-form-content {
.mc_embed_signup .subscribe-form-content {
font-weight: bold;
color: #001934;
padding-right: 40px;
}
#mc_embed_signup form {
.mc_embed_signup form {
display: flex !important;
padding: 0 0 0 0 !important;
flex: 1 !important;
@ -116,17 +116,17 @@ p {
font-size: 16px;
}
/* todo: redesign & clean up */
#mc_embed_signup input:focus {border-color:#333;}
#mc_embed_signup .button {clear:both; background-color: #aaa; border: 0 none; border-radius:4px; transition: all 0.23s ease-in-out 0s; color: #FFFFFF; cursor: pointer; display: inline-block; font-size:15px; font-weight: normal; height: 32px; line-height: 32px; margin: 0 5px 10px 0; padding: 0 22px; text-align: center; text-decoration: none; vertical-align: top; white-space: nowrap; width: auto;}
#mc_embed_signup .button:hover {background-color:#777;}
#mc_embed_signup .clear {clear:both;}
.mc_embed_signup input:focus {border-color:#333;}
.mc_embed_signup .button {clear:both; background-color: #aaa; border: 0 none; border-radius:4px; transition: all 0.23s ease-in-out 0s; color: #FFFFFF; cursor: pointer; display: inline-block; font-size:15px; font-weight: normal; height: 32px; line-height: 32px; margin: 0 5px 10px 0; padding: 0 22px; text-align: center; text-decoration: none; vertical-align: top; white-space: nowrap; width: auto;}
.mc_embed_signup .button:hover {background-color:#777;}
.mc_embed_signup .clear {clear:both;}
#mc_embed_signup div#mce-responses {float:left; top:-1.4em; padding:0em .5em 0em .5em; overflow:hidden; width:90%; margin: 0 5%; clear: both;}
#mc_embed_signup div.response {margin:1em 0; padding:1em .5em .5em 0; font-weight:bold; float:left; top:-1.5em; z-index:1; width:80%;}
#mc_embed_signup #mce-error-response {display:none;}
#mc_embed_signup #mce-success-response {color:#529214; display:none;}
#mc_embed_signup label.error {display:block; float:none; width:auto; margin-left:1.05em; text-align:left; padding:.5em 0;}
#mc-embedded-subscribe {clear:both; width:auto; display:block; margin:1em 0 1em 5%;}
.mc_embed_signup div.mce-responses {float:left; top:-1.4em; padding:0em .5em 0em .5em; overflow:hidden; width:90%; margin: 0 5%; clear: both;}
.mc_embed_signup div.response {margin:1em 0; padding:1em .5em .5em 0; font-weight:bold; float:left; top:-1.5em; z-index:1; width:80%;}
/*.mc_embed_signup .mce-error-response {display:none;}*/
.mc_embed_signup .mce-success-response {color:#529214;}
.mc_embed_signup label.error {display:block; float:none; width:auto; margin-left:1.05em; text-align:left; padding:.5em 0;}
.mc-embedded-subscribe {clear:both; width:auto; display:block; margin:1em 0 1em 5%;}
.newsletter-link,
.newsletter-link:hover,
@ -204,7 +204,7 @@ p {
.submit-box input:focus {
outline: none;
}
#mce-responses .error-message, #mce-responses .success-message {
.mce-responses .error-message, .mce-responses .success-message {
background-color: #001934;
padding: 8px 12px !important;
border-radius: 4px;
@ -216,13 +216,13 @@ p {
width: auto !important;
}
#mce-responses .error-message a, #mce-responses .success-message a {
.mce-responses .error-message a, .mce-responses .success-message a {
color: #fff !important;
}
#mce-responses .error-message {
.mce-responses .error-message {
color: #efc371 !important;
}
#mce-responses .success-message {
.mce-responses .success-message {
color: #1cd3c6 !important;
}
#content_inner_wrapper {
@ -1014,17 +1014,17 @@ article ol ol {
}
}
@media (min-width: 768px) and (max-width: 1385px) {
#mc_embed_signup form {
.mc_embed_signup form {
padding-top: 10px !important;
}
#mc_embed_signup {
.mc_embed_signup {
display: block;
}
#mc_embed_signup .subscribe-form-content {
.mc_embed_signup .subscribe-form-content {
padding-right: 0;
text-align: center;
}
#mce-responses .error-message, #mce-responses .success-message {
.mce-responses .error-message, .mce-responses .success-message {
top: 34px !important;
}
}
@ -1034,20 +1034,20 @@ article ol ol {
top: 170px;
height: calc(100% - 170px);
}
#mc_embed_signup {
.mc_embed_signup {
display: block;
}
#mc_embed_signup .subscribe-form-content {
.mc_embed_signup .subscribe-form-content {
padding-right: 0;
text-align: center;
}
#mc_embed_signup form {
.mc_embed_signup form {
padding-top: 10px !important;
}
.submit-box input {
padding: 0 4px !important;
}
#mce-responses .error-message, #mce-responses .success-message {
.mce-responses .error-message, .mce-responses .success-message {
top: 34px !important;
}
#input_search_box {

View File

@ -29,6 +29,10 @@
{% set deferred_script_files = ['_static/react/react.min.js', '_static/react/react-dom.min.js', '_static/graphiql/graphiql.min.js', '_static/scripts/hdocs.js', '_static/scripts/newsletter.js'] %}
{%- if pagename.endswith('mysql-preview') %}
{% set deferred_script_files = deferred_script_files + ['_static/scripts/mysql-subscribe.js'] %}
{%- endif %}
{%- macro secondnav() %}
{%- if prev %}
&laquo; <a href="{{ prev.link|e }}" title="{{ prev.title|e }}">previous</a>
@ -290,29 +294,27 @@
</div>
</div>
<div class="subscribe-form-wrapper">
<div id="mc_embed_signup">
<div id="mc_embed_signup" class="mc_embed_signup">
<div class="subscribe-form-content">
Stay up to date with product & security news
<!-- <a target="_blank" class="newsletter-link" href="https://us13.campaign-archive.com/home/?u=9b63e92a98ecdc99732456b0e&id=f5c4f66bcf" rel="noopener">See past editions</a> -->
</div>
<form id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate post-subscription-form newsletter-form" target="_blank" rel="noopener" novalidate>
<form id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate post-subscription-form mc-embedded-subscribe-form newsletter-form" target="_blank" rel="noopener" novalidate>
<div class="full-width">
<div class="input-box">
<input type="email" name="EMAIL" id="mce-EMAIL" aria-label="Email" placeholder="Your Email Address" pattern="^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$" required>
<input type="email" name="EMAIL" id="mce-EMAIL" class="mce-EMAIL" aria-label="Email" placeholder="Your Email Address" pattern="^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$" required>
</div>
<div id="mce-responses" class="clear display-inline">
<div class="mce-error-response response error-message hide">
<div id="mce-responses" class="clear display-inline mce-responses">
<div id="mce-error-response" class="mce-error-response response error-message hide">
</div>
<div class="mce-success-response response success-message hide">
<div id="mce-success-response" class="mce-success-response response success-message hide">
</div>
</div>
</div>
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_9b63e92a98ecdc99732456b0e_f5c4f66bcf" tabindex="-1" value=""></div>
<div class="clear submit-box">
<input type="submit" disabled="true" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button">
<input type="submit" disabled="true" value="Subscribe" name="subscribe" id="mc-embedded-subscribe" class="button mc-embedded-subscribe">
</div>
</form>
</div>
</div>
<div class="footer-hasura-custom">

View File

@ -42,6 +42,11 @@ Get started using an existing database
Hasura GraphQL engine supports **Postgres 9.5 and above**
.. admonition:: MySQL support
We are in the process of launching support for MySQL, head to :ref:`this guide <mysql_preview>` to try it out in preview.
.. toctree::
:maxdepth: 2
:titlesonly:

View File

@ -24,6 +24,7 @@ Guides / Tutorials / Resources
Auditing tables <auditing-tables>
Telemetry <telemetry>
Code Editor Integrations <code-editor-integrations/index>
MySQL preview <mysql-preview>

View File

@ -0,0 +1,127 @@
.. meta::
:description: MySQL preview
:keywords: hasura, mysql, preview
.. _mysql_preview:
MySQL preview
=============
.. contents:: Table of contents
:backlinks: none
:depth: 2
:local:
Introduction
------------
We are in the process of launching support for MySQL, and we have a preview available for you to try.
Try it out
----------
MySQL support can be tried out using ``docker-compose`` and an existing MySQL database
as follows:
Prerequisites
^^^^^^^^^^^^^
- `Docker <https://docs.docker.com/install/>`_
- `Docker Compose <https://docs.docker.com/compose/install/>`_
- An existing MySQL database
Step 1: Get the docker-compose file
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Get the Hasura MySQL preview docker compose file:
.. code-block:: bash
# in a new directory run
wget https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/docker-compose-mysql-preview/docker-compose.yaml
# or run
curl https://raw.githubusercontent.com/hasura/graphql-engine/master/install-manifests/docker-compose-mysql-preview/docker-compose.yaml -o docker-compose.yaml
Step 2: Update MySQL config
^^^^^^^^^^^^^^^^^^^^^^^^^^^
You need to now update the ``docker-compose.yaml`` file with credentials for your
MySQL database *(replace the values surrounded by <>)*
.. code-block:: yaml
...
command:
- graphql-engine
- --mysql-host
- <mysql-host>
- --mysql-user
- <mysql-user>
- --mysql-port
- <mysql-port>
- --mysql-dbname
- <mysql-dbname>
- --mysql-password
- <mysql-password>
...
Step 3: Run Hasura GraphQL engine
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
$ docker-compose up -d
Check if the containers are running:
.. code-block:: bash
$ docker ps
CONTAINER ID IMAGE ... CREATED STATUS PORTS ...
097f58433a2b hasura/graphql-engine ... 1m ago Up 1m 8080->8080/tcp ...
b0b1aac0508d postgres ... 1m ago Up 1m 5432/tcp ...
Step 4: Try out the GraphQL API
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The console available at ``http://localhost:8080/console`` can be used to try
out the generated API.
The Hasura console currently does not support MySQL (support coming very soon)
and hence the database needs to be managed externally as of now. i.e. The ``Data``
section of the console will not display the MySQL tables, etc.
Keep up to date
---------------
If you'd like to stay informed about the status of MySQL support, subscribe here:
.. raw:: html
<div>
<div id="mysql_embed_signup" class="mc_embed_signup">
<form id="mysql-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate post-subscription-form mc-embedded-subscribe-form mysql-subscribe-form" target="_blank" rel="noopener" novalidate>
<div style="width: 40%">
<div class="input-box">
<input type="email" name="EMAIL" id="mysql-EMAIL" class="mce-EMAIL" aria-label="Email" placeholder="Your Email Address" pattern="^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$" required>
</div>
<div id="mysql-responses" class="clear display-inline mce-responses">
<div id="mysql-error-response" class="mce-error-response response error-message hide">
</div>
<div id="mysql-success-response" class="mce-success-response response success-message hide">
</div>
</div>
</div>
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_9b63e92a98ecdc99732456b0e_f5c4f66bcf" tabindex="-1" value=""></div>
<div class="clear submit-box" style="max-width: 120px !important">
<input type="submit" disabled="true" value="Subscribe" name="subscribe" id="mysql-embedded-subscribe" class="button mc-embedded-subscribe">
</div>
</form>
</div>
</div>
Give us feedback
----------------
We appreciate any feedback. Please open a new `Github discussion <https://github.com/hasura/graphql-engine/discussions>`__, and we can discuss there.

View File

@ -0,0 +1,41 @@
version: '3.6'
services:
postgres:
image: postgres:12
restart: always
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgrespassword
graphql-engine:
image: hasura/graphql-engine:pull5655-633f084f
ports:
- "8080:8080"
depends_on:
- "postgres"
command:
- graphql-engine
- --mysql-host
- <mysql-host>
- --mysql-user
- <mysql-user>
- --mysql-port
- <mysql-port>
- --mysql-dbname
- <mysql-dbname>
- --mysql-password
- <mysql-password>
- serve
restart: always
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
## enable the console served by server
HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console
## enable debugging mode. It is recommended to disable this in production
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
## uncomment next line to set an admin secret
# HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
volumes:
db_data: