Tilpassede databasetabeller Vedlikehold av databasen

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.


dbDeta

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.


Vær forsiktig

Evnen til dbDelta () å gjøre all denne analysen kommer til en pris: dens fussiness av hva den vil akseptere (eller korrekt tolke). For eksempel:

  • Hver del av spørringen (for eksempel hver kolonne og nøkkelangivelse) må ha sin egen linje. 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',
  • Du må bruke KEY i stedet for sin synonym INDEX.
  • Noen nøkkler må gis et navn. For eksempel, skriv ikke
    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).

  • PRIMARY KEY skal ikke bli gitt et navn, men det må heller være to mellomrom mellom 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.


Legge til eller endre kolonner

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.


Fjerner kolonner

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). ';');

Fjerner nøkler

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). ';');

Oppgrader Rutinemessig

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:

  • Hvis det ikke er noen versjon i databasen, er det en ny installasjon, og vi legger bare til den gjeldende versjonen
  • Hvis det er er en versjon i databasen, og det er den nåværende versjonen, vi gjør ingenting
  • Ellers er det en eldre versjon, så vi vil gjennomgå alle nødvendige oppgraderingsrutiner.
 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.


Avinstaller rutinemessig

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 * /