Skip to content

Commit 9a43bea

Browse files
committed
Thin DB export & Install Drupal commands
1 parent 9a481ec commit 9a43bea

File tree

2 files changed

+369
-8
lines changed

2 files changed

+369
-8
lines changed

commands/host/install-drupal

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,52 @@
11
#!/bin/bash
2-
## #ddev-generated
32

4-
set -euo pipefail # Exit on errors and undefined variables
3+
## #ddev-generated
4+
# Exit on errors and undefined variables
5+
set -euo pipefail
56

67
## Description: Install Drupal using existing configuration
78
## Usage: install-drupal
89

910
echo "🛠️ Installing Drupal..."
10-
# Creating this directory so we can clear cache.
11-
mkdir -p docroot/sites/default/files/addtoany/menu
1211

1312
echo "📥 Importing Database..."
14-
ddev import-db --file=./backups/thin-db.sql.gz
15-
ddev drush cr
1613

14+
# Check if the database file exists
15+
if [ "${IS_CI:-false}" = "TRUE" ]; then
16+
echo "Running in CI environment"
17+
ddev drush sql-drop -y
18+
ddev import-db --file=./backups/thin-db.sql.gz
19+
ddev drush cr
20+
else
21+
if [ -d ./backups ]; then
22+
ddev drush sql-drop -y
23+
# Find all .sql.gz files in the backups directory
24+
mapfile -t db_files < <(find ./backups -maxdepth 1 -type f -name "*.sql.gz")
25+
if [ ${#db_files[@]} -eq 0 ]; then
26+
echo "📥 No database backup files found!"
27+
exit 1
28+
elif [ ${#db_files[@]} -eq 1 ]; then
29+
selected_db="${db_files[0]}"
30+
echo "📥 Found one backup: $selected_db"
31+
else
32+
echo "Multiple database backups found:"
33+
select selected_db in "${db_files[@]}"; do
34+
if [ -n "$selected_db" ]; then
35+
break
36+
else
37+
echo "Invalid selection."
38+
fi
39+
done
40+
fi
41+
ddev import-db --file="$selected_db"
42+
ddev drush cr
43+
else
44+
echo "📥 Database backup not found!"
45+
exit 1
46+
fi
47+
fi
1748
echo "📦 Updating Database..."
18-
ddev drush updb
19-
ddev drush cr
49+
ddev drush updb -y
2050

2151
echo "⚙️ Importing Configuration..."
2252
ddev drush cim -y

commands/web/thin-db-export

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
#!/bin/bash
2+
set -euo pipefail # Exit on errors and undefined variables
3+
4+
# --------------------------
5+
# Start timer
6+
# --------------------------
7+
start_time=$(date +%s)
8+
9+
# --------------------------
10+
# CI Environment or Local excecution
11+
# --------------------------
12+
if [ "${IS_CI:-false}" = "TRUE" ]; then
13+
echo "Running in CI environment"
14+
else
15+
# --------------------------
16+
# Choose operating mode
17+
# --------------------------
18+
echo "How do you want to proceed?"
19+
echo " [1] Create a copy and make changes on that (safe mode)"
20+
echo " [2] Make changes to the existing database"
21+
read -p "Enter your choice [1]: " mode_choice
22+
23+
# Default to safe mode (1) if user enters nothing
24+
mode_choice=${mode_choice:-1}
25+
26+
if [ "$mode_choice" != "1" ] && [ "$mode_choice" != "2" ]; then
27+
echo "❌ Invalid choice. Aborting."
28+
exit 1
29+
fi
30+
31+
# If user chooses to modify existing database, ask for confirmation
32+
if [ "$mode_choice" = "2" ]; then
33+
echo
34+
echo "⚠️ WARNING: This will delete all content in the default database! ⚠️"
35+
echo "⏳ Press Ctrl+C to cancel if you do not wish to proceed."
36+
echo
37+
read -p "🔑 Type 'I Agree' to continue: " user_input
38+
39+
if [ "$user_input" != "I Agree" ]; then
40+
echo "❌ Incorrect agreement. Aborting."
41+
exit 1
42+
fi
43+
fi
44+
45+
# --------------------------
46+
# Configuration
47+
# --------------------------
48+
DB_FILE="thin-db.sql"
49+
WORKDIR="/var/www/html" # DDEV web container's docroot
50+
51+
# Define patterns for tables to truncate
52+
TRUNCATE_PATTERNS=(
53+
"^node"
54+
"^media"
55+
"^taxonomy_term"
56+
"^feeds"
57+
"^path_alias"
58+
"^content_moderation"
59+
"^crop"
60+
"^cache_"
61+
"^redirect"
62+
"file_managed$"
63+
"s3fs_file$"
64+
"search_api_item$"
65+
"admin_audit_trail$"
66+
"taxonomy_index$"
67+
"file_usage$"
68+
"simple_sitemap$"
69+
"batch$"
70+
)
71+
72+
# Get original database details
73+
ORIGINAL_DB=$(drush sql:connect --database=default | sed -n 's/.*--database=\([^ ]*\).*/\1/p')
74+
DRUSH_ARGS=""
75+
76+
if [ "$mode_choice" = "1" ]; then
77+
# Create a copy of the database using DDEV's mysql command
78+
TARGET_DB="${ORIGINAL_DB}_thin"
79+
echo "Creating working copy of database..."
80+
81+
# Add db_copy configuration to settings.ddev.php
82+
SETTINGS_FILE="docroot/sites/default/settings.ddev.php"
83+
DB_COPY_CONFIG=$(cat <<EOF
84+
85+
// Automatically added by thin-db-export script - START
86+
\$databases['${TARGET_DB}']['default'] = [
87+
'database' => '${TARGET_DB}',
88+
'username' => 'db',
89+
'password' => 'db',
90+
'host' => 'db',
91+
'port' => '3306',
92+
'driver' => 'mysql',
93+
];
94+
// Automatically added by thin-db-export script - END
95+
EOF
96+
)
97+
98+
# Backup original file and append configuration
99+
if [ -f "$SETTINGS_FILE" ]; then
100+
cp "$SETTINGS_FILE" "${SETTINGS_FILE}.bak"
101+
echo "$DB_COPY_CONFIG" >> "$SETTINGS_FILE"
102+
echo "✅ Added ${TARGET_DB} configuration to settings.ddev.php"
103+
else
104+
echo "❌ Error: settings.ddev.php not found!"
105+
exit 5
106+
fi
107+
108+
# Create temporary SQL file for database creation
109+
TEMP_SQL="/tmp/create_db.sql"
110+
echo "DROP DATABASE IF EXISTS ${TARGET_DB}; CREATE DATABASE ${TARGET_DB};" > "$TEMP_SQL"
111+
112+
# Use mysql root user to create the database
113+
mysql -uroot -proot < "$TEMP_SQL"
114+
rm "$TEMP_SQL"
115+
116+
# Grant privileges to the 'db' user
117+
mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON ${TARGET_DB}.* TO 'db'@'%';"
118+
119+
# Copy the complete structure first
120+
echo "Copying database structure..."
121+
STRUCTURE_FILE="/tmp/db_structure.sql"
122+
drush sql:dump \
123+
--extra="--skip-comments --skip-dump-date --no-data" \
124+
--result-file="$STRUCTURE_FILE"
125+
126+
# Import the structure to the new database
127+
drush sql:query --database="${TARGET_DB}" --file="$STRUCTURE_FILE"
128+
rm -f "$STRUCTURE_FILE"
129+
130+
# Copy only the essential data (excluding content tables)
131+
echo "Copying essential data..."
132+
133+
# Disable foreign key checks for data copy
134+
drush sql:query --database="${TARGET_DB}" "SET FOREIGN_KEY_CHECKS=0;"
135+
136+
# First handle users and related tables in the correct order
137+
CORE_TABLES=(
138+
"users"
139+
"users_field_data"
140+
"user__roles"
141+
"user__user_picture"
142+
"user__field_pending_expire_sent"
143+
"user__field_password_expiration"
144+
)
145+
146+
for table in "${CORE_TABLES[@]}"; do
147+
echo "Copying core table: $table"
148+
drush sql:query --database="${TARGET_DB}" "TRUNCATE TABLE \`${table}\`;"
149+
drush sql:query "REPLACE INTO ${TARGET_DB}.$table SELECT * FROM ${ORIGINAL_DB}.$table"
150+
done
151+
152+
# Then copy remaining tables
153+
TABLES_TO_COPY=$(drush sql:query "
154+
SELECT TABLE_NAME
155+
FROM information_schema.TABLES
156+
WHERE TABLE_SCHEMA = '${ORIGINAL_DB}'
157+
AND TABLE_NAME NOT REGEXP '^(node|media|taxonomy_term|feeds|path_alias|content_moderation|crop|cache|redirect)'
158+
AND TABLE_NAME NOT IN (
159+
'file_managed', 's3fs_file', 'search_api_item', 'admin_audit_trail',
160+
'taxonomy_index', 'file_usage', 'simple_sitemap', 'batch',
161+
'users', 'users_field_data', 'user__roles', 'user__user_picture',
162+
'user__field_pending_expire_sent', 'user__field_password_expiration'
163+
)
164+
")
165+
166+
for table in $TABLES_TO_COPY; do
167+
echo "Copying table: $table"
168+
drush sql:query --database="${TARGET_DB}" "TRUNCATE TABLE \`${table}\`;"
169+
drush sql:query "INSERT INTO ${TARGET_DB}.$table SELECT * FROM ${ORIGINAL_DB}.$table"
170+
done
171+
172+
# Re-enable foreign key checks
173+
drush sql:query --database="${TARGET_DB}" "SET FOREIGN_KEY_CHECKS=1;"
174+
175+
DRUSH_ARGS="--database=${TARGET_DB}"
176+
echo "✅ Database copy created successfully."
177+
fi
178+
179+
# --------------------------
180+
# Delete All Content
181+
# --------------------------
182+
echo "🗑️ Deleting all content..."
183+
184+
# Disable foreign key checks
185+
drush sql:query $DRUSH_ARGS "SET FOREIGN_KEY_CHECKS=0;"
186+
187+
# Get the target database name based on mode
188+
DB_NAME=$([ "$mode_choice" = "1" ] && echo "$TARGET_DB" || echo "$ORIGINAL_DB")
189+
190+
# Truncate tables using improved pattern matching
191+
for pattern in "${TRUNCATE_PATTERNS[@]}"; do
192+
echo "Truncating tables matching: ${pattern}"
193+
drush sql:query $DRUSH_ARGS "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '${DB_NAME}' AND TABLE_NAME REGEXP '${pattern}'" \
194+
| grep -v '^TABLE_NAME$' \
195+
| while read -r table; do
196+
[ -z "${table}" ] && continue
197+
echo "Truncating ${table}"
198+
drush sql:query $DRUSH_ARGS "TRUNCATE TABLE \`${table}\`;"
199+
done
200+
done
201+
202+
# --------------------------
203+
# Additional Cleanup
204+
# --------------------------
205+
echo "🧹 Cleaning rebuildable data..."
206+
drush sql:query $DRUSH_ARGS "
207+
TRUNCATE cachetags;
208+
TRUNCATE cache_entity;
209+
TRUNCATE cache_menu;
210+
TRUNCATE cache_render;
211+
TRUNCATE cache_data;
212+
DELETE FROM key_value WHERE collection IN (
213+
'pathauto_state.media',
214+
'pathauto_state.node',
215+
'pathauto_state.taxonomy_term',
216+
'pathauto_state.user'
217+
);
218+
"
219+
220+
# Re-enable foreign key checks
221+
drush sql:query $DRUSH_ARGS "SET FOREIGN_KEY_CHECKS=1;"
222+
223+
# --------------------------
224+
# Sanitize Users
225+
# --------------------------
226+
echo "👤 Deleting users..."
227+
drush sql:query $DRUSH_ARGS "
228+
DELETE FROM users_field_data WHERE uid != 1;
229+
DELETE FROM users WHERE uid != 1;
230+
DELETE FROM user__roles WHERE entity_id != 1;
231+
DELETE FROM user__user_picture WHERE entity_id != 1;
232+
DELETE FROM user__field_pending_expire_sent WHERE entity_id != 1;
233+
DELETE FROM user__field_password_expiration WHERE entity_id != 1;
234+
"
235+
236+
# --------------------------
237+
# Export Database
238+
# --------------------------
239+
echo "📦 Exporting database..."
240+
241+
# Generate precise exclusion list
242+
EXCLUDED_TABLES=$(drush sql:query $DRUSH_ARGS "
243+
SELECT GROUP_CONCAT(TABLE_NAME SEPARATOR ',')
244+
FROM information_schema.TABLES
245+
WHERE TABLE_SCHEMA = '${DB_NAME}'
246+
AND TABLE_NAME IN (
247+
'node',
248+
'node_field_data',
249+
'node__body',
250+
'media',
251+
'taxonomy_term_data',
252+
'taxonomy_term_field_data',
253+
'feeds_feed',
254+
'path_alias',
255+
'content_moderation_state',
256+
'crop',
257+
'cache',
258+
'cache_bootstrap',
259+
'cache_config',
260+
'cache_container',
261+
'cache_data',
262+
'cache_default',
263+
'cache_discovery',
264+
'cache_dynamic_page_cache',
265+
'cache_entity',
266+
'cache_menu',
267+
'cache_render',
268+
'cache_toolbar',
269+
'redirect',
270+
'file_managed',
271+
's3fs_file',
272+
'search_api_item',
273+
'admin_audit_trail',
274+
'taxonomy_index',
275+
'file_usage',
276+
'simple_sitemap',
277+
'batch'
278+
)
279+
")
280+
281+
drush sql:dump $DRUSH_ARGS \
282+
--structure-tables-list="${EXCLUDED_TABLES}" \
283+
--ordered-dump \
284+
--extra="--skip-comments --skip-dump-date --single-transaction --no-tablespaces" \
285+
--result-file="${WORKDIR}/${DB_FILE}"
286+
287+
# --------------------------
288+
# Compress and Verify
289+
# --------------------------
290+
echo "🗜️ Compressing..."
291+
cd "${WORKDIR}"
292+
gzip -9 "${DB_FILE}"
293+
294+
mkdir -p "${WORKDIR}/backups/"
295+
mv "${DB_FILE}.gz" "${WORKDIR}/backups/"
296+
297+
echo "✅ Done! Final file: ${WORKDIR}/backups/${DB_FILE}.gz"
298+
echo "File size: $(du -h ${WORKDIR}/backups/${DB_FILE}.gz | cut -f1)"
299+
300+
# Cleanup
301+
if [ "$mode_choice" = "1" ]; then
302+
echo "Cleaning up..."
303+
304+
# Remove database configuration from settings.ddev.php
305+
SETTINGS_FILE="docroot/sites/default/settings.ddev.php"
306+
if [ -f "$SETTINGS_FILE" ]; then
307+
# Use sed to delete the added block
308+
sed -i '/\/\/ Automatically added by thin-db-export script - START/,/\/\/ Automatically added by thin-db-export script - END/d' "$SETTINGS_FILE"
309+
310+
# Remove backup file
311+
rm -f "${SETTINGS_FILE}.bak"
312+
313+
echo "✅ Removed ${TARGET_DB} configuration from settings.ddev.php"
314+
else
315+
echo "⚠️ settings.ddev.php not found during cleanup"
316+
fi
317+
318+
# Drop the temporary database
319+
echo "Cleaning up temporary database..."
320+
drush sql:query "DROP DATABASE ${TARGET_DB}"
321+
fi
322+
323+
fi
324+
325+
# --------------------------
326+
# End timer and report duration
327+
# --------------------------
328+
end_time=$(date +%s)
329+
duration=$((end_time - start_time))
330+
331+
echo "Completed in ${duration} seconds"

0 commit comments

Comments
 (0)