Με προσοχή το hydrate σε queries με joins

php logo

Το laravel είναι ωραιότατο! Βάζει μια τάξη στην άναρχη PHP, της δίνει έναν αέρα από ASP.NET με MVC, χωρίς όμως το γνωστό βαρύ περίβλημα. Παραμένουμε δηλαδή στην PHP, γιατί είναι γρήγορη και δυναμική, δομώντας την όμως καθαρά και σωστά άλα laravel. Αυτά όμως τα ξέρετε και δεν είναι επί του παρόντος. Θα ξέρετε ακόμα και ότι το laravel είναι αυτό που είναι χάρη στο eloquent, το συμπαθητικό ORM, της ίδιας ακριβώς ιδιοσυγκρασίας με το laravel. Έχει όμως και τα τερτίπια του. Και ειδικά όταν η ΒΔ μεγαλώνει, τα πράγματα περιπλέκουν, τα queries απαιτούν πολλά join και το eloquent στενάζει. Ή πιο σωστά ο προγραμματιστής στενάζει προσπαθώντας να απεικονίσει με eloquent αυτό που τόσα χρόνια έκανε με τρεις γραμμές sql. Και γιατί όχι λέει ο Τaylor! Γράψτο όπως ξέρεις και ενυδάτωσέ το!

Λογοπαίγνιο για το hydrate ήταν αυτό, ένα παράδειγμα πάντα βοηθάει:

$result = \DB::table('users')->take(2)->get();
$users = \App\User::hydrate($result); 

Και για τα πιο hardcore τυπάκια, χωρίς table, με ξερό select:

$result = \DB::select('select * from users limit 2 ')->get();
$users = \App\User::hydrate($result); 

Τι κάναμε; Στην πρώτη γραμμή, με ένα ξερό select, η PHP μας γυρνάει ένα γενικού τύπου collection. Στη δεύτερη, χάρη στο hydrate, το αγνώστου τύπου collection παίρνει σάρκα και οστά και γίνεται collection του model User!

Και φυσικά, για ένα τόσο απλό παράδειγμα, δεν έχει νόημα!

Θα μπορούσαμε να πετύχουμε ακριβώς τα ίδια με μια γραμμή eloquent, χωρίς ίχνος sql!

Tα ωραία κόλπα μας θα αρχίσουν με τα join στους ρόλους, στους people και όπου αλλού λαχταράει η ψυχή σας για join. Ειδικά μάλιστα αν είναι αποφύγουμε τα ιδιάζοντα whereHas, whereIn, wherePivot, whereSomethingNew… και να χρησιμοποιήσουμε κάτι πιο οικείο, αυτό που ξέρουμε από τη δεκαετία του ενενήντα: S.Q.L. χωρίς να σπάσουμε το κεφάλι μας για το πως γίνεται το καθετί.

Μην ξεχάσετε όμως στο τέλος να ενυδατώσετε το ξερό query.

$result = \DB::select('select * from users inner join roles on users.role_id = roles.id where roles.type="admin" ')->get();
$users = \App\User::hydrate($result); 

Πως σας φαίνεται το παραπάνω; Ωραιότατο! Δεν θα ήθελα ούτε καν να σκεφτώ πως πρέπει να το συντάξω με eloquent. Αυτό το παραπάνω querάκι μου βγήκε έτσι, αυθόρμητα, χωρίς πολλά-πολλά, σαν να γράφω τη λίστα με τα ψώνια.

Προσοχή όμως γιατί κρύβεται κάτι σατανικό – κάτι που μόνο ένα δίωρο debugging θα το αποκαλύψει, ή εγώ ευθύς αμέσως:

Τι γίνεται αν users και roles έχουν πεδία με ίδια ονόματα – πχ. κλειδάκι με όνομα id; Τι θα κάνει το hydrate σε αυτή την περίπτωση; Θα τα σκατώσει! Και καλά θα κάνει, δεν θα φταίει αυτό! Εμείς φταίμε που δεν ορίσαμε με σαφήνεια τι θα ενυδατωθεί! Ζητήσαμε να ενυδατωθεί το αστεράκι (*) συνεπώς δεν αποκλείεται το hydrate να βάλει στον χρήστη το id του ρόλου!

Ποια είναι η λύση;

Η αποσαφήνιση του αστερίσκου. Πολλά λόγια δεν χρειάζονται. Δείτε παρακάτω και θα καταλάβετε:

$result = \DB::select('select users.* from users inner join roles on users.role_id = roles.id where roles.type="admin" ')->get();
$users = \App\User::hydrate($result); 

Έτσι αποφεύγουμε τις κακοτοπιές, δηλώνουμε ρητά ότι είναι τα πεδία του πίνακα users που θα γίνουν map με το model User!

debian: αναβάθμιση από την 8 (Jessie) στην 9 (Stretch)

Debian Open Logo

Αναβάθμιση του debian από την 8 (Jessie) στην 9 (Stretch)

Το δοκιμάσαμε σε ένα Dell δεκαετίας (!) και όλα πήγαν μια χαρά κι έτσι μεταφέρουμε την εμπειρία μας, για το πως πάμε από την Jessie στην Stretch. Τι πετύχαμε; Να έχουμε στη διάθεσή μας φρέσκο σύστημα με ενημερωμένο kernel και το δυνατόν νεότερο λογισμικό – για τα δεδομένα του debian δηλαδή!3

Θέλετε κι εσείς; Διαβάστε τον οδηγό που ακολουθεί.

Βιάζεστε;

Αν βιάζεστε τόσο πολύ, έχετε ήδη πάρει backup, ξέρετε τι πάτε να κάνετε και απλά δεν θυμάστε τον τρόπο παραθέτουμε τα βήματα εδώ:

  • Πάρτε backup (ή snapshot)
  • Ενημερώστε το σύστημά σας
    • # apt-get update
    • # apt-get upgrade
    • # apt-get dist-upgrade
  • Ενημερώστε το sources.list, αντικαθιστώντας τη λεξούλα jessie με την λεξούλα stretch.
  • Αναβαθμίστε
    • # apt-get update
    • # apt-get upgrade
    • # apt-get dist-upgrade

Γιατί να αναβαθμίσετε;

Φρέσκο λογισμικό, ασφαλές και σταθερό.

Πιο συγκεκριμένα, διαβάζουμε στο debian.org, 15346 νέα πακέτα από ένα σύνολο των 51687 πακέτων. Περισσότερα από 29859 ενημερωμένα πακέτα (άρα 57% των πακέτων της jessie). Και τέλος, σημαντικός αριθμός πακέτων που καταργήθηκαν από την έκδοση (>6739, 13% των πακέτων του jessie).

Προετοιμαστείτε ή Παρατήστε το

Αν δεν έχετε πολύ λογισμικό εγκατεστημένο, αν τα config δεν έχουν παραπειραχθεί και αν γενικά δεν έχετε τίποτα ειδικές ρυθμίσεις μάλλον η αναβάθμιση θα πετύχει.

Σε κάθε περίπτωση, πρέπει να πάρετε backup τα πάντα πριν ξεκινήσετε την αναβάθμιση.

Αν επιχειρείτε την αναβάθμιση σε ένα σύστημα με σημαντικά services, με περίεργες και ειδικές ρυθμίσεις και περίπλοκα config, σχεδιάστε την αναβάθμιση προσεκτικά. Δείτε τι έχετε ανάγκη και τι όχι, ελέγξτε αν αξιοποιείτε κάποιο πακέτο που καταργείται στην 9 και μόνο εφόσον όλα βαίνουν καλώς, τότε συνεχίστε. Σε κάθε περίπτωση να έχετε πάντα στο μυαλό σας ένα σχέδιο για την περίπτωση που αναβάθμιση αποτύχει και βρεθείτε με μη λειτουργικό σύστημα.

Οι πιθανότητες για ένα επιτυχημένα και πλήρως λειτουργικό σύστημα μειώνονται κατακόρυφα αν στην 8 χρησιμοποιείτε λογισμικό τρίτων.  Γι αυτό το λόγο αφαιρέστε το.

# aptitude search '~o'

Η εντολή αυτή εμφανίζει όλα τα πακέτα που δεν βρίσκονται στο στάνταρ αποθετήριο.

Πάρτε backup data και config στο σύστημά σας.  Ιδανικά, αν τρέχετε το debian σε vm, πάρτε ένα snapshot. 

MariaDB και MySQL

Προσοχή: Η MariaDB αντικαθιστά τον MySQL στο Debian 9 Stretch. Αυτό σημαίνει ότι τα δυαδικά αρχεία έχουν νέο φορμάτ και δεν έχουν συμβατότητα προς τα πίσω – κάτι που εμείς στα πρώτα πειράματά μας διαπιστώσαμε με τον δύσκολο τρόπο, αλλά μας έσωσε το backup. Κατά τη διάρκεια της αναβάθμισης οι βάσεις θα αναβαθμιστούν. Εν τούτοις, αν κάτι δεν πάει καλά στις βάσεις σας με τη MariaDB να τις τρέχει, δεν θα μπορέσετε να τις πάτε πίσω. Πάρτε λοιπόν backup!

Ενημερώστε το παλιό σας σύστημα

 # apt-get update
 # apt-get upgrade
 # apt-get dist-upgrade

Λογικά δεν θα αργήσει, λάθη δεν θα προκύψουν.

Τρέξτε κι ένα:

# dpkg -C

καθώς και:

# apt-mark showhold

Αν προκύψουν θέματα στα παραπάνω, φροντίστε να τα φτιάξετε πριν την αναβάθμιση.

Ενημερώστε τα αποθετήρια (τα ρεποζίτορις δηλαδή)!

Τώρα που έχουμε ένα σύστημα πλήρως ενημερωμένο, πρέπει να αλλάξουμε τα ευρετήρια των πακέτων ώστε να δείχνουν σε αυτά του Stretch.

Πάρτε ένα backup το etc/apt/sources.list:

# cp /etc/apt/sources.list /etc/apt/sources.list.backup

Χρησιμοποιήστε το nano ή όποιον άλλο editor θέλετε για να ανοίξετε το αρχείο και αντικαταστήστε τη λέξη jessie με τη λέξη stretch.

Παράδειγμα:

JESSIE
 deb http://httpredir.debian.org/debian jessie main
 deb http://httpredir.debian.org/debian jessie-updates main
 deb http://security.debian.org jessie/updates main


STRETCH
 deb http://httpredir.debian.org/debian stretch main
 deb http://httpredir.debian.org/debian stretch-updates main
 deb http://security.debian.org stretch/updates main

Εναλλακτικά, κάντε ένα sed:

# sed -i 's/jessie/stretch/g' /etc/apt/sources.list

Ήρθε η ώρα για την ενημέρωση του ευρετηρίου:

# apt-get update

Προσομοιώστε

Πριν την αναβάθμιση, ας κάνουμε μια προεπισκόπηση των πακέτων που θα εγκατασταθούν, θα ενημερωθούν ή θα αφαιρεθούν:

# apt list --upgradable

Αναβαθμίστε

Α! Πριν αναβαθμίσετε! Για backup είπαμε; Πάρτε ένα backup.

Αν φτάσατε ως εδώ, και έχετε πάρει backup, τα πράγματα είναι απλά.

# apt-get upgrade
# apt-get dist-upgrade

Κατά τη διάρκεια της αναβάθμισης θα ερωτηθείτε αν επιθυμείτε επανεκκίνηση στα services. Καλύτερα επιλέξτε ναι. Αλλιώς κάθε τόσο θα διακόπτεται η αναβάθμιση με ξεχωριστό prompt για το κάθε service.

Restart services during package upgrades without asking?

Όπως θα διαπιστώσετε, η διαδικασία παίρνει πολλή ώρα, στο παλιό dell μας διήρκησε περίπου 2 ώρες και όλα πήγαν καλά, αν έχετε i7 με SSD, σίγουρα θα σταθείτε πιο τυχεροί.

Αφού φτάσατε ως εδώ, θα έχετε αναβαθμισμένο Debian στην Stretch. Κάντε ένα κόπο και τρέξτε για να βρείτε τυχόν παλιά και παρατημένα πακέτα.

# aptitude search '~o'

debian: πως να ενεργοποιήσετε το tap στο touchpad και άλλα παρεμφερή

Debian Open Logo

debian: Πως να ενεργοποιήσετε το tap στο touchpad και άλλα παρεμφερή θέματα

  • Για να ενεργοποιήσετε το tap στο touchpad γράψτε στο terminal synclient TapButton1=1
  • Για να δείτε τι είδους touchpad έχετε: egrep -i 'synap|alps|etps|elan' /proc/bus/input/devices
  • Το synclient στο terminal δείχνει όλες τις ρυθμίσεις του touchpad.

Άλλα χρήσιμα θέματα για όλες τις εκδόσεις του debian από την επίσημη ιστοσελίδα:
https://wiki.debian.org/SynapticsTouchpad

goaccess: site analytics from web server logs

goaccess screenshot

Ωραιότατο το google analytics αλλά τι γίνεται αν κάποιος δεν έχει εγκατεστημένο το σκριπτ και θέλει να δει το traffic ενός site; Πολλές οι λύσεις, ομολογουμένως όχι όλες τόσο καλές και εύκολες όσο το google analytics. Εδώ παρουσιάζουμε το goaccess που ξεχωρίζει με την απλότητά του.

Το goaccess θυμίζει κάτι από htop, αλλά παράγει και html report για τους λιγότερο σκληροπυρηνικούς, ενώ περιλαμβάνεται στα default πακέτα αρκετών διανομών. Επί παραδείγματι, στο debian, το apt-get install goaccess θα εγκαταστήσει μια σταθερή αλλά παλιά (ως συνήθως) version, την 0.8.3.

Αρχείο ρυθμίσεων

Πρώτα-πρώτα πρέπει να το ρυθμίσετε:

nano /etc/goaccess.conf

Αν είστε με debian και το site το τρέχει ο apache, δοκιμάστε να ξεμαρκάρετε τα comments στις παρακάτω γραμμές:

date-format %d/%b/%Y
log-format %h %^[%d:%^] "%r" %s %b

Αλλιώς δείτε τα σχόλια (ξεκινούν με #) και δοκιμάστε άλλο συνδυασμό σύμφωνα με το δικό σας configuration.

Να σημειώσουμε δε, ότι η επιλογή time-format δεν είναι διαθέσιμη σε παλιότερες εκδόσεις όπως η 0.8.3, για να την αξιοποιήσετε ξεχάστε το apt-get και προτιμήστε compile from latest sources.

Χρήση, παρακολούθηση και αναφορές

Η σύνταξη για να δείτε την στατιστική σε στυλ htop είναι η προφανής:

goaccess -f /var/log/apache2/access.log

Προσαρμόστε αναλόγως σύμφωνα με τη θέση του log file του web server.

Όπως θα δείτε στο output είναι ένα πιο κομψό tail -f για το access.log.

Τώρα, ένα feature που μας αρέσει, είναι το html report που παράγει σύμφωνα με την σύνταξη:

goaccess -f /var/log/access.log -a > /root/temp.html

wannacry: προστατεύστε τα windows xp sp3

Το wannacry εξακολουθεί να εξαπλώνεται, παρά τις προσπάθειες των ειδικών να το περιορίσουν.  Την Παρασκευή, ο νεαρός ερευνητής ασφάλειας λογισμικού με  ψευδώνυμο malwaretech, εντόπισε μια μέθοδο που φρέναρε την εξάπλωση, κι ενώ αρχικά η είδηση λειτούργησε ενθαρρυντικά, λίγες ώρες μετά, βρέθηκαν νέες παραλλαγές του κακόβουλου λογισμικού που δεν εμποδίζονται από τη μέθοδο του ειδικού.

Πως να προστατευτείτε από το wannacry;

Ενεργοποιήστε τις ενημερώσεις! Αυτό ισχύει ακόμα και για Windows που δεν υποστηρίζονται από την Microsoft: ο δημοφιλής κατασκευαστής λογισμικού είχε φροντίσει από το Μάρτιο να διαθέσει patch που προστάτευε από την αδυναμία SMB, άρα όσοι έχουν το λειτουργικό τους ρυθμισμένο στις αυτόματες ενημερώσεις, έμειναν αλώβητοι από το wannacry.

Αν ανήκετε στους καχύποπτους που δεν αφήνουν το λειτουργικό τους στην τύχη των αυτοματισμών της Microsoft, και διαθέτετε παλιότερα windows των οποίων η υποστήριξη έχει σταματήσει (π.χ. windows xp, windows 2003 κλπ) πρέπει να βρείτε το κατάλληλο patch της Microsoft.

  • Για τα windows xp sp3 είναι στη διεύθυνση https://www.microsoft.com/en-us/download/details.aspx?id=55245
  • Για άλλες εκδόσεις των windows, δείτε στη σελίδα https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/

 

προγραμματισμένο mysql backup

mysql logo (110 x 57)

Είδαμε κάτι αντίστοιχο για τον sql server express, αλλά ήρθε και η ώρα του mysql backup. Όταν μιλάμε για mysql, μιλάμε για linux κι όταν μιλάμε για linux, ανοίγουμε την κονσόλα.

mysql backup, όλα και γρήγορα!

Ας δούμε κατ’αρχήν πως κάνουμε παίρνουμε στα γρήγορα ένα backup για όλες τις databases:

mysqldump -u root -p --all-databases > alldb.sql

Θα σας ζητηθεί ο κωδικός του root.

Για να μην ζητάει τον κωδικό του root (π.χ. cron), θα πρέπει να κολλήσετε δίπλα στο -p τον κωδικό:

mysqldump -u root -pSECRET --all-databases > alldb.sql

…και συμπίεση;

Προφανώς θα θέλετε να συμπιέσετε το αρχείο, κάτι που χάρη στην κονσόλα και το piping, γίνεται με μιας, κάπως έτσι:

mysqldump -u root -pSECRET --all-databases | bzip2 -c > alldb.$(date +%Y-%m-%d-%H.%M.%S).sql.bz2

Παρατηρήστε την απλότητα με την οποία δηλώνουμε την ημερομηνιακή μορφή του συμπιεσμένου:

$(date +%Y-%m-%d-%H.%M.%S)

ή μήπως καλύτερα σκριπτάκι;

Συχνά, είναι προτιμότερο να διατηρούμε αντίγραφο της κάθε database σε χωριστό αρχείο. Ακολουθεί ένα ωραιότατο σκριπτάκι bash, το οποίο διαβάζει τα ονόματα των βάσεων δεδομένων και για κάθε μια από αυτές – πλην των συστημικών του mysql – λαμβάνει αντίγραφο και το ζιπάρει!

#!/bin/bash

USER="root"
PASSWORD="SECRET"

databases=`mysql -u $USER -p$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`

for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != "performance_schema" ]] && [[ "$db" != "mysql" ]] && [[ "$db" != _* ]] ; then
        echo "Dumping database: $db"
        OUTPUT=`date +%Y%m%d`.$db.sql
        mysqldump -u $USER -p$PASSWORD --databases $db > $OUTPUT
        gzip $OUTPUT
    fi
done

Ονομάστε το σκριπτάκι backup και μην ξεχάσετε να το κάνετε εκτελέσιμο:

chmod +x backup

Τώρα, για να έχετε το κεφάλι σας ήσυχο βάλτε το και σε ένα κρον (crontab -e) και καλή ανάσταση:

0 7 * * * /root/mysqlbackups/backup

 

άλλη μια ώρα χαμένη με τα τερτίπια του sql server

Οκ, ας το πιάσουμε από την καλή, είναι καλός, γρήγορος και αξιόπιστος, ο sql server αποτελεί αγαπημένο backend για τις εφαρμογές μας, όμως αν αποφασίσει να σκαλώσει σε πάει πίσω για ώρες και μέρες. Ένα παράξενο κόλλημα είχαμε και σήμερα που, πράγματι, δεν ανήκει στις πιο τυπικές περιπτώσεις, είναι όπως θα δείτε, μια αλληλουχία συμπτώσεων που οδηγούν στο ξεβράκωμα του sql, όμως, αυτό έλειπε, να κόλλαγε στις τυπικές περιπτώσεις!

Ας πάρουμε όμως τα πράγματα από την αρχή. Ήταν ένα ηλιόλουστο μεσημέρι και κάναμε debugging σε μια παλιά .net εφαρμογή που παρσάρει κάτι παράξενα αρχεία πάραντοξ (!), κάνει κάτι πράξεις και τέλος τα σπρώχνει σε μια database στον sql server που αναλαμβάνει τα περεταίρω. Κι ενώ όλοι θα στοιχημάτιζαν ότι κάτι θα στράβωνε μεταξύ paradox – bde – access – odbc ή κάποιας άλλης παλαιολιθικής οντότητας, το debugging ανέδειξε σφάλμα στο connectivity με τον sql server.

Τίποτα προφανές: κανένα δικτυακό πρόβλημα, τα συνθηματικά σωστά, ο server πάνω, τι στο καλό; Wtf; -επί το ελληνικότερο!

Συνεχίστε την ανάγνωση του «άλλη μια ώρα χαμένη με τα τερτίπια του sql server»

πως να φτιάξετε ένα child θέμα στο wordpress

Δεν είναι επί του παρόντος να σχολιάσουμε το αν είναι καλό, αποτελεσματικό, γρήγορο και καλογραμμένο το wordpress, αυτό που κανείς δεν μπορεί να αμφισβητήσει είναι ότι είναι πιο δημοφιλές cms, με ότι σημαίνει αυτό, τα καλά του και τα κακά του. Στα καλά του συγκαταλέγεται η ευκολία σε αναβαθμίσεις, ενώ στα κακά του, το γεγονός ότι αν οι αναβαθμίσεις γίνουν απρόσεκτα, καταστρέφουν ότι ασύμβατο βρουν μπροστά τους, με συνήθη θύματα τα θέματα με τα εύθικτα css και τ’ ανεμοδαρμένα functions.php, αν και εφόσον δεν έχουν πραγματοποιηθεί με το ενδεδειγμένο τρόπο.

Συνεχίστε την ανάγνωση του «πως να φτιάξετε ένα child θέμα στο wordpress»

Με την υποστήριξη του WordPress. Διαγραφή.

Υπάρχουν πολλοί τρόποι να το εξαφανίσετε το περίφημο powered by wordpress στο twentyseventeen. Κάποιοι προτείνουν να το κρύψετε με css, όμως η σελίδα εξακολουθεί να το ρεντάρει.

Κατά την γνώμη μας ο καλύτερος τρόπος είναι να επέμβετε στο wp-content/themes/twentyseventeen/template-parts/footer/site-info.php και να διαγράψετε τη 13η γραμμή που ξεκινάει με <a href="...">...</a>.

Αν έχετε φτιάξει child theme σύφωνα με το αντίστοιχο άρθρο μας διαγράψτε την αντίστοιχη γραμμή στη θέση wp-content/themes/twentyseventeen/template-parts/footer/site-info.php