https://getcomposer.org/apidoc/master/index.html
https://getcomposer.org/doc/03-cli.md
composer outdated 'drupal/*'
composer prohibits symfony/console 3.3.5
composer require 'drupal/jsonapi:^1.23'
==================================================================================
https://www.codeenigma.com/build/blog/do-you-really-need-composer-production
Do you really need composer in production?
It is now a common practice to use composer as part of the deployment stack. Is this always such a good idea?
Photo of Pascal Morin
Tue, 2017-03-21 16:26
By pascal
The recipe goes like this : gitignore your "vendor" directory (or whatever folder your dependencies end up in), but commit your composer.lock file, then deploy. Your CI job will then « composer install » all the dependencies where there belong to, magically reproducing your initial files layout exactly how they were.
There are generally a few additional steps involved in between though. Typically, you lost half a day figuring out the right file permissions so that the var/cache of your app can be cleared and recreated properly by the webserver user, wondered for days why some of the builds were randomly failing before realizing that no token was set in this given job, meaning github API rate limit was sometime hit. Then another good day or two finding out how to apply two patches for the same projects when they slightly conflict. And your sysadmin might be slightly suspicious about those files being downloaded and executed directly on production outside of any VCS, and anxiously watching for exploit reports.
Now, you will assure me, you’ve nailed all that, and, apart from an occasional network glitch preventing packages to be fetched, all is running smoothly. Great.
But please, re-read above. Why are you doing all this? To "reproduce your initial files layout exactly how they were". Then why don’t you just commit the files and push them, then?
That is normally the point in the discussion when you’re supposed to use the words « reproducible » and « best practices ».
Reproducible
Right, but what is more reproducible than moving prebuilt files around? You played the recipe once already on your dev environment, taking the risk of re-running it on production feels a bit like recompiling binaries from source simply because you can.
Composer is not magic. What it does is grab a bunch of PHP files, ensuring they are at the right version and that they end up in the right place, so they can play nicely together. Once you have the resulting file set already, why would you want to redo this over and over on each and every environment?
Best practices
Let’s have a closer looks at what is stated in the Composer documentation and the reasons why the project recommends not committing your dependencies:
large VCS repository size and diffs when you update code;
duplication of the history of all your dependencies in your own VCS; and
adding dependencies installed via git to a git repo will show them as submodules.
I’ll just ignore the repository size (because, frankly ?) and focus on the diff and history parts.
For one, the argument here is slightly misleading: reading the statement, you might be under the impression your repository will contain the whole git history of each and every dependency in your project. Nope, it will not. What you will end up with, along the life of your project, is the history of updates to your dependencies after your initial commit.
Which is rather the most important point here. This is a good thing! Why would not you want to be able to look at - and keep track of in your VCS - what was in update from Guzzle 3.8.0 to 3.8.1 or what difference there is between ctools 8.x-3.0-alpha27 and alpha26? Your « live » project is not only your custom code.
What would you find most useful, next time your client opens a ticket because the image embedding in the WYSIWYG editor has stopped working since the last release, when looking back at the commit « Upgrade contrib module media_entity from 8.x-1.5 to 8.x-1.6 » ? Seeing a one line hash change in composer.lock, or seeing a nice diff of the actual changes in code, so you can track down what went wrong?
The .git submodules point is fair, but easy to workaround, as explained on this very same best practices page. Also keep in mind it only applies if you use dev versions or obscure non-packaged dependencies.
So, to sum it up, if you use Composer to build your code in production, you get:
- Un-needed and time consuming deployment complexity increase, with small but real risks of failure on each and every build for external cause
- No auditing of changes that are not your own custom code
+ Easier handling of .git « false » submodules for a few dev dependencies
On the other hand, if you commit the "vendor" directory, you get:
+ Easier and straightforward deployment
+ All code that lands on production gets audited/versioned
- Small amount of work involved in dealing with possible .git « false » submodules
Then why ?
But then, why is that such a widespread practice? I can only guess here, but I suspect there are several factors at play:
Fashion, to some extent, must play a role. There are very good reasons to do this for certain workflows, which may lead people to think that it can apply to any deployment workflow.
The fact that it is presented as « best practice » on the Composer project page. Many people apply it without questioning whether it is applicable to their use case.
My interpretation is that, more fundamentally, the root cause is confusion between "deploying" code and "distributing" code.
Moving a « living thing » for one environment over to another environment is not the same process as making a component or app available for other projects to reuse and build upon. Composer is a fantastic building tool, it is great for the latter case, and using it to assemble your project totally makes sense. Using it as a deployment tool, less so.
If we take another look at the arguments above from a distribution perspective, the analysis is totally different:
Large VCS repository size and diffs when you update code.
Duplication of the history of all your dependencies in your own VCS.
Indeed, in this use case, it all makes total sense: you definitively do not need the whole git history of any component you are re-using for your project. Nor do you want your repo for the nice web-crawler library you contribute on GitHub to contain the Guzzle codebase you depend upon.
In short, think about the usage. If you maintain, say, a Drupal custom distro that you use internally as a starting point for your projects, by all means yes, ignore the vendor directory. Build it with Composer when you use it to start a new project. And continue to use Composer to manage dependencies updates in your dev environment. However, once this is no longer a re-usable component, but instead a living project that will need to be deployed from environment to environment, do yourself a favour and consider carefully whether using Composer to deploy really brings any benefit.
MySQL
===============
Getting started:
- http://www.sqlteaching.com/
- https://www.codecademy.com/courses/learn-sql
Related tutorials:
- [MySQL-CLI](https://www.youtube.com/playlist?list=PLfdtiltiRHWEw4-kRrh1ZZy_3OcQxTn7P)
- [Analyzing Business Metrics](https://www.codecademy.com/learn/sql-analyzing-business-metrics)
- [SQL joins infografic](https://lh4.googleusercontent.com/-RdjzcoAwBYg/UxTXWGJHgoI/AAAAAAAACrs/Gqbu6zyksgo/w852-h670/sql-joins.jpg)
Tools:
- [DataGrip](https://www.jetbrains.com/datagrip/)
- [Sequel Pro](http://www.sequelpro.com/)
Commands
-----------
Access monitor: `mysql -u [username] -p;` (will prompt for password)
Show all databases: `show databases;`
Access database: `mysql -u [username] -p [database]` (will prompt for password)
Create new database: `create database [database];`
Select database: `use [database];`
Determine what database is in use: `select database();`
Show all tables: `show tables;`
Show table structure: `describe [table];`
List all indexes on a table: `show index from [table];`
Create new table with columns: `CREATE TABLE [table] ([column] VARCHAR(120), [another-column] DATETIME);`
Adding a column: `ALTER TABLE [table] ADD COLUMN [column] VARCHAR(120);`
Adding a column with an unique, auto-incrementing ID: `ALTER TABLE [table] ADD COLUMN [column] int NOT NULL AUTO_INCREMENT PRIMARY KEY;`
Inserting a record: `INSERT INTO [table] ([column], [column]) VALUES ('[value]', [value]');`
MySQL function for datetime input: `NOW()`
Selecting records: `SELECT * FROM [table];`
Explain records: `EXPLAIN SELECT * FROM [table];`
Selecting parts of records: `SELECT [column], [another-column] FROM [table];`
Counting records: `SELECT COUNT([column]) FROM [table];`
Counting and selecting grouped records: `SELECT *, (SELECT COUNT([column]) FROM [table]) AS count FROM [table] GROUP BY [column];`
Selecting specific records: `SELECT * FROM [table] WHERE [column] = [value];` (Selectors: `<`, `>`, `!=`; combine multiple selectors with `AND`, `OR`)
Select records containing `[value]`: `SELECT * FROM [table] WHERE [column] LIKE '%[value]%';`
Select records starting with `[value]`: `SELECT * FROM [table] WHERE [column] LIKE '[value]%';`
Select records starting with `val` and ending with `ue`: `SELECT * FROM [table] WHERE [column] LIKE '[val_ue]';`
Select a range: `SELECT * FROM [table] WHERE [column] BETWEEN [value1] and [value2];`
Select with custom order and only limit: `SELECT * FROM [table] WHERE [column] ORDER BY [column] ASC LIMIT [value];` (Order: `DESC`, `ASC`)
Updating records: `UPDATE [table] SET [column] = '[updated-value]' WHERE [column] = [value];`
Deleting records: `DELETE FROM [table] WHERE [column] = [value];`
Delete *all records* from a table (without dropping the table itself): `DELETE FROM [table];`
(This also resets the incrementing counter for auto generated columns like an id column.)
Delete all records in a table: `truncate table [table];`
Removing table columns: `ALTER TABLE [table] DROP COLUMN [column];`
Deleting tables: `DROP TABLE [table];`
Deleting databases: `DROP DATABASE [database];`
Custom column output names: `SELECT [column] AS [custom-column] FROM [table];`
Export a database dump (more info [here](http://stackoverflow.com/a/21091197/1815847)): `mysqldump -u [username] -p [database] > db_backup.sql`
Use `--lock-tables=false` option for locked tables (more info [here](http://stackoverflow.com/a/104628/1815847)).
Import a database dump (more info [here](http://stackoverflow.com/a/21091197/1815847)): `mysql -u [username] -p -h localhost [database] < db_backup.sql`
Logout: `exit;`
Aggregate functions
-----------
Select but without duplicates: `SELECT distinct name, email, acception FROM owners WHERE acception = 1 AND date >= 2015-01-01 00:00:00`
Calculate total number of records: `SELECT SUM([column]) FROM [table];`
Count total number of `[column]` and group by `[category-column]`: `SELECT [category-column], SUM([column]) FROM [table] GROUP BY [category-column];`
Get largest value in `[column]`: `SELECT MAX([column]) FROM [table];`
Get smallest value: `SELECT MIN([column]) FROM [table];`
Get average value: `SELECT AVG([column]) FROM [table];`
Get rounded average value and group by `[category-column]`: `SELECT [category-column], ROUND(AVG([column]), 2) FROM [table] GROUP BY [category-column];`
Multiple tables
-----------
Select from multiple tables: `SELECT [table1].[column], [table1].[another-column], [table2].[column] FROM [table1], [table2];`
Combine rows from different tables: `SELECT * FROM [table1] INNER JOIN [table2] ON [table1].[column] = [table2].[column];`
Combine rows from different tables but do not require the join condition: `SELECT * FROM [table1] LEFT OUTER JOIN [table2] ON [table1].[column] = [table2].[column];` (The left table is the first table that appears in the statement.)
Rename column or table using an _alias_: `SELECT [table1].[column] AS '[value]', [table2].[column] AS '[value]' FROM [table1], [table2];`
Users functions
-----------
List all users: `SELECT User,Host FROM mysql.user;`
Create new user: `CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';`
Grant `ALL` access to user for `*` tables: `GRANT ALL ON database.* TO 'user'@'localhost';`
Find out the IP Address of the Mysql Host
-----------
`SHOW VARIABLES WHERE Variable_name = 'hostname';` ([source](http://serverfault.com/a/129646))