Skip to content

Commit

Permalink
minor typo pass
Browse files Browse the repository at this point in the history
  • Loading branch information
Ducasse committed Aug 23, 2024
1 parent 5e80c6e commit 278ce1e
Showing 1 changed file with 37 additions and 43 deletions.
80 changes: 37 additions & 43 deletions Chapters/Glorp/Glorp.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Glorp is a full-featured ORM which offers a number of features to reduce the _im

## Installation


### Database server

Before installing Glorp you should already have installed the RDBMS of your choice on your machine or a reacheable server, it could be [PostgreSQL (http://postgresql.org)](http://postgresql.org), [MySQL (http://dev.mysql.com/)](http://dev.mysql.com/), [SQLite (http://sqlite.org)](http://sqlite.org), or any other of your preference (as long it is supported). Hereafter we will refer to this RDBMS of your choice as the _Platform_.
Expand Down Expand Up @@ -51,7 +50,7 @@ There are plenty of drivers available in Pharo, however those drivers have
different API's making their use not directly interchangeable. Making it hard
to migrate to a different driver or to simultaneously support different RDBMS.

To solve that there is Garage \(aka _Garage Drivers_\), that provides a common
To solve that there is Garage (aka _Garage Drivers_), that provides a common
API for the different driver implementations. Garage is Pharo's analogous to
ODBC, JDBC or ADO.NET drivers.

Expand All @@ -66,18 +65,18 @@ because all the implemented drivers will conform to the common Garage API.
There are many drivers available drivers in different versions of Pharo, as
the time of writing this, these are the currently supported drivers are:

- P3 \(Native PostgreSQL v3 protocol\)
- P3 (Native PostgreSQL v3 protocol)
- Garage
- PostgreSQL \(Native\)
- MySQL \(Native\)
- PostgreSQL (Native)
- MySQL (Native)
- UDBC SQLite3


#### Glorp with P3

P3 is a modern, lean and mean PostgreSQL client for Pharo.

P3Client uses frontend/backend protocol 3.0 \(PostgreSQL version 7.4 \[2003\] and later\), implementing the simple query cycle. It supports plaintext and md5 password authentication. When SQL queries return row data, it efficiently converts incoming data to objects. P3Client supports most common PostgreSQL types.
P3Client uses frontend/backend protocol 3.0 (PostgreSQL version 7.4 [2003] and later), implementing the simple query cycle. It supports plaintext and md5 password authentication. When SQL queries return row data, it efficiently converts incoming data to objects. P3Client supports most common PostgreSQL types.

More information can be found at [its repository](https://github.com/svenvc/P3).
To load it first install it through Metacello.
Expand All @@ -104,16 +103,15 @@ Metacello new
```


It may be the case that you want to load Garage in an alpha version, in such case, you should load the most recent version instead of a stable version
that may be not defined for a alpha stream.
It may be the case that you want to load Garage in an alpha version, in such case, you should load the most recent version instead of a stable version that may be not defined for an alpha stream.

One package is the `Glorp-Core` and there is also a `Glorp-Tests` package.

#### Glorp with UDBC / SQLite3


Glorp may also be configured to work directly with the UDBC SQLite3
driver in Pharo 5 \(instead of the Garage drivers\):
driver in Pharo 5 (instead of the Garage drivers):

```
Gofer it
Expand Down Expand Up @@ -233,14 +231,14 @@ related to persistence and don't require you to inherit from a
particular class.

Glorp models all the involved concepts \(such as tables, columns, classes, etc.\)
as first class objects, and then links instances of those objects in a `DescriptorSystem`.
as first-class objects, and then links instances of those objects in a `DescriptorSystem`.
It is the core of a Glorp system, it holds all the Glorp metadata,
such as the Tables, Descriptors and Class Models.


By using a separate artifact \(in this case, a class\) to define all
the metadata of your system, you can decouple your business models
from their persistence information.
from their persistent information.
This separation of concerns is a good practice,
and helps with the maintainability of your code.

Expand Down Expand Up @@ -374,8 +372,8 @@ power of the Glorp orthogonal descriptor system, you describe everything and the


Assuming we haven't created the database tables externally, Glorp's metamodel
allows you to perform DDL \(_Data Definition Language_\) commands such as
`CREATE TABLE` or `CREATE CONSTRAINT` \(among others\) using plain
allows you to perform DDL (_Data Definition Language_) commands such as
`CREATE TABLE` or `CREATE CONSTRAINT` (among others) using plain
Pharo objects, and it can even determine when to run those.

To do that we must first connect to the database. We will explain how to do so in the following sections.
Expand Down Expand Up @@ -527,7 +525,7 @@ test the support of certain features, and so on.

In Pharo we have
`MySQLPlatform`, `OraclePlatform`, `PostgresPlatform`, `SQLServerPlatform`, `SQLite3Platform` and `UDBCSQLite3Platform`
as subclass of `DatabasePlatform`.
as a subclass of `DatabasePlatform`.



Expand Down Expand Up @@ -795,14 +793,14 @@ session commitUnitOfWork.

The message `commitUnitOfWorkAndContinue` needs some explanation,
but the concept is simple: It commits the current unit of work, and then
creates a new one migrating all the objects registered in the commited unit of
creates a new one migrating all the objects registered in the committed unit of
work to the newly created, and still open, unit of work. If this paragraph
confuses you, looking at its implementation might explain it better.

It is useful for cases like batch loads or updates,
where you want to commit changes every _n_ instances or similar.

Commiting and continuing the Unit Of Work:
Committing and continuing the Unit Of Work:
```
session beginUnitOfWork.
10 to: 99 do: [ :index |
Expand Down Expand Up @@ -834,9 +832,9 @@ session inUnitOfWorkDo: [
## Glorp Configurations and Additional Concepts


In our previous example we created a simple class that mapped _1:1_ with a
In our previous example, we created a simple class that mapped _1:1_ with a
table using simple data types, but Glorp provides many more features than
an _ActiveRecord_ like mapping. It lets you fine tune the persistence of
an _ActiveRecord_ like mapping. It lets you fine-tune the persistence of
your classes. We will go over the different configurations of class models,
table data types and constraints and mappings of all sorts.

Expand Down Expand Up @@ -906,14 +904,12 @@ GlorpBookDescriptorSystem >> classModelForPerson: aClassModel


Glorp also models your database objects, such as tables, constraints, indexes,
etc.. With this model it will be able to determine how to serialize the objects to
etc.. With this model, it will be able to determine how to serialize the objects to
SQL, how to perform joins to retrieve 1:1 or 1:n relations, and so on.

The descriptor system follows a convention to define the tables,
it uses the `tableForTABLENAME:` selector to configure `TABLENAME`, the
argument of this method is an instance of `DatabaseTable`, and this
method is responsible for describing your table in the relational
database, including field names and their data types, contraints \(primary keys
it uses the `tableForTABLENAME:` selector to configure `TABLENAME`, the argument of this method is an instance of `DatabaseTable`, and this
method is responsible for describing your table in the relational database, including field names and their data types, constraints \(primary keys
and/or foreign keys\), etc.

#### Adding fields to the table
Expand All @@ -934,7 +930,7 @@ As you can see, you can add a field by sending `createFieldNamed:type:` to
the table object. The first argument of the method is name of the field
\(aka _column_\) in your table, the second one is the datatype.

For the datatype we're not specifying any particular implementation of the type
For the datatype, we're not specifying any particular implementation of the type
but instead we send a message to the _platform_ object, and in Glorp jargon
the platform is the RDBMS we'll be using.

Expand Down Expand Up @@ -1011,7 +1007,7 @@ your class model you want to map to a field of a table.

Although many times they will be the same symbol, the argument you pass to
the `from:` parameter is not the symbol of the selector
but instead the name of attribute you have defined in your `classModelFor...:`
but instead, the name of the attribute you have defined in your `classModelFor...:`
method.

#### 1:1 relationships.
Expand All @@ -1038,7 +1034,7 @@ The Many to Many relationships is similar to the previous one, but in this case
the other side of the relation might _belong_ to more than one owner.
For instance, if you have Person and Tag, a Person might have many Tags,
but these tags in turn belong to other instances of Person.
In this case you use the `ManyToManyMapping` and also have to specify
In this case, you use the `ManyToManyMapping` and also have to specify
the _attributeName_.

From your the Pharo point of view, you will continue to see a regular collection
Expand All @@ -1057,9 +1053,9 @@ convenience subclasses of `RelationshipMapping`, and as such they share
common properties that can be modified.

For instance, the only difference between `OneToManyMapping` and
`ManyToManyMapping` is that the later is initialized to use a link table,
`ManyToManyMapping` is that the latter is initialized to use a link table,
but you can have a `OneToManyMapping` that uses a link table if you prefer,
you simple send `useLinkTable` to it.
you simply send `useLinkTable` to it.

#### Reference Classes.

Expand All @@ -1069,11 +1065,11 @@ used a lot, and is a convenience method that ends up modifying the attribute
in the ClassModel. So you can specify it at either place you find more
convenient.

Note we only define the class referenced, because the other side of the
Note we only define the class referenced because the other side of the
relationship is the class for which we're defining the mapping itself.

Other attribute common to all `RelationshipMapping` subclasses is that
you can specify how it is suppose to join with other tables, it is,
Other attributes common to all `RelationshipMapping` subclasses is that
you can specify how it is supposed to join with other tables, it is,
its `Join` object. More on this on the advanced section.

#### Exclusivity.
Expand Down Expand Up @@ -1134,7 +1130,7 @@ them believe they're something they're not!

Now that we explained in more detail the main parts of Glorp's descriptor system,
we're ready to extend our basic example, we're going to create a minimal
invoicing model to include the concepts just learnt.
invoicing model to include the concepts just learned.

We will
- define new Pharo class
Expand Down Expand Up @@ -1403,7 +1399,7 @@ The `orderBy:` attribute instructs
Glorp to read the elements from the database and _order_ \(aka _sort_\) them
by the field described in the block. This is useful so the collection that holds
the references to the items \(in this example\) is always sorted the same way,
because the order the rows come from the database is not always the same,
because the order of the rows comes from the database is not always the same,
and you can't trust they will return in the same order as they were written.

The `writeTheOrderField` command will make Glorp save the index of the
Expand Down Expand Up @@ -1670,14 +1666,14 @@ doesn't provide you with an API for that.
### The read: message

Everytime you sent a `read:` message to the session, the session created a
simple `Query` object to read the class passed as parameter as in the following expression.
simple `Query` object to read the class passed as a parameter as in the following expression.

```
(session read: Invoice) executeIn: session
```


But you can instantiate a Query object independently, configure it to fit your needs and
But you can instantiate a `Query` object independently, configure it to fit your needs and
execute it in the session. Enter the `Query` object!

### SimpleQuery
Expand Down Expand Up @@ -2274,7 +2270,7 @@ than in a `retrieve:` or `groupBy:`.

Because it uses `doesNotUnderstand:` as a way to build the expression tree,
it is possible that some selectors will be highlighted by Pharo as not
implemented, in particular salectors that are used to instantiate
implemented, in particular selectors that are used to instantiate
`FunctionExpression`'s.

### About special selectors
Expand Down Expand Up @@ -2321,7 +2317,7 @@ of the subclasses of `FunctionExpression`. It achieves it by rebuilding
the _archiver_ as it consumes the selectors, you can find how it does by
looking for the implementors of `rebuildOn:startingFrom:withOuterScopeBase:`.

In the middle of those implementors you'll find senders to
In the middle of those implementors, you'll find senders to
`getFunction:arguments:`, this in turn will query the _platform_
for the list of functions available, which will end up creating
the list of default functions by sending `createBasicFunctionsFor:`
Expand Down Expand Up @@ -2397,7 +2393,7 @@ entity integrity and referential integrity.

A primary key uniquely specifies a tuple within a table. In order for an attribute to be a good primary key it must not repeat. While
natural attributes \(attributes used to describe the data being entered\) are
sometimes good primary keys, surrogate keys are often used instead.
sometimes good primary keys, and surrogate keys are often used instead.

A surrogate key is an artificial attribute assigned to an object which uniquely
identifies it \(for instance, in a table of information about students at a
Expand Down Expand Up @@ -2484,18 +2480,16 @@ joins, right outer joins, and full outer joins, depending on which table's rows
are retained \(left, right, or both\).

The result of a left outer join \(or simply left join\) for tables A and B always
contains all records of the "left" table \(A\), even if the join-condition does
contains all records of the "left" table \(A\), even if the join condition does
not find any matching record in the "right" table \(B\). This means that if the ON
clause matches 0 \(zero\) records in B \(for a given record in A\), the join will
still return a row in the result \(for that record\)—but with NULL in each column
from B. A left outer join returns all the values from an inner join plus all
values in the left table that do not match to the right table, including rows
with NULL \(empty\) values in the link field.

For example, this allows us to find an employee's department, but still shows
employees that have not been assigned to a department \(contrary to the
inner-join example above, where unassigned employees were excluded from the
result\).
For example, this allows us to find an employee's department but still shows
employees that have not been assigned to a department (contrary to the inner join example above, where unassigned employees were excluded from the result).

### Data manipulation language \(DML\) queries

Expand Down

0 comments on commit 278ce1e

Please sign in to comment.