From 3819e887d9f485ac0917a9d415961e147581c280 Mon Sep 17 00:00:00 2001
From: aztech <>
Date: Thu, 10 Jan 2008 02:43:04 +0000
Subject: [PL] partial Active Record translation + some base QST page
translations
---
.../protected/pages/Database/pl/ActiveRecord.page | 1163 ++++++++++++++++++++
.../protected/pages/Database/pl/ar_objects.png | Bin 0 -> 20638 bytes
.../protected/pages/Database/pl/ar_relations.png | Bin 0 -> 9693 bytes
.../protected/pages/Database/pl/diagram.png | Bin 0 -> 30320 bytes
.../protected/pages/Database/pl/object_states.png | Bin 0 -> 9596 bytes
.../pages/Database/pl/sqlmap_active_record.png | Bin 0 -> 17351 bytes
.../protected/pages/pl/Construction.page | 5 +
demos/quickstart/protected/pages/pl/Search.page | 29 +
.../quickstart/protected/pages/pl/ViewSource.page | 31 +
9 files changed, 1228 insertions(+)
create mode 100644 demos/quickstart/protected/pages/Database/pl/ActiveRecord.page
create mode 100644 demos/quickstart/protected/pages/Database/pl/ar_objects.png
create mode 100644 demos/quickstart/protected/pages/Database/pl/ar_relations.png
create mode 100644 demos/quickstart/protected/pages/Database/pl/diagram.png
create mode 100755 demos/quickstart/protected/pages/Database/pl/object_states.png
create mode 100755 demos/quickstart/protected/pages/Database/pl/sqlmap_active_record.png
create mode 100644 demos/quickstart/protected/pages/pl/Construction.page
create mode 100644 demos/quickstart/protected/pages/pl/Search.page
create mode 100644 demos/quickstart/protected/pages/pl/ViewSource.page
(limited to 'demos/quickstart/protected/pages')
diff --git a/demos/quickstart/protected/pages/Database/pl/ActiveRecord.page b/demos/quickstart/protected/pages/Database/pl/ActiveRecord.page
new file mode 100644
index 00000000..53bbdee5
--- /dev/null
+++ b/demos/quickstart/protected/pages/Database/pl/ActiveRecord.page
@@ -0,0 +1,1163 @@
+ Rekordy Aktywne są obiektami, które opakowują wiersz w bazie danych lub widoku,
+ obudowują (ang. encapsulate) dostęp do bazy danych oraz dziedziny logiki dla tych danych.
+ Podstawą Rekordu Aktywnego są klasy biznesowe np. klasa
+ Produkty, które są bardzo podobne do struktury rekordu należącego do bazy danych. Każdy Rekord Aktywny jest odpowiedzialny
+ za zapisywanie i łądowanie danych do i z bazy danych. Rekord Aktywne jest dobrym wyborem dla dziedziny logiki, która nie jest zbyt złożona, tak jak tworzenie, odczyty, aktualizacje oraz usuwanie.
+ Pochocne (ang. derivations) oraz sprawdzenia bazujące na pojedyńczym rekordzie sprawdzają się dobrze w tej konstrukcji.
+ Rekord Aktywne ma podstawową zaletę, którą jest prostota. Łatwo jest stworzyć Rekord Aktywny, łatwo go również zrozuieć.
+ Jednakże, jeśli twoja logika biznesowa staje się coraz bardziej złożona, wkrótce będziesz chciał
+ używać bezpośrednich relacji, zbiorów, dziedziczenia twojego obiektu i tak dalej. Nie da się tego łatwo odwzorować za pomocą Rekordu Aktywnego,
+ a dodawanie ich po kawałku staje się bardzo kłopotliwe. Innym argumentem przeciw Rekordowi Aktywnemu jest fakt, że łączy model obiektowy z modelem baz danych.
+ To czyni trudniejszym refaktoring, gdy projekt idzie naprzód.
+ Alternatywą jest używanie wzorca Data Mapper (mapa danych), który odseparowuje role obiektu biznesowego od tego jak te obiekty są przechowywane.
+ Prado dostarcza
+ Prado provides a darmowy wybór pomiędzy rekordem aktywnym a SqlMap Data Mapper.
+ SqlMap Data Mapper może być uzywany do wczytania obiektów Rekordu Aktywnego, i na odwrót, te Rekordy Aktywne mogą zostać użyte do aktualizacji bazy danych.
+ Związek pomiędzy Rekordem Aktywnym a SqlMap przedstawiony jest na kolejnym diagramie. Więcej informacji związanych z SqlMap Data Mapper można znaleźć w
+ manualu SqlMap.
+ alt="Active Records and SqlMap DataMapper" id="fig:diagram.png" class="figure"/>
+
+ Klasa Rekordu aktywnego posiada funkcjonalność do przeprowadzenia następujących zadań:
+
+Implementacja wzorca Aktywnego Rekordu w PRADO nie zapewnia referencyjnej tożsamości (ang. referential identity). Każdy istniejący obiekt używający
+Rekordu Aktywnego jest koopią danych z bazy danych. Na przykład jeśli zapytasz o konkretnego klienta i zostanie zwrócony obiekt Klient,
+to następnym razem kiedy zapytasz o tego klienta otrzymasz spowrotem inną instancję obiektu Klient. To implikuje, że ścisłe porównianie (np. używając ===)
+zwróci fałsz, natomiast luźne porównianie (np. używając ==) zwróci prawdę jeśli wartości obiektu są równe poprzez luźne porónanie.
+
+
+Jest to implikacja modelu wynikająca z następującego pytania:
+"Czy myślisz o kliencie jako o obiekcie, którego któy jest tylko jeden, czy też myślisz o obiekcie na którym działasz jako o kopii bazy danych.
+Inne mapowania O/R implikują, że istnieje tylko jeden obiekt Klienta z KlientID 100
+Other O/R mappings will imply that there is only one Customer object with custID 100 i to dosłownie jest ten klient.
+Jeśli pobierzesz klienta i zmienisz pole w nim, wtedy masz zmienionego tego klienta.
+"To kontroastuje z: zmieniłeś tą kopię klienta ale nie tamtą kopię.
+Jeśli dwóch ludzi zaktualizuje kleinta z dwóch kopii obiektu, kto zaktualizuje pierwszy lub być może ostanie wygrywa." [A. Hejlsberg 2003]
+
+Implementacja Aktywnego Rekordu wykorzystuje kalsy Prado DAO by uzyskać dostęp do danych. Aktualna implementacja Aktywnego Rekordu wspiera następujace bazy danych
+ Wsparcie dla pozostałych baz danych może zostać wprowadzone, keidy będzie dostatecne zapotrzebowanie Rozważmy następującą tablicę "users", która zawiera dwie kolumny nazwane "username" oraz "email",
+ gdzie "username" jest kluczem głównym.
+ Następnie zdefiniujemy naszą klasę Rekordu Aktywnego odpowiadającą tablicy "users".
+ Każda kolumna tablicy "users" musi posiadać odpowiadającą jej właściwość o tej samej nazwie co kolumna w tablicy w klasie UserRecord.
+ Oczywiście, możesz zdefiniować dodatkowe zmienne lub właściwości, które nie istnieją w strukturze tablicy.
+ Stała TABLE jest opcjonalna w klasie , kiedy nazwa klasy jest taka sama jak nazwa tablicy w bazie danych, w przeciwnym przypadku TABLE
+ musi określać nazwę tablicy, która odpowiada klasie Rekordu Aktywnego.
+
+ Odkąd TActiveRecord rozszerza TComponent, metody setter i getter mogą zostać zdefiniowane
+ by umożliwić kontrolę nad tym jak zmienne są ustawiane i zwracane. Na przykłąd dodanie właściwości $level
+ do klasy UserRecord:
+ Więcej szczegółów dotyczących TComponent można znaleźć dokumentacji komponentów.
+Później użyjemy metod getter/setters by umożliwić opóźnione ładowanie (ang. lazy loading) obiektów relacji.
+
+ Metoda statyczna finder() zwraca instancję UserRecord, która może zostać użyta do załadowania rekordów z bazy.
+ Ładowanie rekordów za pomocą tej metody będzie omówione później. Statyczna metoda TActiveRecord::finder()
+ pobiera nazwę klasy Rekord Aktywnego jako parametr.
+
+ Domyślne połączenie z bazą dla Rekordu Aktywnego może zostać ustawione następujaco.
+ Zobacz Ustanawianie połączenia z bazą
+ by uzyskać ogólnie dalsze szczegóły odnośnie tworzenia połączenia z bazą danych.
+ Alternatywnie, możesz stworzyć klasę bazową i nadpisać metodę getDbConnection()
+do zwracania połączenia z bazą. To jest prosty spodób, by umożliwić wielkokrotne połączenia do wielu baz danych.
+ Następujący kod demonstruje definiowanie połączenia z bazą danych w klasie bazowej (nie ma potrzeby by ustawiać połączenie DB gdziekolwiek indziej).
+
+ Domyślne połączenie z bazą może zostać również skonfigurowane używając tagu <module>
+ w pliku application.xml
+ lub config.xml następująco:
+ Do właściwość ConnectionID może zostać przypisana wartość ID z konfiguracji z innego modułu
+ TDataSourceConfig. To pozwala uyżywać to połączenie z bazą danych w innych modułach, takich jak SqlMap (mapa SQL).
+
+ Klasa TActiveRecord dostarcza wielu wygodnych metod do wyszukiwania rekordów z bazy danych.
+ Najprostszym jest znajdowanie jednego rekordu poprzez dopasowanie klucza głównego lub klucza złożonego (ang. composite key)
+ (klucz główny skłądający się z wielu kolumn).
+ Zobacz Znajduje jeden rekord używając klucza głównego lub klucza złożonego.
+ Znajduje wiele rekordów używając listy kluczy głównych lub kluczy złożonych.
+Co następuje jest odpowiednie dla kluczów głównych (klucz główny składa się tylko z jednego pola/kolumny)
+ Znajduj pojedyńczy rekord, który spełnia kryteria. Kryteria mogą być częściowym łąńcuchem SQL lub obiektem TActiveRecordCriteria Klasa TActiveRecordCriteria ma następujące właściwości:
+ Same as find() but returns an array of objects. Dynamic find method using parts of the method name as search criteria.
+Method names starting with findBy return 1 record only
+and method names starting with findAllBy return an array of records.
+The condition is taken as part of the method name after findBy or findAllBy.
+
+The following blocks of code are equivalent:
+ Finds records using full SQL where findBySql()
+return an Active Record and findAllBySql()returns an array of record objects.
+For each column returned, the corresponding Active Record class must define a member variable or
+property for each corresponding column name.
+ Find the number of matchings records, accepts same parameters as the findAll() method.
+Add a new record using TActiveRecord is very simple, just create a new Active
+Record object and call the save() method. E.g.
+
+To update a record in the database, just change one or more properties of
+the Active Record object that has been loaded from the database and then
+call the save() method.
+
+
+Active Record objects have a simple life-cycle illustrated in the following diagram.
+
+We see that new TActiveRecord objects are created by either using one of the find*()
+methods or using creating a new instance by using PHP's new keyword. Objects
+created by a find*() method starts with clean state. New instance of
+TActiveRecord created other than by a find*() method starts with new state.
+Whenever you
+call the save() method on the TActiveRecord object, the object enters the clean
+state. Objects in the clean becomes dirty whenever one of more of its
+internal states are changed. Calling the delete() method on the object
+ends the object life-cycle, no further actions can be performed on the object.
+
+ To delete an existing record that is already loaded, just call the delete() method.
+ You can also delete records in the database by primary keys without
+ loading any records using the deleteByPk() method (and equivalently the deleteAllByPks() method).
+ For example, to delete one or several records with tables using one or more primary keys.
+
+For composite keys (determined automatically from the table definitions):
+
+To delete by a criteria, use deleteAll($criteria) and deleteBy*()
+with similar syntax to findAll($criteria) and findAllBy*() as
+described above.
+ All Active Record objects contain the property DbConnection
+ that can be used to obtain a transaction object.
+
+The TActiveRecord offers two events, OnCreateCommand and OnExecuteCommand.
+ The OnCreateCommand event is raised when a command is prepared and
+parameter binding is completed. The parameter object is TDataGatewayEventParameter of which the
+Command property can be inspected to obtain the SQL query to be executed.
+
+The OnExecuteCommand event is raised when a command is executed and the
+result from the database was returned. The parameter object is TDataGatewayResultEventParameter
+of which the Result property contains the data return from the database.
+The data returned can be changed by setting the Result property.
+ Using the OnExecuteCommand we can attach an event handler to log
+the entire SQL query executed for a given TActiveRecord class or instance. For example, we define
+a base class and override either the getDbConnection() or the constructor.
+
+The Prado Active Record implementation supports the foreign key mappings for database
+that supports foreign key constraints. For Active Record relationships to function the
+underlying database must support foreign key constraints (e.g. MySQL using InnoDB).
+
+In the following sections we will consider the following table relationships between
+Teams, Players, Skills and Profiles.
+ The goal is to obtain object models that represent to some degree the entity
+relationships in the above figure.
+
+There is a mismatch between relationships with objects and table relationships.
+First there's a difference in representation. Objects handle links by storing references
+that are held by the runtime memory-managed environment. Relational databases handle
+links by forming a key into another table. Second, objects can easily use collections
+to handle multiple references from a single field, while normalization forces
+all entity relation links to be single valued. This leads to reversals of the data
+structure between objects and tables. The approach taken in the Prado Active Record
+design is to use the table foreign key constraints to derive object relationships. This implies
+that the underlying database must support foreign key constraints.
+ The entity relationship between the Teams and Players table is what is known
+as an 1-M relationship. That is, one Team may contain 0 or more Players. In terms of
+object relationships, we say that a TeamRecord object has many PlayerRecord objects.
+(Notice the reversal of the direction of relationships between tables and objects.)
+
+We model the Team object as the following Active Record classes.
+
+The static $RELATIONS property of TeamRecord defines that the
+property $players has many PlayerRecords. Multiple relationships
+is permitted by defining each relationship with an entry in the $RELATIONS
+array where array key for the entry corresponds to the property name.
+In array(self::HAS_MANY, 'PlayerRecord'), the first element defines the
+relationship type, the valid types are self::HAS_MANY, self::HAS_ONE,
+self::BELONGS_TO and self::MANY_TO_MANY.
+The second element is a string 'PlayerRecord' that corresponds to the
+class name of the PlayerRecord class.
+And the third element 'team_name' refers to the foreign key column in the Players table that
+references to the Teams table.
+
+The foreign key constraint of the Players table is used to determine the corresponding
+Teams table's corresponding key names. This is done automatically handled
+in Active Record by inspecting the Players and Teams table definitions.
+ The "has many" relationship is not fetched automatically when you use any of the Active Record finder methods.
+You will need to explicitly fetch the related objects as follows. In the code below, both lines
+are equivalent and the method names are case insensitive.
+
+The method with_xxx() (where xxx is the relationship property
+name, in this case, players) fetches the corresponding PlayerRecords using
+a second query (not by using a join). The with_xxx() accepts the same
+arguments as other finder methods of TActiveRecord, e.g. with_players('age = ?', 35).
+ The entity relationship between Players and Profiles is one to one. That is,
+each PlayerRecord object has one ProfileRecord object (may be none or null).
+A has one relationship is nearly identical to a has many relationship with the exception
+that the related object is only one object (not a collection of objects).
+ The "has many" relationship in the above section defines a collection of foreign
+objects. In particular, we have that a TeamRecord has many (zero or more)
+PlayerRecord objects. We can also add a back pointer by adding a property
+in the PlayerRecord class that links back to the TeamRecord object,
+effectively making the association bidirectional.
+We say that the $team property in PlayerRecord class belongs to a TeamRecord object.
+The following code defines the complete PlayerRecord class with 3 relationships.
+
+The static $RELATIONS property of PlayerRecord defines that the
+property $team belongs to a TeamRecord.
+The $RELATIONS array also defines two other relationships that we
+shall examine in later sections below.
+In array(self::BELONGS_TO, 'TeamRecord', 'team_name'), the first element defines the
+relationship type, in this case self::BELONGS_TO;
+the second element is a string 'TeamRecord' that corresponds to the
+class name of the TeamRecord class; and the third element 'team_name' refers
+to the foreign key of Players referencing Teams.
+A player object with the corresponding team object may be fetched as follows.
+
+ The method with_xxx() (where xxx is the relationship property
+ name, in this case, team) fetches the corresponding TeamRecords using
+ a second query (not by using a join). The with_xxx() accepts the same
+arguments as other finder methods of TActiveRecord, e.g.
+with_team('location = ?', 'Madrid').
+ The "belongs to" relationship of ProfileRecord class is defined similarly. In essence, there exists a "belongs to" relationship for objects corresponding to
+entities that has column which are foreign keys. In particular, we see that
+the Profiles table has a foreign key constraint on the column player_id
+that relates to the Players table's player_id column. Thus, the ProfileRecord
+object has a property ($player) that belongs to a PlayerRecord object.
+Similarly, the Players table has a foreign key constraint on the column team_name that relates to the
+Teams table's name column.
+Thus, the PlayerRecord object has a property ($team) that belongs to a
+TeamRecord object.
+ A parent child relationship can be defined using a combination of has many and belongs to
+relationship that refers to the same class. The following example shows a parent children relationship between
+"categories" and a "parent category".
+
+In the above, we show that an Active Record object can reference to its related objects by
+declaring a static class member $RELATIONS which specifies a list of relations. Each relation
+is specified as an array consisting of three elements: relation type, related AR class name,
+and the foreign key(s). For example, we use array(self::HAS_MANY, 'PlayerRecord', 'team_name')
+to specify the players in a team. There are two more optional elements that can be specified
+in this array: query condition (the fourth element) and parameters (the fifth element).
+They are used to control how to query for the related objects. For example, if we want to obtain
+the players ordered by their age, we can specify array(self::HAS_MANY, 'PlayerRecord', 'team_name', 'ORDER BY age').
+If we want to obtain players whose age is smaller than 30, we could use
+array(self::HAS_MANY, 'PlayerRecord', 'team_name', 'age<:age', array(':age'=>30)). In general,
+these two additional elements are similar as the parameters passed to the find() method in AR.
+
+Objects can handle multivalued fields quite easily by using collections as field values.
+Relational databases don't have this feature and are constrained to single-valued fields only.
+When you're mapping a one-to-many association you can handle this using has many relationships,
+essentially using a foreign key for the single-valued end of the association.
+But a many-to-many association can't do this because there is no single-valued end to
+hold the foreign key.
+
+The answer is the classic resolution that's been used by relational data people
+for decades: create an extra table (an association table) to record the relationship.
+The basic idea is using an association table to store the association. This table
+has only the foreign key IDs for the two tables that are linked together, it has one
+row for each pair of associated objects.
+
+The association table has no corresponding in-memory object and its primary key is the
+compound of the two primary keys of the tables that are associated.
+In simple terms, to load data from the association table you perform two queries (in general, it may also be achieved using one query consisting of joins).
+Consider loading the SkillRecord collection for a list PlayerRecord objects.
+In this case, you do queries in two stages.
+The first stage queries the Players table to find all the rows of the players you want.
+The second stage finds the SkillRecord object for the related player ID for each row
+in the Player_Skills association table using an inner join.
+ The Prado Active Record design implements the two stage approach. For the
+Players-Skills M-N (many-to-many) entity relationship, we
+define a many-to-many relationship in the PlayerRecord class and
+in addition we may define a many-to-many relationship in the SkillRecord class as well.
+The following sample code defines the complete SkillRecord class with a
+many-to-many relationship with the PlayerRecord class. (See the PlayerRecord
+class definition above to the corresponding many-to-many relationship with the SkillRecord class.)
+
+The static $RELATIONS property of SkillRecord defines that the
+property $players has many PlayerRecords via an association table 'Player_Skills'.
+In array(self::MANY_TO_MANY, 'PlayerRecord', 'Player_Skills'), the first element defines the
+relationship type, in this case self::MANY_TO_MANY,
+the second element is a string 'PlayerRecord' that corresponds to the
+class name of the PlayerRecord class, and the third element is the name
+of the association table name.
+
+A list of player objects with the corresponding collection of skill objects may be fetched as follows.
+
+The method with_xxx() (where xxx is the relationship property
+name, in this case, Skill) fetches the corresponding SkillRecords using
+a second query (not by using a join). The with_xxx() accepts the same
+arguments as other finder methods of TActiveRecord.
+
+For self referenced association tables, that is, the association points to the same
+table. For example, consider the items table with M-N related
+item via the related_items association table. The syntax in the following
+example is valid for a PostgreSQL database. For other database, consult their respective documentation for
+defining the foreign key constraints.
+ The association table name in third element of the relationship array may
+contain the foreign table column names. The columns defined in the association
+table must also be defined in the record class (e.g. the $related_item_id property
+corresponds to the related_item_id column in the related_items table).
+ Using the with_xxx() methods will load the relationship record on demand. Retrieving the
+related record using lazy loading (that is, only when those related objects are accessed) can be
+achieved by using a feature of the TComponent that provides accessor methods. In particular,
+we define a pair of getter and setter methods where the getter method will retrieve the relationship
+conditionally. The following example illustrates that the PlayerRecord can retrieve its
+$skills foreign objects conditionally.
+ We first need to change the $skills=array() declaration to a private property
+$_skills (notice the underscore) and set it to null instead. This allows us
+to define the skills property using getter/setter methods
+(see Components for details). The getSkills()
+getter method for the skills property will lazy load the corresponding skills foreign record
+when it is used as follows. Notice that we only do a lazy load when its $player_id is
+not null (that is, when the record is already fetched from the database or player id was already set).
+ The setSkills() ensures that the skills property will always be a TList.
+Using a TList allows us to set the elements of the skills property as if they were
+arrays. E.g. $player->skills[] = new SkillRecord(). If array was used, a PHP error
+will be thrown.
+
+Since v3.1.1, Active Record starts to support column mapping. Column mapping allows developers
+to address columns in Active Record using a more consistent naming convention. In particular,
+using column mapping, one can access a column using whatever name he likes, rather than limited by
+the name defined in the database schema.
+
+To use column mapping, declare a static array named COLUMN_MAPPING in the Active Record class.
+The keys of the array are column names (called physical column names) as defined in the database
+schema, while the values are corresponding property names (called logical column names) defined
+in the Active Record class. The property names can be either public class member variable names or
+component property names defined via getters/setters. If a physical column name happens to be the same
+as the logical column name, they do not need to be listed in COLUMN_MAPPING.
+
+With the above column mapping, we can address first_name using $userRecord->firstName
+instead of $userRecord->first_name. This helps separation of logic and model.
+ <%# $this->Page->HighlightSearch($this->DataItem->text) %>Rekord Aktywny (ang. Active Record)
+Kiedy używać?
+
+
+Implikacje modelu
+Wspierane bazy danych
+
+
+Definiowanie Aktywnego Rekordu
+Ustanawianie połączenia z bazą danych
+Używanie application.xml w frameworku Prado
+Ładowanie danych z tablicy
+findByPk()
+ findAllByPks()
+ find()
+
+
+
+findAll()
+findBy*() and findAllBy*()
+findBySql() and findAllBySql()
+count()
+Inserting and updating records
+Deleting existing records
+deleteAll() and deleteBy*()
+Transactions
+Events
+Logging Example
+Active Record Relationships
+Foreign Key Mapping
+Has Many Relationship
+Has One Relationship
+Belongs To Relationship
+Parent Child Relationships
+Query Criteria for Related Objects
+Association Table Mapping
+Self Referenced Association Tables
+Lazy Loading Related Objects
+
+Column Mapping
+References
+
+
+
+
<%# $this->DataItem['type']%>: | +<%# $this->DataItem['name']%> | +