Over levetiden til ditt eget bord vil du sannsynligvis finne ut at du må gjøre endringer i hva den lagrer, eller hvordan den lagrer den. Dette kan skyldes et behov for å lagre flere (eller færre) data. Det kan være at den første utformingen av databasen ikke var ment å håndtere (effektivt) med hva brukerbasen din nå krever. Uansett må vi vite hvordan vi tilpasser vårt bord for å møte våre nye behov. Dette er hva vi skal se på i denne opplæringen, og vi vil primært fokusere på funksjonen dbDelta ()
at vi først møttes i første del.
Heldigvis mesteparten av legworket i håndtering av databaseendringer er gjort av WordPress-funksjonen dbDelta ()
. Vi brukte denne funksjonen i del ett for å lage vårt bord, men det gjør faktisk mye mer enn det: Før du utførte spørsmålet vi ga det, kontrollerer det om bordet allerede eksisterer. Hvis ikke, skaper det bordet, men hvis det eksisterer - det sammenligner forskjellen (dermed navnet) og gjør noen Endringer. Det er derfor i del ett vi ikke kontrollerte manuelt om bordet allerede eksisterte.
Hvis tabellen allerede eksisterer, men er forskjellig fra tabellen gitt av SQL (for eksempel har den eksisterende tabellen en manglende kolonne eller en annen kolonnekollasjon), da dbDelta ()
gjelder automatisk disse oppdateringene. På denne måten kan vi frigjøre en ny versjon av plugin-modulen som endrer vårt bord ved å bare bruke 'dbDelta ()' med den endrede SQL. Nesten.
dessverre, dbDelta ()
gjelder ikke alle Endringer. Vi kan anta at i vår nyeste plugin-utgivelse har vi ikke behov for en kolonne, og vi vil fjerne den. Så vi fjerner den fra SQL-spørringen i del ett, og i oppgraderingsrutinen wptuts_create_tables ()
. Etter oppgradering finner vi at kolonnen fortsatt er der. Verre enn det: Brukerne som oppgraderer fra den gamle versjonen til den nye versjonen, vil da ha en strukturelt forskjellig tabell enn de som starter med den nye versjonen.
Merk: dbDelta ()
er ikke destruktive: det er det vil legge til manglende kolonner, eller endre endrede kolonner, men det vil ikke fjerne kolonner eller indekser.
Så hva gjør dbDelta ()
faktisk gjør?
La oss minne oss om SQL-spørringen vi sender til dbDelta ()
når du lager bordet:
$ sql_create_table = "CREATE TABLE". $ 20% usp NULL standard '0', objekt_type varchar (20) IKKE NULL standard 'post', activity_date datetime IKKE NULL standard '0000-00-00 00:00:00', PRIMARY KEY (log_id), KEY user_id (user_id)) $ charset_collate ; "; dbDelta ($ sql_create_table);
Først trekker det ut alt CREATE TABLE
spørringer (deg kan send flere forespørsler til dbDelta ()
på en gang, adskille dem med en ";
', men for å forbedre lesbarheten foretrekker jeg ikke å). Fra dette tar det tabellnavnet, $ table
, og kjører
$ wpdb-> get_results ("DESCRIBE $ table;");
Dette returnerer en rekke eksisterende kolonner - hver kolonne er faktisk et objekt som inneholder informasjon som gjelder denne kolonnen (navn, type, standardverdi osv.). For eksempel vår log_id
kolonnen ser ut som:
stdClass Object ([Field] => log_id [Type] => bigint (20) unsigned [Null] => NEI [Key] => PRI [Standard] => [Ekstra] => auto_increment)
Hvis tabellen ikke eksisterer, returneres en tom matrise og bordet opprettes. Ellers dbDelta ()
Deretter går gjennom hver linje i det bestått spørsmålet, trekker ut kolonnene og lagrer dem i en matrise $ cfields
. Det gjør det samme med hver av nøklene (inkludert primær).
Deretter går det gjennom hver av de eksisterende kolonner. Hvis de er til stede i ovennevnte matrise, $ cfields
, de er fjernet. Det sammenligner deretter sin type, hvis de ikke samsvarer, genererer det automatisk en tilsvarende ALTER TABLE
spørringen skal utføres senere. Etter at dette er gjort, er de eneste kolonnene igjen i $ cfields
er de som ikke allerede eksisterer. Fra dette genererer det videre ALTER TABLE
spørringer for å lage disse kolonnene.
Det utfører deretter en nesten identisk prosedyre for nøkler.
Evnen til dbDelta ()
å gjøre all denne analysen kommer til en pris: dens fussiness av hva den vil akseptere (eller korrekt tolke). For eksempel:
user_id bigint (20) unsigned IKKE NULL standard '0', aktivitet varchar (20) IKKE NULL standard 'oppdatert',
vil fungere som om aktivitet
kolonnen er ikke til stede. Det riktige formatet er:
user_id bigint (20) unsigned IKKE NULL standard '0', aktivitet varchar (20) IKKE NULL standard 'oppdatert',
KEY (user_id)]
i stedet bør det være
KEY user_id (user_id)
(selv om navnet ikke må være det samme som kolonnen).
PRIMÆRNØKKEL
og kolonneerklæringen: (Log_id)
. For eksempel, PRIMARY KEY (log_id),
vil føre til en feil. Det riktige formatet er:
PRIMARY KEY (log_id),
Dette er ikke en komplett liste, som regel bør du unngå ekstra mellomrom rundt og mellom søkeord, for eksempel SKAPE
og BORD
og det bør ikke være noen ekstra mellomrom rundt kolonner. Internals of dbDelta ()
stole på å bruke preg_match ()
å trekke ut informasjon fra den overførte SQL-setningen - og som slike ting kan gå galt ganske enkelt hvis denne setningen ikke er riktig formatert.
Noen av disse feilene vil oppstå stille (for eksempel hvis du ikke gir en NØKKEL
et navn, dbDelta ()
vil fortsette å duplisere det). Av denne grunn er det viktig at du inspiserer bordet manuelt (ved hjelp av phpMyAdmin eller lignende) for å kontrollere at koden din fungerer korrekt.
Med dbDelta ()
, dette er veldig enkelt - la oss anta at vi vil lage object_id
en indeks, legg til en ekstra kolonne user_ip
for å lagre brukerens IP-adresse og endre typen av aktivitetskolonnen til varchar (30)
, vi erstatter bare den opprinnelige SQL Query med:
$ sql_create_table = "CREATE TABLE". $ wpdb-> wptuts_activity_log. "(log_id bigint (20) usignert IKKE NULL auto_increment, user_id bigint (20) unsigned IKKE NULL standard '0', user_ip varchar (15), aktivitet varchar (30) IKKE NULL standard 'oppdatert', object_id bigint (20) unsigned IKKE NULL standard '0', object_type varchar (20) IKKE NULL standard 'post', activity_date datetime IKKE NULL standard '0000-00-00 00:00:00', PRIMARY KEY (log_id), KEY user_id (user_id), KEY object_id (object_id),) $ charset_collate; ";
Da sørger vi bare for at vi ringer wptuts_create_tables ()
i oppgraderingsrutinen, og endringene trer i kraft.
Siden dbDelta ()
vil ikke fjerne kolonner, det vil ikke være nok å fjerne riktig linje fra spørringen (det er fortsatt nødvendig skjønt). I stedet må vi gjøre ting manuelt.
Først trekk ut en rekke eksisterende kolumner:
$ existing_columns = $ wpdb-> get_col ("DESC $ wpdb-> wptuts_activity_log", 0);
Så, hvis kolonnene vi ønsker å fjerne er til stede, kan vi fjerne dem med en ALTER TABLE
spørsmål:
$ remove_columns = array ('object_id'); // Array av kolonner for å fjerne $ remove_columns = array_intersect ($ remove_columns, $ existing_columns); hvis (! tom ($ remove_columns)) $ wpdb-> spørring ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP COLUMN" .implode (', DROP COLUMN', $ remove_columns). ';');
Akkurat som vi gjorde med kolonner, får du først en rekke indekser:
$ existing_keys = $ wpdb-> get_col ("VIS INDEX FRA $ wpdb-> wptuts_activity_log WHERE Key_name! = 'PRIMARY';", 2);
Så, hvis nøklene vi ønsker å fjerne finnes, kan vi fjerne dem som ovenfor, men nå bruker DROP INDEX
$ remove_keys = array ('user_id'); // Array av nøkler for å fjerne $ remove_keys = array_intersect ($ remove_keys, $ existing_keys); hvis (! tomt ($ remove_keys)) $ wpdb-> spørring ("ALTER TABLE $ wpdb-> wptuts_activity_log DROP INDEX" .implode (', DROP INDEX', $ remove_keys). ';');
Nå som vi vet hvordan vi skal oppgradere databasen - kan vi se hvordan vi skal håndtere dette i plugin-modulen vår. Vi lagrer all vår oppgraderingshåndtering inne i funksjonen: wptuts_activity_log_upgradecheck ()
. Vær oppmerksom på at plugin-aktiveringskroken vil ikke utløses ved oppdatering av en plugin-modul: For å sikre at oppgraderingsrutinen gjør jobben sin, hekker vi på admin_init
.
For å sjekke hvilke oppgraderingsrutiner vi må utføre, lagrer vi plugin-versjonen i databasen. Vi sammenligner denne versjonen (den installerte versjonen) med gjeldende (aktiverte) versjonen av plugin-modulen:
add_action ('admin_init', 'wptuts_activity_log_upgradecheck'); funksjon wptuts_activity_log_upgradecheck () // Versjon av for øyeblikket aktivert plugin $ current_version = '1.3'; // Databaseversjon - dette kan trenge å oppgradere. $ installed_version = get_option ('wptuts_activity_log_version'); hvis (! $ installed_version) // Ingen installert versjon - vi antar at den bare har blitt nylig installert add_option ('wptuts_activity_log_version', $ current_version); elseif ($ installed_version! = $ current_version) / * * Hvis dette er en gammel versjon, utfør noen oppdateringer. * / // Installert versjon er før 1.1 - oppgrader til 1.1 hvis (version_compare ('1.1', $ installed_version)) // Kode for å oppgradere til versjon 1.1 // Installert versjon er før 1,3 - oppgrader til 1,3 hvis (version_compare '1.3', $ installed_version)) // Kode for å oppgradere til versjon 1.3 // Database er nå oppdatert: Oppdater installert versjon til siste versjon update_option ('wptuts_activity_log_version', $ current_version);
Merk: Det er viktig at denne oppgraderingsrutinen er til stede i første slipp som den vil legge til den første versjonen (1.0) i databasen. Hvis du ikke gjør det, kan det oppstå problemer for de som oppgraderer fra 1,0 til 1,1.
Hver av de enkelte oppgraderingsrutiner skal sikre at databasen er oppdatert ved å bruke koden som er omtalt i de tidligere seksjonene. Viktig, hvis vi gjør noen endringer i CREATE TABLE SQL, må du huske å kjøre den søket gjennom dbDelta ()
(i vårt eksempel ved å ringe wptuts_create_tables ()
som en del av oppgraderingsrutinen) for at endringene skal tre i kraft.
Vær forsiktig med hvordan du håndterer oppdateringer når du bruker dbDelta
. Husk at noen brukere kan oppgradere på tvers av to eller flere oppdateringer. Så hvis slike endringer ikke kan gjøres parallelt - må du oppgradere i trinn, kaller "dbDelta ()" flere ganger, og gjør de nødvendige endringene for det stadiet.
Mens vi er på det, la oss se på å rydde opp etter oss selv når plugin-modulen ble avinstallert. Dette er vanligvis svært enkle rutiner: Bare fjern databasetabellen, eventuelle alternativer lagret og eventuelle cron-jobber du har aktivert, kan plugin-modulen din ha aktivert. Vi hekker rutinen vår på avinstallasjonshaken ved hjelp av registreringsavinstalleringshaken ()
registrer avinstalleringshaken (__ FIL __, 'wptuts_uninstall_plugin'); funksjon wptuts_uninstall_plugin () global $ wpdb; // Fjern vårt bord (hvis det finnes) $ wpdb-> spørring ("DROP TABLE IF EXISTS $ wpdb-> wptuts_activity_log"); // Fjern databaseversjonen delete_option ('wptuts_activity_log_version'); / * Fjern eventuelle andre alternativer du har installert, og fjern eventuelle plugin-inn-jobber * /