emGee Software Solutions Custom Database Applications

Share this

Web Technologies

A Look into MariaDB Auditing for GDPR Compliance

Planet MySQL - Wed, 05/23/2018 - 15:27
A Look into MariaDB Auditing for GDPR Compliance maria-luisaraviol Wed, 05/23/2018 - 18:27

When we are talking about a database auditing concept, what we are focused on is tracking the use of database records, and the monitoring of each operation on the data.

The auditing activities goal is to provide a clear and reliable answer to the typical 4 W questions: Who accessed the database, When did this happen, What was touched, Where this access came from. Auditing should also help the security team answer the 5th W: Why this happened?

Auditing is also a very important task when we want to monitor the database activity to collect information that can help to increase the database performance or debug the application.

When we talk about security, accountability and regulatory compliance Database Auditing plays an even more critical role.

An auditing activity is key in achieving accountability as it allows us to investigate malicious or suspicious database activities. It’s used to help DBAs detect excessive user privileges or suspicious activities coming from specific connections.

In particular, the new European Union General Data Protection Regulation (GDPR) says that it will be important to be able to provide detail of changes to personal data to demonstrate that data protection and security procedures are effective and are being followed. Furthermore, we must ensure that data is only accessed by appropriate parties. This means that we need to be able to say who changed an item of data and when they changed it.

It’s broader than GDPR. HIPAA (Health Insurance Portability and Accountability Act) requires healthcare providers to deliver audit trails about anyone and everyone who touches any data in their records. This is down to the row and record level.

Furthermore, if a data breach occurs, organizations must disclose full information on these events to their local data protection authority (DPA) and all customers concerned with the data breach within 72 hours so they can respond accordingly.

MariaDB Audit Plugin

For all these reasons MariaDB started including the Audit Plugin since version 10.0.10 of MariaDB Server. The purpose of the MariaDB Audit Plugin is to log the server's activity: for each client session, it records who connected to the server (i.e., user name and host), what queries were executed, and which tables were accessed and server variables that were changed.

Events that are logged by the MariaDB Audit Plugin are grouped into three different types: CONNECT, QUERY and TABLE events.

There are actually more types of events to allow fine-tuning of the audit, and focus on just the events and statements relevant for a specific organisation. These are detailed on the Log Settings Page.

There also exist several system variables to configure the MariaDB Audit Plugin. the Server Audit Status Variables page includes all variables relevant to review the status of the auditing. The overall monitoring should include an alert to monitor that the auditing is active.

This information is stored in a rotating log file or it may be sent to the local syslog.

For security reasons, it's sometimes recommended to use the system logs instead of a local file: in this case the value of server_audit_output_type needs to be set to syslog.

It is also possible to set up even more advanced and secure solutions such as using a remote syslog service (Read more about the MariaDB Audit Plugin and setting up a rsyslog).

What does the MariaDB audit log file looks like?

The audit log file is a set of rows in plain text format, written as a list of comma-separated fields to a file. The general format for the logging to the plugin's own file is defined like the following:

[timestamp],[serverhost],[username],[host],[connectionid], [queryid],[operation],[database],[object],[retcode]

If the log file is sent to syslog the format is slightly different as the syslog has its own standard format (refer to the MariaDB Audit Plugin Log Format page for the details).

A typical MariaDB Audit plugin log file example is:

# tail mlr_Test_audit.log 20180421 09:22:38,mlr_Test,root,localhost,22,0,CONNECT,,,0 20180421 09:22:42,mlr_Test,root,localhost,22,35,QUERY,,'CREATE USER IF NOT EXISTS \'mlr\'@\'%\' IDENTIFIED WITH \'mysql_native_password\' AS \'*F44445443BB93ED07F5FAB7744B2FCE47021238F\'',0 20180421 09:22:42,mlr_Test,root,localhost,22,36,QUERY,,'drop user if exists mlr',0 20180421 09:22:45,mlr_Test,root,localhost,22,0,DISCONNECT,,,0 20180421 09:25:29,mlr_Test,root,localhost,20,0,FAILED_CONNECT,,,1045 20180421 09:25:44,mlr_Test,root,localhost,43,133,WRITE,employees,salaries, 20180421 09:25:44,mlr_Test,root,localhost,43,133,QUERY,employees,'DELETE FROM salaries LIMIT 100',0

Audit Files Analysis

Log files are a great source of information but only if you have a system in place to consistently review the data. Also the way you shape your application and database environment is important. In order to get useful auditing, for example, it’s recommended that every human user has his own account.

Furthermore, from the applications standpoint, if those are not using native DB accounts but application based accounts, each application accessing the same server should have its own "application-user".

As we said before, you have to use the information collected and analyse it on a regular basis, and when needed, take immediate actions based on those logged events. However, even small environments can generate a lot of information to be analysed manually.

Starting with the most recent release, Monyog 8.5, the monitoring tool that is included with the MariaDB TX and MariaDB AX subscriptions,  added a very interesting feature for MariaDB: The Audit Log.

This feature parses the audit log maintained by MariaDB Server and displays the content in a clean tabular format.

Monyog accesses the audit log file, the same way it does for other MariaDB log files, including the Slow Query, General Query and Error log.

Through the Monyog interface you can select the server and the time-frame for which you want the audit log to be seen from.  Then, clicking on “SHOW AUDIT LOG” fetches the contents of the log. The limit on the number of rows that can be fetched in one time-frame is 10000.

The snapshot above gives you a quick summary of the audit log in a percentage, like Failed Logins, Failed Events, Schema changes, Data Changes and Stored Procedure. All these legends are clickable and shows the corresponding audit log entries on clicking.

Furthermore, you can use the filter option to fetch audit log based on Username, Host, Operation, Database and Table/Query.

Login or Register to post comments

Categories: Web Technologies

Percona Monitoring and Management 1.11.0 Is Now Available

Planet MySQL - Wed, 05/23/2018 - 13:37

Percona Monitoring and Management (PMM) is a free and open-source platform for managing and monitoring MySQL® and MongoDB® performance. You can run PMM in your own environment for maximum security and reliability. It provides thorough time-based analysis for MySQL® and MongoDB® servers to ensure that your data works as efficiently as possible.

In PMM Release 1.11.0, we deliver the following changes:

  • Configurable MySQL Slow Log Rotation – enable or disable rotation, and specify how many files to keep on disk
  • Predictable Graphs – we’ve updated our formulas to use aggregation functions over time for more reliable graphs
  • MySQL Exporter Parsing of my.cnf – we’ve improved how we read my.cnf
  • Annotation improvements – passing multiple strings results in single annotation being written

The issues in the release includes 1 new features & improvements, and 9 bugs fixed.

MySQL Slow Log Rotation Improvements

We spent some time this release going over how we handle MySQL’s Slow Log rotation logic. Query Analytics requires that slow logging be enabled (either to file, or to PERFORMANCE_SCHEMA) and we found that users of Percona Server for MySQL overwhelmingly choose logging to a file in order to take advantage of log_slow_verbosity which provides enhanced InnoDB Usage information. However, the challenge with MySQL’s Slow Log is that it is very verbose and thus the number one concern is disk space. PMM strives to do no harm and so MySQL Slow Log Rotation was a natural fit, but until this release we were very strict and hadn’t enabled any configuration of these parameters.

Percona Server for MySQL Users have long known about Slow Query Log Rotation and Expiration, but until now had no way of using the in-built Percona Server for MySQL feature while ensuring that PMM wasn’t missing any queries from the Slow Log during file rotation. Or perhaps your use case is that you want to do Slow Log Rotation using logrotate or some other facility. Today with Release 1.11 this is now possible!

We’ve made two significant changes:

  1. You can now specify the number of Slow Log files to remain on disk, and let PMM handle deleting the oldest files first. Default remains unchanged – 1 Slow Log to remain on disk.
  2. Slow Log rotation can now be disabled, for example if you want to manage rotation using logrotate or Percona Server for MySQL Slow Query Log Rotation and Expiration. Default remains unchanged – Slow Log Rotation is ON.

Number of Slow Logs Retained on Disk

Slow Logs Rotation – On or Off

You specify each of these two new controls when setting up the MySQL service. The following example specifies that 5 Slow Log files should remain on disk:

pmm-admin add mysql ... --retain-slow-logs=5

While the following example specifies that Slow Log rotation is to be disabled (flag value of false), with the assumption that you will perform your own Slow Log Rotation:

pmm-admin add mysql ... --slow-log-rotation=false

We don’t currently support modifying option parameters for an existing service definition. This means you must remove, then re-add the service and include the new options.

We’re including a logrotate script in this post to get you started, and it is designed to keep 30 copies of Slow Logs at 1GB each. Note that you’ll need to update the Slow Log location, and ensure a MySQL User Account with SUPER, RELOAD are used for this script to successfully execute.

Example logrotate /var/mysql/mysql-slow.log {     nocompress     create 660 mysql mysql     size 1G     dateext     missingok     notifempty     sharedscripts     postrotate        /bin/mysql -e 'SELECT @@global.long_query_time INTO @LQT_SAVE; SET GLOBAL long_query_time=2000; SELECT SLEEP(2); FLUSH SLOW LOGS; SELECT SLEEP(2); SET GLOBAL long_query_time=@LQT_SAVE;'     endscript     rotate 30 } Predictable Graphs

We’ve updated the logic on four dashboards to better handle predictability and also to allow zooming to look at shorter time ranges.  For example, refreshing PXC/Galera graphs prior to 1.11 led to graphs spiking at different points during the metric series. We’ve reviewed each of these graphs and their corresponding queries and added in <aggregation>_over_time() functions so that graphs display a consistent view of the metric series. This improves your ability to drill in on the dashboards so that no matter how short your time range, you will still observe the same spikes and troughs in your metric series. The four dashboards affected by this improvement are:

  • Home Dashboard
  • PXC/Galera Graphs Dashboard
  • MySQL Overview Dashboard
  • MySQL InnoDB Metrics Dashboard
MySQL Exporter parsing of my.cnf

In earlier releases, the MySQL Exporter expected only key=value type flags. It would ignore options without values (i.e. disable-auto-rehash), and could sometimes read the wrong section of the my.cnf file.  We’ve updated the parsing engine to be more MySQL compatible.

Annotation improvements

Annotations permit the display of an event on all dashboards in PMM.  Users reported that passing more than one string to pmm-admin annotate would generate an error, so we updated the parsing logic to assume all strings passed during annotation creation generates a single annotation event.  Previously you needed to enclose your strings in quotes so that it would be parsed as a single string.

Issues in this release New Features & Improvements
  • PMM-2432 – Configurable MySQL Slow Log File Rotation
Bug fixes
  • PMM-1187 – Graphs breaks at tight resolution 
  • PMM-2362 – Explain is a part of query 
  • PMM-2399 – RPM for pmm-server is missing some files 
  • PMM-2407 – Menu items are not visible on PMM QAN dashboard 
  • PMM-2469 – Parsing of a valid my.cnf can break the mysqld_exporter 
  • PMM-2479 – PXC/Galera Cluster Overview dashboard: typo in metric names 
  • PMM-2484 – PXC/Galera Graphs display unpredictable results each time they are refreshed 
  • PMM-2503 – Wrong InnoDB Adaptive Hash Index Statistics 
  • PMM-2513 – QAN-agent always changes max_slowlog_size to 0 
  • PMM-2514 – pmm-admin annotate help – fix typos
  • PMM-2515 – pmm-admin annotate – more than 1 annotation 
How to get PMM

PMM is available for installation using three methods:

Help us improve our software quality by reporting any bugs you encounter using our bug tracking system.

The post Percona Monitoring and Management 1.11.0 Is Now Available appeared first on Percona Database Performance Blog.

Categories: Web Technologies

Learning Gutenberg: React 101

CSS-Tricks - Wed, 05/23/2018 - 12:41

Although Gutenberg is put together with React, the code we’re writing to make custom blocks isn’t. It certainly resembles a React component though, so I think it’s useful to have a little play to get familiar with this sort of approach. There’s been a lot of reading in this series so far, so let’s roll-up our sleeves and make something cool.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)
Let’s make an “About Me” component

We’re going to make a single React component that updates the background color of a page and the intro text based on data you input into a couple of fields. “I thought this was supposed to be cool,” I hear you all mutter. I’ll admit, I may have oversold it, but we’re going to learn some core concepts of state-driven JavaScript which will come in handy when we dig into our Gutenberg block.

For reference, this is what we’re going to end up with:

Getting started

The first thing we’re going to do is fire up CodePen. CodePen can be used for free, so go head over there and create a new Pen.

Next, we’re going to pull in some JavaScript dependencies. There are three editor screens—find the JS screen and click the settings cog. This will open up a Pen Settings modal where you’ll find the section titled Add External Scripts/Pens. Right at the bottom, theres a Quick-add select menu. Go ahead and open that up.

From the menu, select React. Once that’s selected, open the menu and select ReactDOM. You’ll see that this has pre-filled some text boxes.

Lastly, we need to enable our ES6 code, so at the menu titled JavaScript Preprocessor, select Babel.

Now, go ahead and click the big Save & Close button.

What we’ve done there is pull the main React JS library and ReactDOM library. These will enable us to dive in and write our code, which is our next step.

Setup our CSS

Let’s make it look cool. First up though, let’s setup our CSS editor. The first thing we’re going to do is set it up to compile Sass for us. Just like we did with the JS editor, click on the settings cog which will bring up the Pen Settings modal again—this time with the CSS settings.

At the top, there’s a CSS Preprocessor menu. Go ahead and select SCSS from there.

When that’s done, go down to the Add External Stylesheets/Pens and paste the following three links into separate text-boxes:

https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.css https://fonts.googleapis.com/css?family=Work+Sans:300 https://rawgit.com/hankchizljaw/boilerform/master/dist/css/boilerform.min.css

Those three in order give us a reset, a fancy font and some helpful form styles.

Now that they’re all set, go ahead and click the "Save & Close" button again.

Adding a bit of style

We’re all setup so this step should be easy. Paste the following Sass into the CSS editor:

:root { --text-color: #f3f3f3; } * { box-sizing: border-box; } html { height: 100%; font-size: 16px; } body { height: 100%; position: relative; font-size: 1rem; line-height: 1.4; font-family: "Work Sans", sans-serif; font-weight: 300; background: #f3f3f3; color: #232323; } .about { width: 100%; height: 100%; position: absolute; top: 0; left: 0; color: var(--text-color); transition: all 2000ms ease-in-out; &__inner { display: flex; flex-direction: column; height: 100%; margin: 0 auto; padding: 1.2rem; } &__content { display: flex; flex-direction: column; justify-content: center; align-items: center; flex: 1 1 auto; font-size: 3rem; line-height: 1.2; > * { max-width: 30ch; } } &__form { display: flex; flex-direction: column; align-items: center; padding: 2rem 0; width: 100%; max-width: 60rem; margin: 0 auto; @media(min-width: 32rem) { flex-direction: row; justify-content: space-between; padding: 2rem; } > * { width: 15rem; } > * + * { margin: 1rem 0 0 0; @media(min-width: 32rem) { margin: 0; } } label { display: block; } } } // Boilerform overrides .c-select-field { &, &__menu { width: 100%; } } .c-input-field { width: 100%; } .c-label { color: var(--text-color); }

That’s a big ol’ chunk of CSS, and it’ll look like nothing has really happened, but it’s all good—we’re not going to have to worry about CSS for the rest of this section.

Digging into React

The first thing we’re going to do is give React something to latch on to. Paste this into the HTML editor of your Pen:

<div id="root"></div>

That’s it for HTML—you can go ahead and maximize your JS editor so we’ve got complete focus.

Let’s start our component code, by creating a new instance of a React component by writing the following JavaScript:

class AboutMe extends React.Component { }

What that code is doing is creating a new AboutMe component and extending React’s Component class, which gives us a load of code and tooling for free.

Right, so we’ve got a class, and now we need to construct it! Add the following code, inside the brackets:

constructor(props) { super(props); let self = this; };

We’ve got a few things going on here, so I’ll explain each:

constructor is the method that’s called when you write new AboutMe(), or if you write <AboutMe /> in your JSX. This constructs the object. The props parameter is something you’ll see a lot in React. This is the collection of properties that are passed into the component. For example: if you wrote <AboutMe name="Andy" />, you’d be able to access it in your constructor with props.name.

super is how we tell the class that we’ve extended to construct with its own constructor. You’ll see we’re also passing the props up to it in case any parent components need to access them.

Finally let self = this is a way of controlling the scope of this. Remember, because we’re using let, self will only be available in the constructor function.

Quick note for those readers not-so-confident in JavaScript: I found a deeper look at scope in JavaScript to result in a lot of “aha” moments in my learning. I highly recommend Kyle Simpson’s You Don’t Know JS book series (available for free on GitHub!). Volumes of note: this and Object Prototypes and Scope & Closures. Good stuff, I promise.

Now we’ve covered the constructor, let’s add some more code to it. After the let self = this; line, paste the following code:

self.availableColors = [ { "name": "Red", "value": "#ca3814" }, { "name": "Blue", "value": "#0086cc" }, { "name": "Green", "value": "#3aa22b" } ];

What we’ve got there is an array of objects that define our options for picking your favorite color. Go ahead and add your own if it’s not already there!

Your class definition and constructor should now look like this:

class AboutMe extends React.Component { constructor(props) { super(props); let self = this; // Set a list of available colors that render in the select menu self.availableColors = [ { "name": "Red", "value": "#ca3814" }, { "name": "Blue", "value": "#0086cc" }, { "name": "Green", "value": "#3aa22b" } ]; }; }

Pretty straightforward so far, right? Let’s move on and set some initial values to our reactive state. Add the following after the closing of self.availableColors:

// Set our initial reactive state values self.state = { name: 'Foo', color: self.availableColors[0].value };

This initial setting of state enables our component to render both a name and a color on load, which prevents it from looking broken.

Next, we’ll add our render function. This is a pure function, which does nothing but render the component based on the initial state or any state changes during the component’s lifecycle. You may have guessed already, but this is where the main body of our JSX lives.

Wait up! What’s a pure function? Welcome to functional programming, a hot topic in the React world. Pure functions are functions where, for input X, the output will always be Y. In an "impure" function, input X might result in different outputs, depending other parts of the program. Here’s a CodePen comparing pure and impure functions. Check out this article out, too, for more details.

Now, because there’s quite a lot of markup in this single component, we’re going to copy the whole lot into our function. Add the following under your constructor:

render() { let self = this; return ( <main className="about" style={ { background: self.state.color } }> <section className="about__inner"> <article className="about__content"> { self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null } </article> <form className="[ about__form ] [ boilerform ]"> <div> <label className="c-label" htmlFor="name_field">Your name</label> <input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } /> </div> <div> <label className="c-label" htmlFor="color_field">Your favourite color</label> <div className="c-select-field"> <select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field"> { self.availableColors.map((color, index) => { return ( <option key={ index } value={ color.value }>{ color.name }</option> ); })} </select> <span className="c-select-field__decor" aria-hidden="true" role="presentation">▾</span> </div> </div> </form> </section> </main> ); };

You may be thinking something like: “Holy cow, there’s a lot going on here.” Let’s dissect it, so don’t worry about copying code for a bit—I’ll let you know where we’re going to do that again. Let’s just focus on some key bits for now.

In JSX, you need to return a single element, which can have child elements. Because all of our code is wrapped in a <main> tag, we’re all good there. On that <main> tag, you’ll see we have an expression in an attribute, like we covered in Part 2. This expression sets the background color as the current active color that’s set in our state. This will update like magic when a user changes their color choice without us having to write another line of code for it in this render function. Pretty cool, huh?

Inside the <article class="about__content"> element, you’ll notice this:

{ self.state.name ? <p>Hello there. My name is { self.state.name }, and my favourite color is { self.getActiveColorName() }</p> : null }

This ternary operator checks to see if there’s a name set and renders either a sentence containing the name or null. Returning null in JSX is how you tell it to render nothing to the client. Also related to this snippet: we were able to run this ternary operator within our JSX because we created an expression by opening some brackets. It’s a really useful way of sprinkling small, simple bits of display logic within your render function.

Next up, let’s look at an event binding:

<input className="c-input-field" type="text" id="name_field" value={ self.state.name } onChange={ self.updateName.bind(self) } />

If you don’t bind an event to your input field, it’ll be read only. Don’t panic about forgetting though. React helpfully warns you in your console.

Remember, self is equal to this, so what we’re doing is attaching the updateName function to the input’s onChange event, but we’re also binding self, so that when we’re within the updateName function, this will equal AboutMe, which is our component.

The last thing we’re going to look at in the render function is loops. Here’s the snippet that renders the color menu:

<select className="c-select-field__menu" value={ self.state.color } onChange={ self.updateColor.bind(self) } id="color_field"> { self.availableColors.map((color, index) => { return ( <option key={ index } value={ color.value }>{ color.name }</option> ); }) } </select>

The value and change setup is the same as the above <input /> element, so we’ll ignore them and dive straight in to the loop. What we’ve done is open up an expression where we run a pretty standard Array Map function, but, importantly, it returns JSX in each iteration, which allows each option to render with the rest of the JSX.

Wiring it all up

Now that we’ve got our core aspects of the component running, we need to wire it up. You’ll notice that your CodePen isn’t doing anything at the moment. That’s because of two things:

  • We haven’t attached the component to the DOM yet
  • We haven’t written any methods to make it interactive

Let’s start with the former and add our change event handlers. Add the following underneath your constructor function:

updateName(evt) { let self = this; self.setState({ name: evt.target.value }) }; updateColor(evt) { let self = this; self.setState({ color: evt.target.value }) };

These two functions handle the onChange events of the <select> and <input> and set their values in state using React’s setState function. Now that the values are in state, anything that is subscribed to them will update automatically. This means that the ternary statement that renders your name and the background color will change in realtime as you type/select. Awesome. right?

Now, it would be recommended to make your code more DRY by combining these two as one change event handler that updates the relevant state. For this series though, let’s keep things simple and more understandable. &#x1f600;

Next up, let’s add the last method to our component. Add the following under your recently added update methods:

// Return active color name from available colors, based on state value getActiveColorName() { let self = this; return self.availableColors.filter(color => color.value === self.state.color)[0].name; };

This function uses one of my favorite JavaScript array methods: filter. With ES6, we can cherry pick array items based on their object value in one line, which is powerful stuff. With that power, we can pick the currently active availableColors item’s human-readable name and return it back.

JavaScript array methods are very cool and commonly spotted in the React ecosystem. Sarah Drasner made a seriously amazing “Array Explorer”—check it out here! Attaching the component to the DOM

The last thing we’re going to do is attach our component to the DOM, using ReactDOM. What we’re doing is saying, “Hey browser, fetch me the <div id="root"> element and render this React component in it.” ReactDOM is doing all the magic that makes that possible.

ReactDOM is a really smart package that takes changes in your dynamic React components, calculates what needs to be changed in the DOM and applies those changes in the most efficient possible way. With ReactDOM’s renderToString() method, you can also render your React components to a static string, which can then be inserted to your page with your server-side code. What’s smart about this is that references are added so that if your front-end picks up some server-rendered React, it’ll work out which components are needed and make the whole chunk of static markup dynamic automatically. Pretty damn smart, huh?

Anyway, back to our Pen. Add this right at the bottom of your JS editor:

// Attach our component to the <div id="root"> element ReactDOM.render(<AboutMe />, document.getElementById('root'));

Now, you’ll notice that your preview window has suddenly come alive! Congratulations — you just wrote a React component &#x1f389;

See the Pen About Me React Component by Andy Bell (@hankchizlja) on CodePen.

Wrapping up

In this part, you’ve learned about reactive, component JavaScript by writing a React component. This is relevant to your learning because custom Gutenberg blocks follow a very similar setup to a React component. Now that you’ve got a better understanding of how a React component works, you should be able to understand how a custom Gutenberg block works too.

It took me a bit to wrap my mind around the fact that, in terms of Gutenberg, React is only relevant to building blocks within the admin. In Gutenberg, React functions as a means of preparing the markup to be saved to the database in the post_content column. Using React on the front-end of a WordPress site to build something like this would be separate from what we will be doing in this series.

Next up in this series, we’re going to edit our WordPress theme so that we can build our custom Gutenberg block.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax
  5. React 101 (This Post)
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: React 101 appeared first on CSS-Tricks.

Categories: Web Technologies

Learning Gutenberg: Modern JavaScript Syntax

CSS-Tricks - Wed, 05/23/2018 - 07:03

One of the key changes that Gutenberg brings to the WordPress ecosystem is a heavy reliance on JavaScript. Helpfully, the WordPress team have really pushed their JavaScript framework into the present and future by leveraging the modern JavaScript stack, which is commonly referred to as ES6 in the community. It’s how we’ll refer to it as in this series too, to avoid confusion.

Let’s dig into this ES6 world a bit, as it’s ultimately going to help us understand how to structure and build a custom Gutenberg block.

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)
What is ES6?

ES6 is short for “EcmaScript 6” which is the 6th edition of EcmaScript. It’s official name is ES2015, which you may have also seen around. EcmaScript has since gone through many iterations, but modern JavaScript is still often referred to as ES6. As you probably guessed, the iterations have continued ES2016, ES2017 and so-on. I actually asked a question on ShopTalk show about what we could name modern JavaScript, which I the conclusion was... ES6.

I’m going to run through some key features of ES6 that are useful in the context of Gutenberg.

Functions

Functions get a heck of an update with ES6. Two changes I want to focus on are Arrow Functions and Class Methods.

Inside a class you don’t actually need to write the word function anymore in ES6. This can be confusing, so check out this example:

class Foo { // This is your 'bar' function bar() { return 'hello'; } }

You’d invoke bar() like this:

const fooInstance = new Foo(); const hi = fooInstance.bar();

This is commonplace in the land of modern JavaScript, so it’s good to clear it up.

Fun fact! ES6 Classes in JavaScript aren’t really “classes” in an object-oriented programming sense—under the hood, it’s the same old prototypical inheritance JavaScript has always had. Prior to ES6, the bar() method would be defined like so: Foo.prototype.bar = function() { ... }. React makes great use of ES6 classes, but it’s worth noting that ES6 classes are essentially syntactic sugar and hotly contested by some. If you’re interested in more details, checkout the MDN docs and this article on 2ality.

Right, let’s move on to arrow functions. &#x1f680;

An arrow function gives us a compact syntax that is often used as a one-liner for expressions. It’s also used to maintain the value of this, as an arrow function won’t rebind this like setInterval or an event handler would usually do.

An example of an arrow function as an expression is as follows:

// Define an array of fruit objects const fruit = [ { name: 'Apple', color: 'red' }, { name: 'Banana', color: 'yellow' }, { name: 'Pear', color: 'green' } ]; // Select only red fruit from that collection const redFruit = fruit.filter(fruitItem => fruitItem.color === 'red'); // Output should be something like Object { name: "Apple", color: "red" } console.log(redFruit[0]);

As you can see above, because there was a single parameter and the function was being used as an expression, we can redact the brackets and parenthesis. This allows us to really compact our code and improve readability.

Let’s take a look at how we can use an arrow function as an event handler in our Foo class from before:

class Foo { // This is your 'bar' function bar() { let buttonInstance = document.querySelector('button'); buttonInstance.addEventListener('click', evt => { console.log(this); }); } } // Run the handler const fooInstance = new Foo(); fooInstance.bar();

When the button is clicked, the output should be Foo { }, because this is the instance of Foo. If we were to replace that example with the following:

class Foo { // This is your 'bar' function bar() { let buttonInstance = document.querySelector('button'); buttonInstance.addEventListener('click', function(evt) { console.log(this); }); } } // Run the handler const fooInstance = new Foo(); fooInstance.bar();

When the button is clicked, the output would be <button> because the function has bound this to be the <button> that was clicked.

You can read more about arrow functions with Wes Bos, who wrote an excellent article about them.

const, let, and var

You may have noticed that I’ve been using const and let in the above examples. These are also a part of ES6 and I’ll quickly explain what each one does.

If a value is absolutely constant and won’t change through re-assignment, or be re-declared, use a const. This would commonly be used when importing something or declaring non-changing properties such as a collection of DOM elements.

If you have a variable that you want to only be accessible in the block it was defined in, then use a let. This can be confusing to understand, so check out this little example:

function foo() { if (1 < 2) { let bar = 'always true'; // Outputs: 'always true' console.log(bar); } // Outputs 'ReferenceError: bar is not defined' console.log(bar); } // Run the function so we can see our logs foo();

This is a great way to keep control of your variables and make them disposable, in a sense.

Lastly, var is the same old friend we know and love so well. Unfortunately, between const and let, our friend is becoming more and more redundant as time goes on. Using var is totally acceptable though, so don’t be disheartened—you just won’t see it much in the rest of this tutorial!

Destructuring assignment

Destructuring allows you to extract object keys at the point where you assign them to your local variable. So, say you’ve got this object:

const foo = { people: [ { name: 'Bar', age: 30 }, { name: 'Baz', age: 28 } ], anotherKey: 'some stuff', heyAFunction() { return 'Watermelons are really refreshing in the summer' } };

Traditionally, you’d extract people with foo.people. With destructuring, you can do this:

let { people } = foo;

That pulls the people array out of the the foo object, so we can dump the foo. prefix and use it as it is: people. It also means that anotherKey and heyAFunction are ignored, because we don’t need them right now. This is great when you’re working with big complex objects where being able to selectively pick stuff out is really useful.

You can also make use of destructuring to break up an object into local variables to increase code readability. Let’s update the above snippet:

let { people } = foo; let { heyAFunction } = foo;

Now we’ve got those two separate elements from the same object, while still ignoring anotherKey. If you ran console.log(people), it’d show itself an array and if you ran console.log(heyAFunction), you guessed it, it’d show itself as a function.

JSX

Most commonly found in React JS contexts: JSX is an XML-like extension to JavaScript that is designed to be compiled by preprocessors into normal JavaScript code. Essentially, it enables us to write HTML(ish) code within JavaScript, as long as we’re preprocessing it. It’s usually associated with a framework like React JS, but it’s also used for Gutenberg block development.

Let’s kick off with an example:

const hello = <h1 className="heading">Hello, Pal</h1>;

Pretty cool, huh? No templating system or escaping or concatenating required. As long as you return a single element, which can have many children, you’re all good. So let’s show something a touch more complex, with a React render function:

class MyComponent extends React.Component { /* Other parts redacted for brevity */ render() { return ( <article> <h2 className="heading">{ this.props.heading }</h2> <p className="lead">{ this.props.summary }</p> </article> ); } };

You can see above that we can drop expressions in wherever we want. This is also the case with element attributes, so we can have something like this:

<h2 className={ this.props.headingClass }> { this.props.heading } </h2>

You might be thinking, “What are these random braces doing?”

The answer is that this is an expression, which you will see a ton of in JSX. Essentially, it’s a little inline execution of JavaScript that behaves very much like a PHP echo does.

You’ll also probably notice that it says className instead of class. Although it looks like HTML/XML, it’s still JavaScript, so reserved words naturally are avoided. Attributes are camel-cased too, so keep and eye out for that. Here’s a useful answer to why it’s like this.

JSX is really powerful as you’ll see while this series progresses. It’s a great tool in our stack and really useful to understand in general.

I like to think of JSX as made up-tag names that are actually just function calls. Pick out any of the made-up tags you see in Gutenberg, let's use <InspectorControls /> for example, and do a "Find in Folder" for class InspectorControls and you’ll see something structured like Andy’s example here! If you don't find it, then the JSX must be registered as functional component, and should turn up by searching for function InspectorControls. Wrapping up

We’ve had a quick run through some of the useful features of ES6. There’s a ton more to learn, but I wanted to focus your attention on the stuff we’ll be using in this tutorial series. I’d strongly recommend your further your learning with Wes Bos’ courses, JavaScript 30 and ES6.io.

Next up, we’re going to build a mini React component!

Article Series:
  1. Series Introduction
  2. What is Gutenberg, Anyway?
  3. A Primer with create-guten-block
  4. Modern JavaScript Syntax (This Post)
  5. React 101
  6. Setting up a Custom webpack (Coming Soon!)
  7. A Custom "Card" Block (Coming Soon!)

The post Learning Gutenberg: Modern JavaScript Syntax appeared first on CSS-Tricks.

Categories: Web Technologies

RSuite:React UI Component Suite

Echo JS - Wed, 05/23/2018 - 06:24
Categories: Web Technologies

Koa middleware: koa-body-clean

Echo JS - Wed, 05/23/2018 - 06:24
Categories: Web Technologies

Drag and Drop in JavaScript

Echo JS - Wed, 05/23/2018 - 06:24
Categories: Web Technologies

Configuring MySQL in a Docker Container

Planet MySQL - Wed, 05/23/2018 - 06:16

In recent weeks I’ve been focusing on Docker in order to get a much better understanding of the containerized world that is materializing in front of us. Containers aren’t just for stateless applications anymore and we’re seeing more cases where MySQL and other databases are being launched in a containerized fashion, so it’s important to know how to configure your MySQL container!

In docker hub, you will see an option for this by doing a volume mount from the docker host to the container on /etc/mysql/conf.d. But the problem is that the container image you’re using may not have an !includedir referencing the conf.d directory, much like the latest version of mysql community, as you will see below.

[root@centos7-1 ~]# docker run --memory-swappiness=1 --memory=2G -p 3306:3306 --name=mysql1 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:5.7.22 [root@centos7-1 ~]# docker exec -it mysql1 cat /etc/my.cnf | grep -i include [root@centos7-1 ~]#

This means that if you use the prescribed method of placing a config file in /etc/mysql/conf.d in the container, it’s not going to be read and will have no impact on the configuration of the underlying MySQL instance.

You might think that the next step would be to attach to the container, modify the my.cnf file (after installing a text editor) and adding the !includedir in your my.cnf file, but this goes against the docker / containerization philosophy. You should be able to just launch a container with the appropriate arguments and be off to fight the universe’s data battles. So in this case, I would propose the following workaround:

Instead of using /etc/mysql/conf.d, we can look at the mysql option file reference and realize there is more than one place we can put a config file. In fact, it looks like the next place mysql is going to look for configuration is going to be /etc/mysql/my.cnf and if we check our recently deployed container, we’ll see that /etc/mysql isn’t used.

[root@centos7-1 ~]# docker exec -it mysql1 ls /etc/mysql ls: cannot access /etc/mysql: No such file or directory

We can mount a volume with a my.cnf file to this directory on the container and it should pick up whatever configuration we supply, as demonstrated below.

[root@centos7-1 ~]# docker stop mysql1 mysql1 [root@centos7-1 ~]# docker rm mysql1 mysql1 [root@centos7-1 ~]# cat /mysqlcnf/mysql1/my.cnf [mysqld] server-id=123 [root@centos7-1 ~]# docker run --memory-swappiness=1 --memory=2G -p 3306:3306 -v /mysqlcnf/mysql1:/etc/mysql --name=mysql1 -e MYSQL_ROOT_PASSWORD=password -d mysql/mysql-server:5.7.22 d5d980ee01d5b4707f3a7ef5dd30df1d780cdfa35b14ad22ff436fb02560be1b [root@centos7-1 ~]# docker exec -it mysql1 cat /etc/mysql/my.cnf [mysqld] server-id=123 [root@centos7-1 ~]# docker exec -it mysql1 mysql -u root -ppassword -e "show global variables like 'server_id'" mysql: [Warning] Using a password on the command line interface can be insecure. +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 123 | +---------------+-------+ [root@centos7-1 ~]#

Another option for doing this is overriding the my.cnf file in /etc/ with our own version. You can do this with a mount as noted in the mysql reference for Persisting Data and Configuration Changes, but in that case you will be overwriting other items that might be included in the my.cnf as part of the docker build. This may or may not be your intention depending on how you want to deploy your containers.

Conclusion

Be aware of the container image you’re using and what configuration options are available to you. Some forks will include a !includedir reference to /etc/mysql/conf.d, some won’t. You may want to overwrite the entire my.cnf file by volume mounting to a copy of the my.cnf on the docker host. Or you may just want to supplement the configuration with a second configuration file in /etc/mysql. The important things are to test, to make sure your configuration is properly read by the mysql container, and to establish confidence in the configuration method used before deploying in your environment.

Categories: Web Technologies

Happy Birthday MySQL 1995

Planet MySQL - Wed, 05/23/2018 - 05:32
Happy Birthday MySQL  ! Turned 23 today !
Categories: Web Technologies

Interview with Karen Baker - Voices of the ElePHPant

Planet PHP - Wed, 05/23/2018 - 04:30

@wsakaren Audio Show Notes

 

This episode is sponsored by Nexcess.

The post Interview with Karen Baker appeared first on Voices of the ElePHPant.

Categories: Web Technologies

Interview with Karen Baker - Voices of the ElePHPant

Planet PHP - Wed, 05/23/2018 - 04:30

@wsakaren Audio Show Notes

 

This episode is sponsored by Nexcess.

The post Interview with Karen Baker appeared first on Voices of the ElePHPant.

Categories: Web Technologies

Pages