1#!/bin/bash
2#  Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3#
4#  This program is free software; you can redistribute it and/or modify
5#  it under the terms of the GNU General Public License as published by
6#  the Free Software Foundation; version 2 of the License.
7#
8#  This program is distributed in the hope that it will be useful,
9#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#  GNU General Public License for more details.
12#
13#  You should have received a copy of the GNU General Public License
14#  along with this program; if not, write to the Free Software
15#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16
17OS=`uname`
18SYSDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
19GENDIR=$SYSDIR/gen
20PWD=$( pwd )
21
22# Grab the current sys version
23SYSVERSIONTMP=`cat views/version.sql | grep 'AS sys_version' | awk '{print $2}'`
24SYSVERSION=`echo "${SYSVERSIONTMP//\'}"`
25
26MYSQLUSER="'root'@'localhost'"
27
28if [ $OS == "Darwin" ] ;
29then
30  SED_R="sed -E"
31else
32  SED_R="sed -r"
33fi
34
35USAGE="
36Options:
37================
38
39    v: The version of MySQL to build the sys schema for, either '56' or '57'
40
41    b: Whether to omit any lines that deal with sql_log_bin (useful for RDS)
42
43    m: Whether to generate a mysql_install_db / mysqld --initialize formatted file
44
45    u: The user to set as the owner of the objects (useful for RDS)
46
47Examples:
48================
49
50Generate a MySQL 5.7 SQL file that uses the 'mark'@'localhost' user:
51
52    $0 -v 57 -u \"'mark'@'localhost'\"
53
54Generate a MySQL 5.6 SQL file for RDS:
55
56    $0 -v 56 -b -u CURRENT_USER
57
58Generate a MySQL 5.7 initialize / bootstrap file:
59
60    $0 -v 57 -m
61"
62
63# Grab options
64while getopts ":v:bhmu:" opt; do
65  case $opt in
66    b)
67      SKIPBINLOG=true
68      ;;
69    h)
70      echo $"$USAGE"
71      exit 0
72      ;;
73    m)
74      MYSQLCOMPAT=true
75      # Bundled mysql expects the mysql.sys user to be used
76      MYSQLUSER="'mysql.sys'@'localhost'"
77      ;;
78    u)
79      if [ -z "$MYSQLCOMPAT" ] ;
80      then
81        MYSQLUSER="${OPTARG}"
82      fi
83      ;;
84    v)
85      if [ $OPTARG == "56" ] || [ $OPTARG == "57" ] ;
86      then
87        MYSQLVERSION=$OPTARG
88      else
89      	echo "Invalid -v option, please run again with either '-v 56' or '-v 57'"
90      	exit 1
91      fi
92      ;;
93    \?)
94      echo "Invalid option: -$OPTARG" >&2
95      echo $"$USAGE"
96      exit 1
97      ;;
98    :)
99      echo "Option -$OPTARG requires an argument." >&2
100      echo $"$USAGE"
101      exit 1
102      ;;
103  esac
104done
105
106# Check required options
107if [[ -z "$MYSQLVERSION" ]] ;
108then
109  echo "  -v (MySQL Version) parameter required, please run again with either '-v 56' or '-v 57'"
110  echo $"$USAGE"
111  exit 1
112fi
113
114# Create the gen directory
115if [[ ! -d $GENDIR ]] ;
116then
117  mkdir $GENDIR
118fi
119
120# Create output file name
121if [[ ! -z "$MYSQLCOMPAT" ]] ;
122then
123  OUTPUTFILE="mysql_sys_schema.sql"
124else
125  OUTPUTFILE="sys_${SYSVERSION}_${MYSQLVERSION}_inline.sql"
126fi
127
128# Create the initial output file
129if [[ ! -z "$MYSQLCOMPAT" ]] ;
130then
131  # Pre-process all the files in a copied temp directory
132  if [[ ! -d $GENDIR/tmpgen ]] ;
133  then
134    mkdir $GENDIR/tmpgen
135  fi
136  cd $GENDIR/tmpgen
137  rm -rf *
138  cp -r $SYSDIR/after_setup.sql $SYSDIR/tables $SYSDIR/triggers $SYSDIR/functions $SYSDIR/views $SYSDIR/procedures .
139
140  # Switch user if requested
141  # Remove individual copyrights
142  # Replace newlines in COMMENTs with literal \n
143  # Drop added trailing \n <sad panda>
144  # Remove DELIMITER commands
145  # Replace $$ delimiter with ;
146  # Remove leading spaces
147  # Remove -- line comments *after removing leading spaces*
148  for file in `find . -name '*.sql'`; do
149    sed -i -e "s/'root'@'localhost'/$MYSQLUSER/g" $file
150    sed -i -e "/Copyright/,/51 Franklin St/d" $file
151    sed -i -e "/^ *COMMENT/,/^ *'/{G;s/\n/\\\n/g;}" $file
152    sed -i -e "s/            '\\\n/            '/g" $file
153    sed -i -e "/^DELIMITER/d" $file
154    sed -i -e "s/\\$\\$/;/g" $file
155    sed -i -e "s/^ *//g" $file
156    sed -i -e "/^--/d" $file
157  done
158
159  # Start the output file from a non-removed copyright file
160  sed -e "s/^/-- /" $SYSDIR/LICENSE > $OUTPUTFILE
161  echo "" >> $OUTPUTFILE
162  echo "--" >> $OUTPUTFILE
163  echo "-- WARNING: THIS IS A GENERATED FILE, CHANGES NEED TO BE MADE ON THE UPSTREAM MYSQL-SYS REPOSITORY AS WELL" >> $OUTPUTFILE
164  echo "-- PLEASE SUBMIT A PULL REQUEST TO https://github.com/MarkLeith/mysql-sys" >> $OUTPUTFILE
165  echo "--" >> $OUTPUTFILE
166  echo "" >> $OUTPUTFILE
167
168  # Add the expected user
169  # Note this currently only works with 5.7 mysql.user structure
170  echo "REPLACE INTO mysql.user VALUES ('localhost','mysql.sys','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','Y','N','','','','',0,0,0,0,'mysql_native_password','*THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE','N',CURRENT_TIMESTAMP,NULL,'Y');" >> $OUTPUTFILE
171  echo "" >> $OUTPUTFILE
172  echo "REPLACE INTO mysql.tables_priv VALUES ('localhost','sys','mysql.sys','sys_config','root@localhost', CURRENT_TIMESTAMP, 'Select', '');" >> $OUTPUTFILE
173  echo "" >> $OUTPUTFILE
174
175  # Put in the contents of before_setup.sql, though don't collapse lines
176  sed -e "/sql_log_bin/d;s/'root'@'localhost'/$MYSQLUSER/g;/Copyright/,/51 Franklin St/d" $SYSDIR/before_setup.sql >> $OUTPUTFILE
177
178  # Add the rest of the files in install file order, removing new lines along the way
179  cat "$SYSDIR/sys_$MYSQLVERSION.sql" | tr -d '\r' | grep 'SOURCE' | grep -v before_setup | grep -v after_setup | $SED_R 's .{8}  ' | sed 's/^/./' >  "./sys_$MYSQLVERSION.sql"
180  while read file; do
181      # First try and get a DROP command
182      grep -E '(^DROP PROCEDURE|^DROP FUNCTION|^DROP TRIGGER)' $file >> $OUTPUTFILE
183      # And remove any that may exist (but keep DROP TEMPORARY TABLE)
184      sed -i -e "/^DROP PROCEDURE/d;/^DROP FUNCTION/d;/^DROP TRIGGER/d" $file
185      echo "" >> $OUTPUTFILE
186      # Then collapse the rest of the file
187      cat $file | tr '\n' ' ' >> $OUTPUTFILE
188      echo "" >> $OUTPUTFILE
189      echo "" >> $OUTPUTFILE
190  done < "./sys_$MYSQLVERSION.sql"
191
192  # Does essentially nothing right now, but may in future
193  sed -e "/Copyright/,/51 Franklin St/d;/sql_log_bin/d" $SYSDIR/after_setup.sql >> $OUTPUTFILE
194
195  # Remove final leading and trailing spaces
196  sed -i '' -e "s/^ *//g" $OUTPUTFILE
197  sed -i '' -e "s/[ \t]*$//g" $OUTPUTFILE
198  # Remove more than one empty line
199  sed -i '' -e "/^$/N;/^\n$/D" $OUTPUTFILE
200
201  mv $OUTPUTFILE $GENDIR/
202  cd $GENDIR/
203  rm -rf $GENDIR/tmpgen
204else
205  sed -e "s/^/-- /" $SYSDIR/LICENSE > $GENDIR/$OUTPUTFILE
206  cat "$SYSDIR/sys_$MYSQLVERSION.sql" | tr -d '\r' | grep 'SOURCE' | $SED_R 's .{8}  ' | sed "s/^/$(echo $SYSDIR | sed -e 's/[]\/$*.^|[]/\\&/g')/g" \
207    | xargs sed -e "/Copyright/,/51 Franklin St/d;s/'root'@'localhost'/$MYSQLUSER/g" >> $GENDIR/$OUTPUTFILE
208fi
209
210# Check if sql_log_bin lines should be removed
211if [[ ! -z "$SKIPBINLOG" ]] ;
212then
213  LOGWARNING="WARNING: Using a routine that could cause binary log events, but disabling of binary logging has been removed"
214  sed -i '' -e "s/^[ \s]*SET sql_log_bin = 0/SELECT \"$LOGWARNING\"/g" $GENDIR/$OUTPUTFILE
215  sed -i '' -e "s/\sSET sql_log_bin = @log_bin;/SET @log_bin = NULL;/g" $GENDIR/$OUTPUTFILE
216  SKIPBINLOG="disabled"
217else
218  SKIPBINLOG="enabled"
219fi
220
221cd $PWD
222
223# Print summary
224echo $"
225    Wrote file: $GENDIR/$OUTPUTFILE
226Object Definer: $MYSQLUSER
227   sql_log_bin: $SKIPBINLOG
228 "
229