text:
# Backbone-relational
Backbone-relational provides one-to-one, one-to-many and many-to-one relations between models for [Backbone](https://github.com/documentcloud/backbone). To use relations, extend `Backbone.RelationalModel` (instead of the regular `Backbone.Model`) and define a property `relations`, containing an array of option objects. Each relation must define (as a minimum) the `type`, `key` and `relatedModel`. Available relation types are `Backbone.HasOne` and `Backbone.HasMany`. Backbone-relational features:

* Bidirectional relations, which notify related models of changes through events.
* Control how relations are serialized using the `includeInJSON` option.
* Automatically convert nested objects in a model's attributes into Model instances using the `createModels` option.
* Lazily retrieve (a set of) related models through the `fetchRelated(key<string>, [options<object>], update<bool>)` method.
* Determine the type of `HasMany` collections with `collectionType`.
* Bind new events to a `Backbone.RelationalModel` for:
	* addition to a `HasMany` relation (bind to `add:<key>`; arguments: `(addedModel, relatedCollection)`),
	* removal from a `HasMany` relation (bind to `remove:<key>`; arguments: `(removedModel, relatedCollection)`),
	* reset of a `HasMany` relation (bind to `reset:<key>`; arguments: `(relatedCollection)`),
	* changes to the key itself on `HasMany` and `HasOne` relations (bind to `update:<key>`; arguments=`(model, relatedModel/relatedCollection)`).

## Contents

* [Getting started](#getting-started)
* [Backbone.Relation options](#backbone-relation)
* [Backbone.RelationalModel](#backbone-relationalmodel)
* [Example](#example)
* [Known problems and solutions](#q-and-a)
* [Under the hood](#under-the-hood)

## Getting started

Resources to get you started with Backbone-relational:

* [A great tutorial by antoviaque](http://antoviaque.org/docs/tutorials/backbone-relational-tutorial/) ([and the accompanying git repository](https://github.com/antoviaque/backbone-relational-tutorial))

### Installation

Backbone-relational depends on [backbone](https://github.com/documentcloud/backbone) (and thus on  [underscore](https://github.com/documentcloud/underscore)). Include Backbone-relational right after Backbone and Underscore:

```html
<script type="text/javascript" src="./js/underscore.js"></script>
<script type="text/javascript" src="./js/backbone.js"></script>
<script type="text/javascript" src="./js/backbone-relational.js"></script>
```

Backbone-relational has been tested with Backbone 0.9.2 (or newer) and Underscore 1.3.1 (or newer).

## Backbone.Relation options

Each `Backbone.RelationalModel` can contain an array of `relations`.
Each relation supports a number of options, of which `relatedModel`, `key` and `type` are mandatory.
A relation could look like the following:

```javascript
Zoo = Backbone.RelationalModel.extend({
	relations: [{
		type: Backbone.HasMany,
		key: 'animals',
		relatedModel: 'Animal',
		collectionType: 'AnimalCollection',
		reverseRelation: {
			key: 'livesIn',
			includeInJSON: 'id'
			// 'relatedModel' is automatically set to 'Zoo'; the 'relationType' to 'HasOne'.
		}
	}]
});

Animal = Backbone.RelationalModel.extend({
	urlRoot: '/animal/'
});

AnimalCollection = Backbone.Collection.extend({
	model: Animal,

	url: function( models ) {
		return '/animal/' + ( models ? 'set/' + _.pluck( models, 'id' ).join(';') + '/' : '' );
	}
});
```

### relatedModel

Value: a string (which can be resolved to an object type on the global scope), or a reference to a `Backbone.RelationalModel` type.

### key

Value: a string. References an attribute name on `relatedModel`.

### type

Value: a string, or a reference to a `Backbone.Relation` type

Example: `Backbone.HasOne` or `'HasMany'`.

###### **HasOne relations (`Backbone.HasOne`)**

The key for a `HasOne` relation consists of a single `Backbone.RelationalModel`. The default `reverseRelation.type` for a HasOne relation is HasMany.
This can be set to `HasOne` instead, to create a one-to-one relation.

###### **HasMany relations (`Backbone.HasMany`)**

The key for a `HasMany` relation consists of a `Backbone.Collection`, containing zero or more `Backbone.RelationalModel`s.
The default `reverseRelation.type` for a HasMany relation is HasOne; this is the only option here, since many-to-many is not supported directly.

###### **Many-to-many relations**
A many-to-many relation can be modeled using two `Backbone.HasMany` relations, with a link model in between:

```javascript
Person = Backbone.RelationalModel.extend({
	relations: [
		{
			type: 'HasMany',
			key: 'jobs',
			relatedModel: 'Job',
			reverseRelation: {
				key: 'person'
			}
		}
	]
});

// A link object between 'Person' and 'Company', to achieve many-to-many relations.
Job = Backbone.RelationalModel.extend({
	defaults: {
		'startDate': null,
		'endDate': null
	}
})

Company = Backbone.RelationalModel.extend({
	relations: [
		{
			type: 'HasMany',
			key: 'employees',
			relatedModel: 'Job',
			reverseRelation: {
				key: 'company'
			}
		}
	]
});

niceCompany = new Company( { name: 'niceCompany' } );
niceCompany.bind( 'add:employees', function( model, coll ) {
		// Will see a Job with attributes { person: paul, company: niceCompany } being added here
	});

paul.get( 'jobs' ).add( { company: niceCompany } );
```

### keySource

Value: a string. References an attribute on the data used to instantiate `relatedModel`.

Used to override `key` when determining what data to use when (de)serializing a relation, since the data backing your relations may use different naming conventions.
For example, a Rails backend may provide the keys suffixed with `_id` or `_ids`. The behavior for `keySource` corresponds to the following rules:

1. When a relation is instantiated, the contents of the `keySource` are used as it's initial data.
2. The application uses the regular `key` attribute to interface with the relation and the models in it; the `keySource` is not available as an attribute for the model.

So you may be provided with data containing `animal_ids`, while you want to access this relation as `zoo.get( 'animals' );`.

**NOTE**: for backward compatibility reasons, setting `keySource` will set `keyDestination` as well.
This means that when saving `zoo`, the `animals` attribute will be serialized back into the `animal_ids` key.

**WARNING**: when using a `keySource`, you should not use that attribute name for other purposes.

### keyDestination

Value: a string. References an attribute to serialize `relatedModel` into.

Used to override `key` (and `keySource`) when determining what attribute to be written into when serializing a relation, since the server backing your relations may use different naming conventions.
For example, a Rails backend may expect the keys to be suffixed with `_attributes` for nested attributes.

When calling `toJSON` on a model (either via `Backbone.sync`, or directly), the data in the `key` attribute is transformed and assigned to the `keyDestination`.

So you may want a relation to be serialized into the `animals_attributes` key, while you want to access this relation as `zoo.get( 'animals' );`.

**WARNING**: when using a `keyDestination`, you should not use that attribute name for other purposes.

### collectionType

Value: a string (which can be resolved to an object type on the global scope), or a reference to a `Backbone.Collection` type.

Determine the type of collections used for a `HasMany` relation. If you define a `url(models<Backbone.Model[]>)` function on
the specified collection, this enables `fetchRelated` to fetch all missing models in one request, instead of firing a separate request for each.
See [Backbone-tastypie](https://github.com/PaulUithol/backbone-tastypie/blob/master/backbone_tastypie/static/js/backbone-tastypie.js#L92) for an example
of a `url` function that can build a url for the collection (or a subset of models).

### collectionKey

Value: a string or a boolean

Used to create a back reference from the `Backbone.Collection` used for a `HasMany` relation to the model on the other side of this relation.
By default, the relation's `key` attribute will be used to create a reference to the RelationalModel instance from the generated collection.
If you set `collectionKey` to a string, it will use that string as the reference to the RelationalModel, rather than the relation's `key` attribute.
If you don't want this behavior at all, set `collectionKey` to false (or any falsy value) and this reference will not be created.

### collectionOptions

Value: an options hash or a function that accepts an instance of a `Backbone.RelationalModel` and returns an option hash

Used to provide options for the initialization of the collection in the "Many"-end of a `HasMany` relation. Can be an options hash or
a function that should take the instance in the "One"-end of the "HasMany" relation and return an options hash

### includeInJSON

Value: a boolean, a string referencing one of the model's attributes, or an array of strings referencing model attributes. Default: `true`.

Determines how the contents of a relation will be serialized following a call to the `toJSON` method. If you specify a:

* Boolean: a value of `true` serializes the full set of attributes on the related model(s).
  Set to `false` to exclude the relation completely.
* String: include a single attribute from the related model(s). For example, `'name'`,
  or `Backbone.Model.prototype.idAttribute` to include ids.
* String[]: includes the specified attributes from the related model(s).

Only specifying `true` is cascading, meaning the relations of the model will get serialized as well!

### createModels

Value: a boolean. Default: `true`.

Should models be created from nested objects, or not?

### reverseRelation

If the relation should be bidirectional, specify the details for the reverse relation here.
It's only mandatory to supply a `key`; `relatedModel` is automatically set. The default `type` for a `reverseRelation` is `HasMany` for a `HasOne` relation (which can be overridden to `HasOne` in order to create a one-to-one relation), and `HasOne` for a `HasMany` relation. In this case, you cannot create a reverseRelation with type `HasMany` as well; please see [Many-to-many relations](#many-to-many) on how to model these type of relations.

**Please note**: if you define a relation (plus a `reverseRelation`) on a model, but never actually create an instance of that model, the model's `constructor` will never run, which means it's `initializeRelations` will never get called, and the reverseRelation will not be initialized either. In that case, you could either define the relation on the opposite model, or define two single relations. See [issue 20](https://github.com/PaulUithol/Backbone-relational/issues/20) for a discussion.

## Backbone.RelationalModel

`Backbone.RelationalModel` introduces a couple of new methods, events and properties.

### Methods

###### **getRelations `relationalModel.getRelations()`**

Returns the set of initialized relations on the model.

###### **fetchRelated `relationalModel.fetchRelated(key<string>, [options<object>], [update<boolean>])`**

Fetch models from the server that were referenced in the model's attributes, but have not been found/created yet.
This can be used specifically for lazy-loading scenarios.  Setting `update` to true guarantees that the model
will be fetched from the server and any model that already exists in the store will be updated with the retrieved data.

By default, a separate request will be fired for each additional model that is to be fetched from the server.
However, if your server/API supports it, you can fetch the set of models in one request by specifying a `collectionType`
for the relation you call `fetchRelated` on. The `collectionType` should have an overridden `url(models<Backbone.Model[]>)`
method that allows it to construct a url for an array of models.
See the example at the top of [Backbone.Relation options](#backbone-relation) or
[Backbone-tastypie](https://github.com/PaulUithol/backbone-tastypie/blob/master/backbone_tastypie/static/js/backbone-tastypie.js#L92) for an example.

### Methods on the type itself

Several methods don't operate on model instances, but are defined on the type itself.

###### **setup `ModelType.setup()`**

Initialize the relations and submodels for the model type. See the [`Q and A`](#q-and-a) for a possible scenario where
it's useful to call this method manually.

###### **build `ModelType.build(attributes<object>, [options<object>])`**

Create an instance of a model, taking into account what submodels have been defined.

###### **findOrCreate `ModelType.findOrCreate(attributes<string|number|object>, [options<object>])`**

Search for a model instance in the `Backbone.Relational.store`.

* If `attributes` is a string or a number, `findOrCreate` will just query the `store` and return a model if found.
* If `attributes` is an object, the model will be updated with `attributes` if found.
  Otherwise, a new model is created with `attributes` (unless `options.create` is explicitly set to `false`).

### Events

* `add`: triggered on addition to a `HasMany` relation.
  Bind to `add:<key>`; arguments: `(addedModel<Backbone.Model>, related<Backbone.Collection>)`.
* `remove`: triggered on removal from a `HasMany` relation.
  Bind to `remove:<key>`; arguments: `(removedModel<Backbone.Model>, related<Backbone.Collection>)`.
* `update`: triggered on changes to the key itself on `HasMany` and `HasOne` relations.
  Bind to `update:<key>`; arguments: `(model<Backbone.Model>, related<Backbone.Model|Backbone.Collection>)`.

### Properties

Properties can be defined along with the subclass prototype when extending `Backbone.RelationalModel` or a subclass thereof.

###### **subModelTypes**

Value: an object. Default: `{}`.

A mapping that defines what submodels exist for the model (the `superModel`) on which `subModelTypes` is defined.
The keys are used to match the [`subModelTypeAttribute`](#property-submodel-type-attribute) when deserializing,
and the values determine what type of submodel should be created for a key. When building model instances from data,
we need to determine what kind of object we're dealing with in order to create instances of the right `subModel` type.
This is done by finding the model for which the key is equal to the value of the
[`submodelTypeAttribute`](#property-submodel-type-attribute) attribute on the passed in data.

Each `subModel` is considered to be a proper submodel of its superclass (the model type you're extending),
with a shared id pool. This means that when looking for an object of the supermodel's type, objects
of a submodel's type can be returned as well, as long as the id matches. In effect, any relations pointing to
the supermodel will look for instances of it's submodels as well.

Example:

```javascript
Mammal = Animal.extend({
	subModelTypes: {
		'primate': 'Primate',
		'carnivore': 'Carnivore'
	}
});
var Primate = Mammal.extend();
var Carnivore = Mammal.extend();

var MammalCollection = AnimalCollection.extend({
	model: Mammal
});

// Create a collection that contains a 'Primate' and a 'Carnivore'.
var mammals = new MammalCollection([
	{ id: 3, species: 'chimp', type: 'primate' },
	{ id: 5, species: 'panther', type: 'carnivore' }
]);
```

Suppose that we have an `Mammal` model and a `Primate` model extending `Mammal`. If we have a `Primate` object with
id `3`, this object will be returned when we have a relation pointing to a `Mammal` with id `3`, as `Primate` is
regarded a specific kind of `Mammal`; it's just a `Mammal` with possibly some primate-specific properties or methods.

Note that this means that there cannot be any overlap in ids between instances of `Mammal` and `Primate`, as the
`Primate` with id `3` will *be* the `Mammal` with id `3`.

###### **subModelTypeAttribute**

Value: a string. Default: `"type"`.

The `subModelTypeAttribute` is a references an attribute on the data used to instantiate `relatedModel`.
The attribute that will be checked to determine the type of model that
should be built when a raw object of attributes is set as the related value,
and if the `relatedModel` has one or more submodels.

See [`subModelTypes`](#property-submodel-types) for more information.

## Example

```javascript
paul = new Person({
	id: 'person-1',
	name: 'Paul',
	user: { id: 'user-1', login: 'dude', email<EMAIL_ADDRESS>}
});

// A User object is automatically created from the JSON; so 'login' returns 'dude'.
paul.get('user').get('login');

ourHouse = new House({
	id: 'house-1',
	location: 'in the middle of the street',
	occupants: ['person-1', 'person-2', 'person-5']
});

// 'ourHouse.occupants' is turned into a Backbone.Collection of Persons.
// The first person in 'ourHouse.occupants' will point to 'paul'.
ourHouse.get('occupants').at(0); // === paul

// If a collection is created from a HasMany relation, it contains a reference
// back to the originator of the relation
ourHouse.get('occupants').livesIn; // === ourHouse

// the relation from 'House.occupants' to 'Person' has been defined as a bi-directional HasMany relation,
// with a reverse relation to 'Person.livesIn'. So, 'paul.livesIn' will automatically point back to 'ourHouse'.
paul.get('livesIn'); // === ourHouse

// You can control which relations get serialized to JSON (when saving), using the 'includeInJSON'
// property on a Relation. Also, each object will only get serialized once to prevent loops.
paul.get('user').toJSON();
	/* result:
		{
			email<EMAIL_ADDRESS>			id: "user-1",
			login: "dude",
			person: {
				id: "person-1",
				name: "Paul",
				livesIn: {
					id: "house-1",
					location: "in the middle of the street",
					occupants: ["person-1"] // just the id, since 'includeInJSON' references the 'idAttribute'
				},
				user: "user-1" // not serialized because it is already in the JSON, so we won't create a loop
			}
		}
	*/

// Load occupants 'person-2' and 'person-5', which don't exist yet, from the server
ourHouse.fetchRelated( 'occupants' );

// Use the 'add' and 'remove' events to listen for additions/removals on HasMany relations (like 'House.occupants').
ourHouse.bind( 'add:occupants', function( model, coll ) {
		// create a View?
		console.debug( 'add %o', model );
	});
ourHouse.bind( 'remove:occupants', function( model, coll ) {
		// destroy a View?
		console.debug( 'remove %o', model );
	});

// Use the 'update' event to listen for changes on a HasOne relation (like 'Person.livesIn').
paul.bind( 'update:livesIn', function( model, attr ) {
		console.debug( 'update to %o', attr );
	});

// Modifying either side of a bi-directional relation updates the other side automatically.
// Make paul homeless; triggers 'remove:occupants' on ourHouse, and 'update:livesIn' on paul
ourHouse.get('occupants').remove( paul.id );

paul.get('livesIn'); // yup; nothing.

// Move back in; triggers 'add:occupants' on ourHouse, and 'update:livesIn' on paul
paul.set( { 'livesIn': 'house-1' } );
```

This is achieved using the following relations and models:

```javascript
House = Backbone.RelationalModel.extend({
	// The 'relations' property, on the House's prototype. Initialized separately for each instance of House.
	// Each relation must define (as a minimum) the 'type', 'key' and 'relatedModel'. Options are
	// 'includeInJSON', 'createModels' and 'reverseRelation', which takes the same options as the relation itself.
	relations: [
		{
			type: Backbone.HasMany, // Use the type, or the string 'HasOne' or 'HasMany'.
			key: 'occupants',
			relatedModel: 'Person',
			includeInJSON: Backbone.Model.prototype.idAttribute,
			collectionType: 'PersonCollection',
			reverseRelation: {
				key: 'livesIn'
			}
		}
	]
});

Person = Backbone.RelationalModel.extend({
	relations: [
		{ // Create a (recursive) one-to-one relationship
			type: Backbone.HasOne,
			key: 'user',
			relatedModel: 'User',
			reverseRelation: {
				type: Backbone.HasOne,
				key: 'person'
			}
		}
	],

	initialize: function() {
		// do whatever you want :)
	}
});

PersonCollection = Backbone.Collection.extend({
	url: function( models ) {
		// Logic to create a url for the whole collection, or a set of models.
		// See the tests, or Backbone-tastypie, for an example.
		return '/person/' + ( models ? 'set/' + _.pluck( models, 'id' ).join(';') + '/' : '' );
	}
});

User = Backbone.RelationalModel.extend();
```

## Known problems and solutions

> **Q:** (Reverse) relations or submodels don't seem to be initialized properly (and I'm using CoffeeScript!)

**A:** You're probably using the syntax `class MyModel extends Backbone.RelationalModel` instead of `MyModel = Backbone.RelationalModel.extend`.
This has advantages in CoffeeScript, but it also means that `Backbone.Model.extend` will not get called.
Instead, CoffeeScript generates piece of code that would normally achieve roughly the same.
However, `extend` is also the method that Backbone-relational overrides to set up relations and other things as you're defining your `Backbone.RelationalModel` subclass.

For exactly this scenario where you're not using `.extend`, `Backbone.RelationalModel` has the `.setup` method, that you can call manually after defining your subclass CoffeeScript-style. For example:

```javascript
class MyModel extends Backbone.RelationalModel
	relations: [
		// etc
	]

MyModel.setup()
```

See [issue #91](https://github.com/PaulUithol/Backbone-relational/issues/91) for more information.

> **Q:** After a fetch, I don't get `add:<key>` events for nested relations.

**A:** This is due to `Backbone.Collection.reset` silencing add events. Pass `fetch( {add: true} )` to bypass this problem.
You may want to override `Backbone.Collection.fetch` for this, and also trigger an event when the fetch has finished while you're at it.
Example:

```javascript
var _fetch = Backbone.Collection.prototype.fetch;
Backbone.Collection.prototype.fetch = function( options ) {
	options || ( options = {} );
	_.defaults( options, { add: true } );

	// Remove old models
	this.reset();

	// Call 'fetch', and trigger an event when done.
	var dit = this,
		request = _fetch.call( this, options );
	request.done( function() {
			if ( !options.silent ) {
				dit.trigger( 'fetch', dit, options );
			}
		});

	return request;
};
```

## Under the hood

Each `Backbone.RelationalModel` registers itself with `Backbone.Store` upon creation (and is removed from the `Store` when destroyed).
When creating or updating an attribute that is a key in a relation, removed related objects are notified of their removal,
and new related objects are looked up in the `Store`.


text:
# [Kingdom Hearts V-Cast](index.md) - file types

| Extension | Description | Tool |
|-----------|-------------|------|
| bar | BREW Application Resource file: binary file that contains resource information, strings in menu controls, regional images |
| m3g | 3D model format also name of Mobile 3D Graphics API for J2ME |
| mid | MIDI music file |
| mif | Module Information File: provides application entry point for application. It's an application descriptor and provides information about external libs that the app needs for execution. |
| mod | Binary executable for Brew MP component, it's signed and stored in the component's home directory. |
| pmd | sound effects? |
| png | picture files |
| dat |     |
| sig | Signature file |

[Link to BREW documentation](https://developer.brewmp.com/resources/tech-guides/programming-model/brew-mp-programming-concepts-and-terminology/brew-mp-application-files)

repository: OpenKH/OpenKh

branch_name: refs/heads/master

extension: md

gha_language: C#

license_type: permissive

repo_name: OpenKH/OpenKh


text:
# Craft Starter
Boilerplate for Craft CMS projects with Docker as development environment

## Getting Started

This repository is to be used to start a new craft project:

1. Copy the repository's contents into a local directory, and `cd` into the local repository path

    - Using [degit](https://github.com/Rich-Harris/degit#readme) (recommended):
    ```
    degit github:yoannisj/craft-starter <path/to/project-directory>
    cd <path/to/project-directory>
    ```

    - Using git clone:
    ```
    git clone --depth=1 https://github.com/yoannisj/craft-starter.git <path/to/project-directory>
    cd <path/to/project-directory>
    ```

2. Duplicate the `.env.example` file and rename your copy to `.env`.

    ```
    cp .env.example .env
    ```

3. Choose a database driver by changing the `COMPOSE_FILE` variable in your `.env` file:

    - mysql: `COMPOSE_FILE=./docker-compose.yml:./services/database/mysql/docker-compose.override.yml`
    - mariadb: `COMPOSE_FILE=./docker-compose.yml:./services/database/mariadb/docker-compose.override.yml`
    - postgresql: `COMPOSE_FILE=./docker-compose.yml:./services/database/postgres/docker-compose.override.yml`

    **Note**: the database specific docker-compose file will also override some of the environment variables populated in the php containers, so Craft CMS knows which database driver to use.

4. Create a security key used for the project's crypotography, and assign it to the `SECURITY_KEY` environment variable.

    **Note**: the security key must be shared on development, staging and production environments, so make sure you use a strong key from the start. We recommend to use a random  alphanumeric string of 48 characters long, which you can generate using a a service such as https://passwordsgenerator.net/.

5. Enable local HTTPS and virtual hostname (optional)

    - Choose a virtual hostname (e.g. `myproject.test`) and assign it `WEB_HOSTNAME` environment variable in your local `.env` file
    - Add the virtual hostname to your local computer's `hosts` file and point it to `<IP_ADDRESS>`
    - Create SSL certificate files for your virtual hostname with [mkcert](./docs/dev/ssl-mkcert-certificates.md), or [openssl (self-signed)](./docs/dev/ssl-openssl-certificates.md)
    - Update the `LOCAL_SSL_KEY_FILE` and `LOCAL_SSL_CERT_FILE` environment variables in your local `.env` file to point to the newly created SSL files in `services/ssl`

6. Additionally to the environment variables edited above, you may want to override the following variables in the `.env` file to better reflect your project:

    - `PUBLIC_PORT_PREFIX` - Set this to a number between `1` and `5`, which will be used as a prefix to all ports exposed on your local computer by docker
    - `APP_ID` - Set this to a handle string that represents your craftcms project instance (e.g. `myproject_craftcms`)
    - `ENVIRONMENT` - Set this to `development` on your local computer so you can run the project in development mode
    - `DATABASE_NAME` - Set this to a string that represents your craftcms project instance (e.g. `myproject_craftcms_localdev`)
    - `DATABASE_TABLE_PREFIX` - Change this if your production database already contains data from another craft CMS project

7. Run `docker-compose run --rm craft-web composer update` to update all composer dependencies and update your project's `composer.lock` file.

8. Run `docker-compose run --rm craft-cli install` to install Craft in your local database

9. Run `docker-compose down && docker-compose up -d` to start the docker containers running your craft project locally

10. Visit http://localhost:8080/admin in your browser and log in with the admin user account to start fiddling!

    **Note**: the local URL to your project differs if you enabled HTTPS and a virtual hostname in previous steps
    **Note**: the username and password to access the admin area are the ones you created during craft installation in previous steps

## Development Environment

This project uses docker as a development environment, relying on the docker-compose services described below.

The services use the project's own images, which are based on debian/ubuntu in order to minimise discrepancies with the production environment. The images' `Dockerfile`s and configuration files are saved in the project's `docker` repository.

- The `httpd` service provides the local web-server, used to serve static files from the project's `web` folder, and forwarding dynamic `.php` requests to the `craft-web` service.

- The `craft-web` service is responsible for handling dynamic web-requests with PHP-FPM, forwarded by the httpd web-server to Craft-CMS's `web/index.php` script file. Craft-CMS, its dependencies and plugins are installed on this service's image with Composer.

- The `craft-cli` service can be used to run commands from Craft's CLI. It is using the same docker image as the `craft-web` service, and runs commands in the same Craft-CMS instance. To run a Craft CLI command, use `docker-compose run --rm craft-cli <command-name>`.

- The `craft-queue` service is responsible for running background jobs with the PHP CLI. It is using the same docker image as `craft-web`, and therefore runs jobs from the same Craft-CMS instance. In order to discover and run jobs in Craft-CMS's queue, it runs the `craft queue/listen` command behind the scenes.

- The `db` service provides a maria-db server, and is where Craft CMS's dynamic data is stored.

- The `redis` service provides a redis server, used to store Craft CMS's session and cache data in memory for an extra performance boost.

- The `ngrok` service can be used to expose your project's local web-server publicly with [ngrok](https://ngrok.com/), and share previews that can be accessed by co-workers on their own devices, or by external web-services (e.g. services that need to call craft controller action URLs).

#### composer.json

- map the namespace of your custom craft modules to their base file path in the composer.json file's `autoload.psr-4` field
- add repositories to your custom composer packages to the `repositories` key

## TODO

- add asset compilation and bundling service (using gulp.js, vite.js or laravel mix)
- separate environment variables into service-speficic .env files (e.g. `.craft.env`, `.db.env`, etc.)
- move docs to the `docs/dev` sub-folder and reserve the Readme.md file for the project itself
- use docker secrets for passwords and other cryptographic keys for encryption/authentication
- ensure depending services are also removed when running `docker-composer run --rm service_name`
- further abstract down the `ngrok` service to support other web-tunneling services
- implement git deployment to runcloud and/or laravel-forge with github actions
- document installation and deployment on runcloud/laravel-forge servers

## References

The following articles were used as references to build this project, and contain further information about the project's setup and practices:

- https://mattgrayisok.com/a-craft-cms-development-workflow-with-docker-part-1-local-development
- https://mattgrayisok.com/logging-from-craft-cms-in-docker
- https://mattgrayisok.com/craft-cms-in-docker-https-ftw
- https://nystudio107.com/blog/an-annotated-docker-config-for-frontend-web-development
- https://blog.amosti.net/local-reverse-proxy-with-nginx-mkcert-and-docker-compose/

license: Unlicense

repository: yoannisj/craft-starter

branch_name: refs/heads/main

repo_name: yoannisj/craft-starter


text:
# Canceling

Some of Hazelcast .NET client operations support cancellation via a `CancellationToken`. This section details what actually happens when that token is cancelled.

## Default Operations

When a `CancellationToken` is passed to a method that triggers a server-side operation, the token is ultimately passed to the internal method which sends the request message to the server. At that point:
* If the token is cancelled before the request has been sent, the request is not sent
* If the token is cancelled while retrying to send a request, the retry is aborted

Otherwise, the request message is sent as a whole non-cancellable operation, and the client then waits for a response message from the server. It the token is cancelled during this wait, the wait is aborted and the response message will be ignored when it is received.

> [!WARNING]
>Note however that, since the request message *has* been sent, the resulting server state is unspecified: the operation *may* have been executed and is *not* rolled back.

## Sql Operations

This section details cancellation behaviors specific to SQL. Refer to the  [SQL documentation](sql.md) for more general information on SQL.

### Sql Queries

Sql queries (see @Hazelcast.Sql.ISqlService `ExecuteQueryAsync` method) fetch the first page of rows, and return an enumerable @Hazelcast.Sql.ISqlQueryResult object representing an open *server-side* query. This query remains open and running on the server, in order to provide more pages of rows.

The `CancellationToken` which is passed to `ExecuteQueryAsync`, if any, works just as with any other server operation as far as fetching the first page of rows is concerned (see above). In addition, it is also passed to the `ISqlQueryResult`.

> [!NOTE]
> If the operation is cancelled before the `ISqlQueryResult` is returned, the SQL service tries its best to notify the server that the query should be closed.

The `ISqlQueryResult` is `IAsyncEnumerable<SqlRow>`. This means that one can either:
* Invoke its `GetAyncEnumerator(CancellationToken enumerationToken)` method
* Enumerate it with `async foreach`, with  `.WithCancellation(CancellationToken enumerationToken)`

In both cases, the enumeration ends up being controlled by a `CancellationToken` which is either `token` (from `ExecuteQueryAsync`), `enumerationToken`, or a combination of both. If `token` or `enumerationToken` is canceled, the enumeration is canceled and throws an `OperationCancelledException`.

It is important to understand that the `ISqlQueryResult` represents a server-side query which needs to be closed in order to release server resources. This is achieved by async-disposing the `ISqlQueryResult` (which is `IAsyncEnumerable`).

If the result is enumerated with `await foreach`, the pattern guarantees that the enumerator will be disposed when exiting. This will, in turn, dispose the result. Should the enumeration be cancelled and abort with an exception, the result would therefore safely be disposed.

With other patterns, it is important to ensure that, in the event of a cancellation, the result is always disposed. This can be achieved by wrapping the `ISqlQueryResult` in a `using` block:

```csharp
await using var result = await client.Sql.ExecuteQueryAsync(...);
```

### Sql Commands

Sql commands (see @Hazelcast.Sql.ISqlService `ExecuteCommandAsync` method) do not have a special result type, as they only return the number of affected rows, and therefore the `CancellationToken` works just as with any other server operation.

> [!WARNING]
> Because Sql commands can have side-effect on the server, and cancellation may happen before or after the request message has been sent to the server, it is important to understand that cancellation concerns the client-side async method call only, and that the command may or may not execute on the server.

repository: hazelcast/hazelcast-csharp-client

repo_name: hazelcast/hazelcast-csharp-client


text:
---
layout: post
author: Matt Dancho
categories:
- Code-Tools
tags:
- R-Bloggers
- Learn-R
- R
title: 'ggdensity: A new R package for plotting high-density regions'
date: 2022-07-21T06:00:00.000-04:00
excerpt: 'As data scientists, it can be downright impossible to drill into messy data.
  Fortunately, there''s a new R package that helps us focus on a "high-density region".
  It''s called ggdensity. '
image: "/assets/ggdensity_thumb_2.jpg"
image_preview: "/assets/ggdensity_thumb_2.jpg"

---
**As data scientists, it can be downright impossible to drill into messy data.** Fortunately, there's a new R package that helps us focus on a _"high-density region"_, which is simply an area in a scatter plot defined by a high percentage of the data points. It's called `ggdensity`.

![](/assets/ggdensity_thumb_3.jpg)

High Density Regions on a Scatter Plot

In this R-tip, I'm going to show you how to hone in on high-density regions **under 5-minutes:**

1. Learn how to **make high-density scatter plots** with `ggdensity`
2. **BONUS:** Make faceted density plots to drill into over-plotted high-density region data

# R-Tips Weekly

This article is part of R-Tips Weekly, a weekly video tutorial that shows you step-by-step how to do common R coding tasks. Pretty cool, right?

Here are the links to get set up. 👇

Get the Code

YouTube Tutorial

# Video Tutorial

I have a companion video tutorial that shows even more secrets (plus mistakes to avoid).

# What you make in this R-Tip

By the end of this tutorial, you'll use of high density regions to make insights from groups within your data. For example, here we can see where each  Class of Vehicle compares in terms of engine displacement (displ) and highway fuel economy (hwy), answering questions like:

* Is vehicle class a good way to describe vehicle clusters?
* Which vehicle classes have the greatest variation in highway fuel economy versus displacement?

Do you see how powerful `ggdensity` is?

![](/assets/ggdensity_facet_hdr_2.jpg)

Uncover insights with ggdensity

# Thank You Developers.

Before we move on, please recognize that `ggdensity` was developed by [James Otto](https://github.com/jamesotto852), Doctoral Candidate at the Department of Statistical Science, Baylor University. Thank you for everything you do! Also, the full documentation for `ggdensity` can be [accessed here](https://jamesotto852.github.io/ggdensity/).

## Before we get started, get the R Cheat Sheet

`ggdensity` is great for extending ggplot2 with advanced features. But, you'll need to learn `ggplot2` to take full advantage. For these topics, I'll use the [Ultimate R Cheat Sheet](https://www.business-science.io/r-cheatsheet.html) to refer to `ggplot2` code in my workflow.

### Quick Example:

[Download the Ultimate R Cheat Sheet](https://www.business-science.io/r-cheatsheet.html). Then **Click the "CS" hyperlink** to "ggplot2".

Now you're ready to quickly reference the `ggplot2` cheat sheet. This shows you the core plotting functions available in the ggplot library.

![ggplot2 cheat sheet](/assets/2021-08-12-ggalt-dumbbell-plots/ggplot2_cheatsheet.jpg)

Onto the tutorial.

# `ggdensity` Tutorial

Let's dive into using `ggdensity` so we can **show you how to make high-density regions on your scatter plots**.

**Important:** All of the data and code shown can be accessed through our Business Science [**R-Tips Project**](https://learn.business-science.io/r-tips-newsletter).

Plus I have a **surprise** at the end (for everyone)!

## 💡 Step 1: Load the Libraries and Data

### First, run this code to **load the R libraries:**

Load `tidyverse` , `tidyquant`, and `ggdensity`.

![](/assets/ggdensity_01_libraries_2.jpg)

 Get the code.

### Next, run this code to **pull in the data**.

We'll read in the `mpg` data set that was comes with ggplot2.

![](/assets/ggdensity_02_data.jpg)

 Get the Data.

We want to understand how highway fuel economy relates to engine size (displacement) and to see if there are clusters by vehicle class.

## 💡 Step 2: Make a basic ggplot

Next, make a basic `ggplot` using the following code. This creates a scatter plot with the colors that change by vehicle class. I won't go into all of the mechanics, but you can [download my R cheat sheet](https://www.business-science.io/r-cheatsheet.html) to learn more about ggplot and the grammar of graphics.

![](/assets/ggdensity_03_ggplot_basic.jpg)

 Get the code.

Here's what the plot looks like. **Do you see how it's really tough to pull out the clusters in there?** Each of the points overlap which makes understanding the group structure in the data very tough.

![](/assets/ggdensity_03_ggplot_basic_scatter.jpg)

## Step 3: Add High Density Regions

Ok, now that we have a basic scatter plot, we can make a quick alteration by adding high density regions that capture 90% and 50% of the data. We use `geom_hdr(probs = c(0.9, 0.5, alpha = 0.35)` to accomplish the next plot.

![](/assets/ggdensity_04_ggplot_hdr.jpg)

 Get the code.

Let's see what we have here.

![](/assets/ggdensity_04_ggplot_hdr_2_scatter.jpg)

We can now see where the clusters have the highest density. But there's still a problem called **"overplotting"**, which is when too many graphics get plot on top of each other.

# 💡 BONUS: Overplotting solved!

**Here's the problem we're facing: overplotting.** We simply have too many groups that are too close together. Let's see how to fix this.

The fix is pretty simple. Just use facetting from ggplot2.

![](/assets/ggdensity_05_ggplot_facet.jpg)

 Get the code.

And, voila! We can easily inspect the clusters by vehicle class.

![](/assets/ggdensity_05_ggplot_facet_plot.jpg)

# 💡 Conclusions

You learned how to use the `ggdensity` library to create high-density regions that help us understand the clusters within our data. Great work! **But, there's a lot more to becoming a Business Scientist.**

If you'd like to become a Business Scientist (and have an awesome career, improve your quality of life, enjoy your job, and all the fun that comes along), then I can help with that.

{% include cta_struggles_rtrack.md %}


text:
# Guidelines for Getting Help with UserFrosting

**Before** you open a new issue or ask a question in chat, you **must** read these guidelines.  If it is evident from your issue that you failed to research your question properly, your issue may be closed without being answered.

## Troubleshooting

There are a few common stumbling blocks that new users face when setting up UserFrosting for the first time.  If you are new to the current version of UserFrosting, please first look at the [basic requirements and installation instructions](https://learn.userfrosting.com/basics/requirements/basic-stack).

If you don't find what you're looking for in the troubleshooting page, then please check the [wiki](https://github.com/userfrosting/UserFrosting/wiki) and [existing issues](https://github.com/alexweissman/UserFrosting/issues?utf8=%E2%9C%93&q=is%3Aissue), both opened and closed.  Your question may have already been asked and answered before!

You can also search for help on Stack Overflow or in our [Forums](https://forums.userfrosting.com/).  In addition to the tags for the components that UF builds upon, such as [Slim](http://stackoverflow.com/questions/tagged/slim), [Twig](http://stackoverflow.com/questions/tagged/twig), [Eloquent](http://stackoverflow.com/questions/tagged/eloquent), [jQuery Validate](http://stackoverflow.com/questions/tagged/jquery-validate), [Select2](http://stackoverflow.com/questions/tagged/jquery-select2), there is now a [UserFrosting tag](http://stackoverflow.com/questions/tagged/userfrosting) as well.

There are also tags for the utilities upon which UserFrosting depends, such as [Composer](http://stackoverflow.com/questions/tagged/composer-php) and [Git](http://stackoverflow.com/questions/tagged/git).

## Asking for Help

In general, the Github issue tracker should only be used for bug reports and feature requests.  If you're just having trouble getting something to work, you should ask on Stack Overflow or in our [Forums](https://forums.userfrosting.com/) instead. Tag your question with the `userfrosting` tag, and optionally with any tags specific to the relevant underlying technologies, such as `slim`, `twig`, `eloquent`, `composer`, etc.  You should also mention the version of UserFrosting that you are using.

After posting a question on Stack Overflow or in our [Forums](https://forums.userfrosting.com/), please [link to it in chat](https://chat.userfrosting.com).  This will ensure that more people see it, and provide a place where we can discuss and help clarify your question.

On Github, Chat, and Stack Overflow, please keep in mind the following:

1. Remember that courtesy and proper grammar go a long way. Please take the time to craft a **precise, polite issue**. We will do our best to help, but remember that this is an open-source project - none of us are getting paid a salary to develop this project, or act as your personal support hotline :wink:

2. Report any errors in detail.  Vague issues like "it doesn't work when I do this" are not helpful.  Show that you have put some effort into identifying the cause of the error.

3. There are three main places where you may find error messages:

- Backend (PHP-related) fatal errors: in your PHP error log. This is usually a file called `php_error_log` or something like that. In XAMPP, the default location of this file is `XAMPP/xamppfiles/logs/`. For other web hosting platforms, please consult the documentation or do a quick Google search (i.e. "where is the php error log in _____"). Some web hosts may provide a special interface for accessing the php error log, through ssh, cpanel, etc. Please ask them directly for help with this.

- Non-fatal PHP errors will be logged in your UserFrosting error log.  Look for your `app/logs/errors.log` file.

- Frontend (Javascript-related) errors: in your browser's Javascript console. See [this guide](https://learn.userfrosting.com/background/client-side) to using your browser console.

You should also try testing your code in a local development environment, to separate **code-related** issues from **server** issues.  In general, we recommend that you install a local development server on your computer, rather than [testing your code directly on the production server](https://pbs.twimg.com/media/BxfENwpIYAAcHqQ.png).  This means you can test your code directly on your own computer, making development faster and without the risk of exposing sensitive information to the public.  We recommend installing [XAMPP](https://www.apachefriends.org) if you don't already have a local server set up.

## Contributing to the Codebase

We welcome your technical expertise!  But first, please join us in [chat](https://chat.userfrosting.com) to discuss your proposed changes/fixes/enhancements before you get started.  At least one member of our development team will usually be around.

Please also be sure to read our [style guidelines](../STYLE-GUIDE.md).

When it's time to integrate changes, our git flow more or less follows http://nvie.com/posts/a-successful-git-branching-model/.

### Branches

#### `master`
The current release or release candidate.  Always numbered as `major.minor.revision`, possibly with an `-alpha`, `-beta` or `-RC` extension as well. Commits should **never** be send directly on this branch.

#### `hotfix`
Contains the next bug fix release, typically matching the next `revision` version.  Any changes not introducing a breaking change can be committed to this branch. Always numbered as `major.minor.revision`.

When ready, changes should be merged into both **master** and **develop**.

#### `develop`
Contains breaking changes that will need to wait for the next version to be integrated. Typically matched the next `minor` version. Always numbered as `major.minor.x`.

When ready, changes should be merged into both **master** and **hotfix**.

#### `feature-*`
New features that introduce some breaking changes or incomplete code should be committed in a separate `feature-{name}` branch.

When ready, the branch should be **[squashed-merged](https://github.com/blog/2141-squash-your-commits)** ([guide](https://stackoverflow.com/a/5309051/445757)) into `develop` (or `hotfix` if it doesn't introduce a breaking change).

### Releases

After every release, the `hotfix` branch (and possibly `develop`, for minor/major releases) should immediately be version-bumped.  That way, new changes can be accumulated until the next release.

When a new version is created, the version number need to be changed in `app/define.php`. `CHANGELOG.md` should also be updated and the associated tag should be created on Github.

#### Alpha/beta/RC releases

During alpha/beta/RC, a release candidate always sits on the `master` branch. During the alpha/beta phase, major changes can still be integrated into `master` from `develop`. However, this should bump the revision number instead of the minor/major number. During RC, only _hotfixes_ can be merged into `master`.

## Working together

### Issues

Issues are used as a todo list. Each issue represent something that needs to be fixed, added or improved. Be sure to assign issues to yourself when working on something so everyones knows this issue is taken care of.

Issues are tagged to represent the feature or category it refers to. We also have some special tags to help organize issues. These includes:

 - [`good first issue`](https://github.com/userfrosting/UserFrosting/labels/good%20first%20issue): If this is your first time contributing to UserFrosting, look for the `good first issue` tag. It's associated with easier issues anyone can tackle.

 - [`up-for-grabs`](https://github.com/userfrosting/UserFrosting/labels/up-for-grabs): Theses issues have not yet been assigned to anybody. Look for theses when you want to start working on a new issue.

 - [`needs discussion`](https://github.com/userfrosting/UserFrosting/labels/needs%20discussion) : This issue needs to be discussed with the dev team before being implemented as more information is required, questions remain or a higher level decision needs to be made.

 - [`needs more info`](https://github.com/userfrosting/UserFrosting/labels/needs%20more%20info): More information is required from the author of the issue.

### Milestones

In order to keep a clear roadmap, milestones are used to track what is happening and what needs to be done. Milestones are used to classify problems by:
- Things that need to be done ASAP
- Things we are doing right now
- Things we will probably do soon
- Things we probably will not do soon

**Things that need to be done ASAP**: this is the highest priority and this milestone should always be empty. Issues related to important bug fixes should be set on this milestone immediately. The milestone always refers to the next version of _revision_, also known as the next bugfix version.

**Things we are doing right now**: this is the "main" milestone we are currently working on. Usually represents the next `minor` version, but may also represent the next major version when the focus is on the next major release.

**Things we’ll probably do soon**: It's a "Next Tasks" milestone. These tasks will be addressed in the near future, but not close enough for the next version. Usually represents the second minor revision **and** the next major release.

**Things we probably won’t do soon**: We refer to these issues and sometimes look through them, but they are easy to ignore and sometimes intentionally ignored. Represent issues without milestones that do not have a defined timeframe.

To maintain a clear history of progress on each milestone, milestones must be closed when completed and the corresponding version released. A new milestone must then be created for the next release. In addition, the milestone version must be updated when new versions are released.

## Learn documentation

The [Learn Documentation](https://learn.userfrosting.com) should always be updated along side code changes.

Changes to the [learn repository](https://github.com/userfrosting/learn) should follow the same logic as the main repository, ie. any changes applied to the `hotfix` branch should be documented in the learn `hotfix` branch. This also apply to `feature-*` branches.

Additionally, the `learn` repository can have `dev-*` for learn specific features and fixes.

## Building the API documentation

To build the API documentation, install [phpDocumentor](https://www.phpdoc.org) globally and then run from the UserFrosting root :

```
phpdoc
```

The resulting documentation will be available in `api/`.

## Automatically fixing coding style with PHP-CS-Fixer

[PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) can be used to automatically fix PHP code styling. UserFrosting provides a project specific configuration file ([`.php_cs`](.php_cs)) with a set of rules reflecting our [style guidelines](../STYLE-GUIDE.md). This tool should be used before submitting any code change to assure the style guidelines are met. Every sprinkles will also be parsed by the fixer.

PHP-CS-Fixer is automatically loaded by Composer and can be used from the UserFrosting root directory :

```
app/vendor/bin/php-cs-fixer fix
```

## Useful tools

If you are using **Atom**, be sure to checkout theses useful packages :
 - [Docblockr](https://atom.io/packages/docblockr) : Used to generate [documentation block](https://github.com/userfrosting/UserFrosting/blob/master/STYLE-GUIDE.md#documentation).
 - [php-ide-serenata](https://atom.io/packages/php-ide-serenata) : Integrates [Serenata](https://gitlab.com/Serenata/Serenata) as PHP IDE, providing autocompletion, code navigation, refactoring, signature help, linting and annotations.

license: MIT

repository: userfrosting/UserFrosting

gha_language: PHP

gha_license_id: NOASSERTION

repo_name: userfrosting/UserFrosting


text:
# Augeas and Config::Model

- author: Markus Raab
- guid: eca69e19-5ddb-438c-ac06-57c20b1a9160
- pubDate: Mon, 22 Oct 2014 17:31:42 +0200

A common question is: now we have Augeas for editing config files,
why do we need Elektra, Config::Model or something else?

First, it is clear that Augeas is a huge step forward and improved
configuration of Linux systems, especially when used with centralized
configuration management tools.

Augeas, in short, introduces a special-purpose programming language that
allows to transform configuration files into configuration trees and
back. This transformation is it strength (so it is easy to add support
for a particular legacy configuration files), but also it weakness (the
mapping is implementation-defined by a language that is limited to a bit
more than regular expressions). Augeas is not able nor is it intended
to provide more abstraction over the configuration files. Instead Augeas
mirrors the structure of the configuration as closely as possible.

Elektra’s goal, instead, is not only to provide access to legacy
configuration files, but to provide access to the configuration
exactly as the programs itself uses it. So with Elektra, the developers of
applications are part of Elektra’s ecosystem by providing specifications
how their configuration should look like and by writing plugins that
define how the configuration is accessed and checked. Ideally, after
some time of legacy issues and migration, developers will also not
have to care about writing plugins anymore, but just use any available
ones (and users of their application can choose any other compatible
plugin).  What is about to stay is a specification that defines the
application's configuration, e.g. in INI (could be any syntax):

    [/yourapp/file_dialog/show_hidden_files]
    type=Boolean
    default=true

allows other applications to reuse your setting show_hidden_files by
referring to above specification. So Elektra not only abstracts from
cross-platform-related issues with an consistent API, but also allows
us to be aware of other applications' configurations, leveraging easy
application integration.

Config::Model shares most of Elektra’s goals, especially those regarding
validation (you saw the type=Boolean above) and having a unified
interface for all programs (this feature is unavoidable with any such
approach). The projects mainly differs that Elektra is supposed to be used
by the programs themselves (and not only by GUIs and validation tools)
and that Elektra uses self-describing data: the specification itself
is also in Elektra’s key database, stored in metadata and e.g. below
system/elektra/mountpoints. In Elektra validators can be
written in any language (because the specification is just data)
and can enforce constraints on any access (because plugins define
the behaviour of the key database).

# 0.8.7 release

- author: Markus Raab
- date: 28.07.2014

Again, we managed to have a great feature release with dozens of
corrections!

## New Features

Thanks to Manuel Mausz for further improving lua, python3 bindings
and the new python2 bindings.

The GSoC efforts have their first large contribution to Elektra, the 3
way merge finally arrives with this release. It is still a long way to
go, however, because augeas plugins can only be mounted with a
workaround and the package integration of the 3-way merge is still in
its infancy. More information about GSoC and its progress can be found
[here](http://community.libelektra.org/wp).

A special thanks to  Felix Berlakovich for his contributions to the
3-way merge, including meta merging, conflict resolving strategies and
extensive testing.

Additionally, he added the plugins keytometa, ini and greatly improved
the glob plugin. These plugins are technical previews and will receive
some improvements in the next release, too.

Now a script for tab completion is available
[here](/scripts/scripts/kdb-bash-completion), again thanks to Felix
Berlakovich.

The contextual values now got a [tutorial]
(https://github.com/ElektraInitiative/libelektra/tree/master/src/tools/gen)
and small fixes.

## Corrections

Thanks to Pino Toscano for fixing a lot of spelling errors, simplify
RPATH setting, respect $HOME and $TMPDIR, improvements of test cases,
and his debian-packaging efforts.

In the kdb tool not allowed subfolders are now checked properly
and the output of warnings comes before output of the error.
This fixes the problem that in the case of a longer list of
warnings one did not see the error anymore.

Fix compilation warnings on clang and gcc 4.9.
Also improve test coverage on kdb tool and some plugins.

Fix kdb import/export for some plugins (Should now work with any storage
plugin again).

kdb run_all should run flawlessly with this release. Remaining problems
with not installed test data were fixed. kdb run_all also checks if the
test cases do not modify any existing key and keeps a backup if this
happened.

Some remaining mem leaks in rare circumstances were fixed. Valgrind
should now never report any leaks, if it does, please report the issue.

## API Changes

Added delMeta() for C++, because setMeta() with NULL will set the
number 0 and not remove the meta.

Arguments of isBelow, isDirectBelow, isBelowOrSame are swapped for
better readability. k.isBelow(root) now means the obvious thing.
The change only effects the C++ binding, keyIsBelow is unaffected by
the change.

## Documentation

[Specification of metadata](doc/specification.ini) and
[contracts](doc/contracts.ini) written/greatly improved.

[Decisions](decisions) are introduced again.

Most often the KeySet is ideal, e.g. when doing full iteration or when
performing set operations. In some cases, however, a hierarchical data
structure fits better. This is especially true for GUIs. Luckily, Keys
can be in multiple data structures because of their reference counting.

## Other Stuff

We now fully embrace github:
- We use its issue tracker (all issues from local text files were moved
  there)
- We have rewritten many READMEs to use githubs markdown
- On pull requests the build server checks if the merge would break
  the build.
- All previous gitorious users are now at github. (Most had an account
  anyway)

Raffael Pancheri also made progress with its qt-gui. It now features a
model that implements great parts of Elektra’s features. Unfortunately
the model cannot be serialised and thus changes cannot made persistent.
Also undo and other important use-cases are still not there. The GUI
looks very clean and was evaluated in a SUS study on 23.07.2014.
The current implementation can be found [here]
(https://github.com/0003088/qt-gui).

Many distributions already have Elektra packages
 - [Fedora](https://admin.fedoraproject.org/pkgdb/package/elektra/)
 - [Gentoo](http://packages.gentoo.org/package/app-admin/elektra)
 - [Arch Linux](https://aur.archlinux.org/packages/elektra/)

In some distributions Elektra packages are available, but are not
up-to-date. Pino Toscano is working on get them (actually
Debian, but others are derived from it) up-to-date.
 - [Ubuntu](https://launchpad.net/ubuntu/+source/elektra)
 - [Debian](https://packages.debian.org/de/wheezy/libelektra3)
 - [Linux Mint](http://community.linuxmint.com/software/view/elektra)

A special thanks to Kai-Uwe Behrmann for providing packages for
[CentOS, Fedora, OpenSUSE, RHEL and
SLE](http://software.opensuse.org/download.html?project=home%3Abekun&package=elektra).

## Get It!

You can download the release from:

http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.7.tar.gz
size: 1566800
md5sum: 4996df62942791373b192c793d912b4c
sha1: 00887cc8edb3dea1bc110f69ea64f6b700c29402
sha256: 698ebd41d540eb0c6427c17c13a6a0f03eef94655fbd40655c9b42d612ea1c9b

already build API-Docu can be found here:

https://doc.libelektra.org/api/0.8.7/html/

Best regards,
Markus

-------------

Date: 21.06.2014
Subject: Move to Github, Code Coverage Report

The Elektra Initiative moved to Github for following reasons:

- We were seriously missing a bug tracker
- It may make collaboration easier
- Build Server Integration:
 - [Build on MergeRequests](https://build.libelektra.org/job/elektra-mergerequests/)
   waits for the first merge request to be built!
 - And the build status is now published [for this job](https://build.libelektra.org/job/elektra-gcc47-all/)

The main entrance point and URL for any advertisement and linking stays

  http://www.libelektra.org

(which points to github at the moment)

Additionally (not related to github), we now have a
[LCOV code coverage report](https://doc.libelektra.org/coverage/latest/)!

best regards,
Markus

Subject: 0.8.6 Release

Hello List,

this release adds both many improvements and some technical previews.

== Improvements ==

The hosts plugin got documentation and several bug fixes.
Multiline comments now remove the comment start sequences within
the metadata comment.
Additionally the kdb tool has an improved error message on invalid
filenames. (thanks to Manuel Mausz)

Fix a issue that the resolver plugin did not delete tmpfile in some
error situations and add testcases with error plugin.

Fix KS_END in C++ that did not specify the namespace.

"kdb run_all" will now run all tests using Elektra from your system.
Because not all testdata will be installed, some testcases fail unless
you copy the data manually. Those are:
testmod_yajl testmod_augeas testmod_fstab testmod_hosts test_xml

Virtually all clang compiler warnings were fixed
(thanks to Felix Berlakovich).

kdb mv now is atomic. (API was used wrongly in the tool)

Clang, icc and gcc are now all supported and tested.

== Technical Previews==

A plugin that logs write operations and errors via the native
journald interface was added (thanks to Felix Berlakovich).

A preview of the augeas plugin was added. In cmake add "augeas" to PLUGINS
and then run "kdb info augeas" for further instructions. Additionally,
see Outlook below (thanks to Felix Berlakovich).

A preview of python3 and lua bindings were added. In cmake enable the
options BUILD_SWIG BUILD_SWIG_LUA BUILD_SWIG_PYTHON so that they are
compiled (thanks to Manuel Mausz).

The code generator was extended to support contextual values, more
information about that topic later.

The libtools library is back to life again! It has the same idea as its
predecessor, but it is much more powerful. Because of the plugin system
libtools is able to export and import any configuration format
Elektra supports. Additionally it adds support for mounting backends.
While most of its functionality is mature, the API is not final, though.

== API Changes ==

The API and ABI is as always backwards-compatible within the 0.8 series.

This time it is, however, not forward-compatible (that means programs
linked against 0.8.6 might not work with 0.8.5), because ksAtCursor()
was added.

ksAtCursor() provides the means for an external iterator. This
was immediately exploited by an implementation of the C++
iterators. These new C++(11) (reverse)iterators allow multi-pass
algorithm over the same KeySet.

ksSort was in the kdb.h header file, even though it never was
needed nor available in 0.8. Automatic compatibility checkers may
wrongly tell that the API is not compatible, but this is not the case
(thanks to Manuel Mausz).

The C++ API changed, including:
- does not wrongly convert garbage to default types using ```get<T>```
- getMeta now interally uses ```get<T>``` and both throw the
  KeyTypeConversion Exception
- KeySet::at directly allows one to use ksAtCursor()
- KeyTypeConversion (or former KeyBadMeta) is not thrown anymore if key
  is not available
- Key::hasMeta allows one to directly check if metadata is available

CMake: ENABLE_CXX11 is now default OFF (because gcc 4.6 and older won't
       work with it). It disables some tests, though.
unique_ptr will automatically be used instead of auto_ptr in this mode.

Note for maintainers: libelektratools now needs to be installed so that
the kdb tool will work.

== Outlook ==

One drawback of Elektra is the small number of available storage
plugins. While writing storage plugins isn't too hard, it still requires
knowledge of Elektra’s plugin architecture. In addition it is always
necessary to keep both translation directions in mind (from file to
Elektra and back).  In order to mitigate this issue Felix Berlakovich
is working on an Elektra storage plugin which uses Augeas [1] to read
and manipulate configuration files. Augeas uses a concept called lenses
to translate between files and abstract trees (i.e. trees that hide
unimportant details like whitespaces). In brief, what makes lenses special
is the fact that they automatically disallow translations that cannot be
reversed. This means that one of the translation directions comes for free
as it is implicitly described by the other one. Therefore writing lenses
is much simpler than programming both directions explicitly as done in
traditional Elektra storage plugins.  Furthermore many lenses for common
applications like Apache, MySQL, DHCPd and many more [2] already exist.
Besides these benefits, Augeas lacks many features of Elektra. Although
this is mostly intended because Augeas aims to concentrate just on
configuration file manipulation some of these features would be valuable
for administrators and developers. Some of these mentioned Elektra
features include but are not limited to: logging of all configuration
changes done, transformation of character encoding as needed, import and
export of configuration data in any format, e.g. XML or JSON (Augeas has
a similar feature for XML), file conflict detection and several different
validations for configuration options (see [3] for a full list of
features). With the Augeas storage plugin these features cannot be used
with only the applications already integrated into Elektra, but with all
applications for which lenses exist.  This storage plugin targets system
administrators as well as developers, that wish to take advantage of
Elektra’s features, but were unable to do so because of missing plugins. If
no lens exists already, writing a new one requires neither programming
skills nor knowledge of Elektra’s plugin architecture. Furthermore,
implementing a new configuration file format is just a matter of writing a
lens instead of writing a full-fledged parser.
[1] http://augeas.net/
[2] http://augeas.net/stock_lenses.html
[3] http://www.libelektra.org

Since Elektra is written in C, integration is limited to projects
written in C and languages compatible with C like C++. In order to
change this situation Manuel Mausz is working on the implementation of
language bindings using two different techniques.  The first technique
uses SWIG as a generic generator for various languages. In a nutshell,
SWIG is a compiler that takes C/C++ declarations and creates the wrappers
needed to access those declarations from other languages. The second
technique is called GObject Introspection. In contrast to SWIG, GObject
Introspection generates a language independent metadata file. For dynamic
languages the GObject Introspection support in the target language will
load this metadata file to generate bindings at run-time. In order to
provide bindings for static languages a compiler on the metadate file
will be used. This is comparable to using SWIG. Manuel will focus on
implementing language bindings for Python and Lua though both techniques
will support various other languages.  As language bindings only allow
to call into Elektra’s API Manuel will also embed the interpreters of
both Python and Lua into two generic plugins. Using these plugins in
combination with the languages bindings it will be fully possible to
write plugins for Elektra in languages other than C/C++.

While Elektra offers sophisticated methods to store and manipulate
configuration, currently there is only a command line tool (kdb)
available to interact with the database. This requires the user to study
and learn the possible commands and does not allow free exploration of the
options of the application.  To enable new ways to interact with Elektra,
Raffael Pancheri is designing and implementing a Graphical User Interface
(GUI). To increase the probability to create a GUI that is indeed usable
and beneficial, Pancheri is following the design principles proposed by
Ben Shneiderman and Jakob Nielson.

Finally, as you already noticed, Ian Donnelly is working on a semantic
3-way merge to make distribution and package upgrades smoother.
This is done as GSOC project. The progress is documented here:
http://community.libelektra.org/wp/

== Get It! ==

You can download the release at:
 http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.6.tar.gz
 size: 1188337
 md5sum: 4a59824e70a29295e9ef9ae7605d9299
 sha1: 2570710b0057470223611ca00d61a0196e54e7b2
 sha256: e815cf69b070c339784472841aa0ee0b169fab7c78f41cbbd7044f53fa9ed216

Docu can be found here:
 https://doc.libelektra.org/api/0.8.6/html/

You can install the debian packages for debian (wheezy, amd64 only,
some packages will be added later) by adding following lines to your
/etc/apt/sources.list:
 deb http://markus-raab.org/ftp/wheezy wheezy main

and install or upgrade the packages with:
 sudo apt-get update
 sudo apt-get install libelektra-core4 libelektra-full4 libelektra-bin libelektra-dev libelektra-test libelektra-xmltool4 libelektra-json4 libelektra-dbus4 libelektra-doc

Best regards,
Markus

-------------

0.8.5 Release

In this release, again, amazing features wait for you.

kdb tool now smoothly integrates external tools. These tools can reside
in external source repositories and even written in other programming
languages. The approach is similar from "git". Any executable in the
folder, given with the CMake Cache variable TARGET_TOOL_EXEC_FOLDER
(default "/usr/lib/elektra/tool_exec"), can be executed by

   kdb name

All tests (script+compiled) now install in this folder instead of
directly to /usr/bin to minimise cluttering folders in the user's PATH.

The CMake variable TOOLS, similar to PLUGINS, now allows you to decide
which tools should be built and installed. Default is "kdb" only.

The first new tool that makes use of this feature creates a powerful
alternative to directly use Elektra’s API. The tool "gen", executed with
"kdb gen" can generate code and documentation for your specific
application with your specific types. The code includes getopt parsing
(short+long options), high level getter and setter in C and C++. The
documentation includes html, doxygen and troff (manpages). The
full implications of this holistic approach cannot be summarised in
one paragraph, but they include better type safety and especially
much faster development. Give it a try, examples are included in the
folder "src/tools/gen" (see Makefile) and external tools using it will
be released soon
(see https://gitorious.org/elektra-tools/elektra-tools/).

For the code generation clear mappings from Elektra’s type system to
C/C++11 types are needed. The new header file kdbtypes.h introduces
these mappings using CORBAs mappings for types -- except wchar_t was not
included, because imho it is useless to have a wide char as long it is
not clear if it is 16 or 32 bits. But also included are including enum
and string types.

Unfortunately, the freedesktop-resolver features for OpenICC have to be
moved to the next release.

The documentation's installation directory now can be configured more
fine-grained (the old TARGET_DOCUMENTATION_FOLDER is gone):
TARGET_DOCUMENTATION_HTML_FOLDER
TARGET_DOCUMENTATION_LATEX_FOLDER
TARGET_DOCUMENTATION_MAN_FOLDER

Man pages now have the default location /usr/share/man/man3 and all
man pages are in namespace 3elektra to not conflict with other man
pages.

Test data for the test cases will be installed, too. The path can be
configured with:
TARGET_TEST_DATA_FOLDER
The path allows one to run tests from an installed version.

Additionally, many small bugs were fixed. The release is, as always,
100% binary and API compatible, so you can drop it in and all
applications continue to work.

You can download the release at:
 http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.5.tar.gz
 size: 1193948
 md5sum: 6fe4a48d70cefc04c04639e5d85a0ddc
 sha1: 7e26ce19a186d96091bfc0ec3ce4013991082a1c
 sha256: 4ff9fc35ce9354d3bfe7877ae7ac3426621952c974feaab8d1ad20f72c4fb9ce

Docu can be found here:
 https://doc.libelektra.org/api/0.8.5/html/

You can install the debian packages for debian (wheezy, amd64 only;
gen tool, and "all" package will be added later) by
adding following lines to your /etc/apt/sources.list:
 deb http://markus-raab.org/ftp/wheezy wheezy main

and install or upgrade the packages with:
 sudo apt-get update
 sudo apt-get install libelektra-core4 libelektra-full4 libelektra-bin libelektra-dev libelektra-test libelektra-xmltool4 libelektra-json4 libelektra-dbus4 libelektra-doc

---------------

0.8.4 Release

I am proud to announce this amazing feature release!

Elektra now speaks json!
From this release on, Elektra has full read and write capabilities
towards the world of json. json is a very popular serialization format
which is originated in Javascript.
It is very similar to the already existing tcl plugin, which also works
like a parser without intermediate data structures. But unlike the tcl
plugin, where a grammar was written, the blazing fast yajl library was
used.

Elektra now has convention for arrays!
Multiplicity is a very common need within configuration. Json specifically
has syntactic support for it. Up to now Elektra used different conventions
for arrays. E.g. Mountpoints name their plugins #0-#9, and fstab had
#00-#99 lines. These approaches
always limited to  number of predefined elements.

The new convention solves the problem: #0-#9 (unmodified to be compatible
with mountpoints) is followed by #_10-#_99, continuing with #__100 -
#__999 and so on. It gets a bit long for large arrays, but they are
supposedly not edited by hand anyway.  This approach has the big advantage
that it works without modifying the sort order for the KeySet., which
cannot be done for two reasons:

1.) Backwards compatibility: It would break applications which count on
5 being ordered after 12. The compatibility problem could be tackled in
Elektra 0.9, but:

2.) Slower comparison is the main issue. Elektra heavily depends on
comparing keys. It is needed for inserting, lookups and other KeySet
operations.
Currently comparison is done by strcmp() which is highly optimized on
most platforms. When numbers need some special handling, strcmp() could
not be used anymore.

POSIX compatibility and handling of multi-process conflicts has
been improved. Now the HOME environment variable will be used. The
old behaviour (USER environment variable) is still available as
fallback. Additionally there is a fallback for embedded systems to the
hard coded variant. In case of these fallbacks a warning will be added.

A new plugin uname was added. It allows you to mount the functionality
of uname within Elektra’s key-value namespace. Currently it is read-only
and needs POSIX.

The built-in description of plugins, especially for new plugins, was
extended and improved. It is now also possible to output the description
by:
 kdb info <plugin> description
e.g.
 kdb info yajl description
 (the rebase plugin mentioned there did not made it into the release)

Two new kdb commands were added:
 kdb file
allows you to print out the configuration file where a given key is located.

 kdb sget
guarantees you to get a value which is handy in shell scripts.

Now a large test suite makes sure that the kdb tool works without
troubles. Many bugs, especially concerning resolver and mounting, were
fixed. The list is way too long to put it here, see git log for details.

The build server now has a job searching for TODOs:
 https://build.libelektra.org/job/elektra-todo/

The latest documentation from git master is also build there and the
results are published here:
 https://doc.libelektra.org/api/latest/html

The current release is always documented at:
 https://doc.libelektra.org/api/current/html

To get exactly this version you can look at:
 https://doc.libelektra.org/api/0.8.4/html

You can download the release at:
 http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.4.tar.gz
 size: 1153568
 md5sum: 247498bf77e6c60b02d67d32e69fc963
 sha1: 32ef1f5f31956c43bda1494c864012c98a930f75
 sha256: 06be5ebe240f8c0cbbafb30dc061176760a5c66a1675165af2736c15923c84c2

You can install the debian packages for debian (wheezy, amd64 only) by
adding following lines to your /etc/apt/sources.list:
 deb http://markus-raab.org/ftp/wheezy wheezy main

and install or upgrade the packages with:
 sudo apt-get update
 sudo apt-get install libelektra-core4 libelektra-full4 libelektra-bin libelektra-dev libelektra-test libelektra-xmltool4

---------------

Roadmap

Exciting times for software integration for free operating systems:
After some years of more or less deep sleep I will reactivate the
initiative so that we finally can lay a foundation for a truly integrated
system. During my PhD I will have time to remove the larger barriers and
tackle some fundamental problems.

The targets will be:
- Embedded: Elektra is on the frontier for embedded systems because of
  its tiny core and the many possibilities with its plugins.
- Server: Elektra is ideal suited for a local configuration storage by
  mounting existing configuration files into the global tree. Nodes
  using Elektra can be connected by already existing configuration
  management tools.
- Desktop: Elektra allows applications to read and write from a global
  configuration tree. Missing is a description (schema) so that these
  values actually can be shared.

Quality Goals will be:
- Extensibility: Requirements for configuration can vary a lot.
  The only common dominator are key-value pairs, nearly everything else
  can differ from project to project. So Elektra needs to be, and is,
  very extensible to fulfil this wide range of goals.
- Simplicity: The system should be very simple in its core so that it
  can be understood easily. Complexity should be hidden in optional
  extensions. The full system should work out-of-the-box as much as
  possible. With these properties it should also be as safe and
  fault-tolerant as possible.
- Performance: Features will not be used if they impact performance too
  hard. So Elektra and it's extensions are designed to perform well with
  a minimum amount of syscalls with an emphasis on retrieving configuration
  fast.

The roadmap for Elektra’s implementation has three steps:

1.) Elektra 0.8
Is the current stable release branch. It will get continuous development
with releases at least every two month. They focus will be on stability,
better user experience, integration of new programming languages and
more serialise formats.
Some ideas:
- serialiser: e.g. json, using lenses
- resolver: e.g. xdg with improved locking
- testing: automated abi compatibility checks, shell test suite
- bindings: gobject, swig
- more tutorials and explanations
- more advertisement (e.g. conferences)
- creating applications using Elektra
- schema for configuration
- more tool support, e.g. GUIs
- and much more...
(see also doc/todo/CURRENT and doc/todo/TODO in repo)

If you are interested in working on one of these topics, please contact me.
It will also be possible for students to write a thesis solving problems
concerning those ideas.

2.) Elektra 0.9 (starting around 2014)
This will be a development branch which will coexist next to 0.8. In it
all features will emerge which are too large for the 0.8 branch, like
changes in the core and the plugin system. Some of them might be "boring
and academical" :-)
The branch will lead to releases which can be considered as technology
previews. They will be most likely not intended to be used in a
production environment.
Some ideas:
- allow plugins to be first level citizens
- allow plugins to nest in each other
- allow non-file based plugins
- Next generation of type system allowing user defined types, subtypes,
  units and constraints
- Next generation of contracts which allow recursive nesting and
  auto-negotiation of capabilities
- and much more...
(see also doc/todo/FUTURE in repo)

Those tasks will be done by me, but ideas and discussions are always
appreciated.

3.) Elektra 1.0
This will basically a stable snapshot of 0.9 when there is no doubt that
Elektra can be extended without breaking your (the customers) way to
deal with configuration.
Some ideas:
- API cleanup
- build an environment around the libraries
- build sharing platforms for configuration
- extend the foundations created in 0.9
- and much more...

More information will be published soon, so stay tuned.

---------------

0.8.3 Release

This release mostly brings improvements in the release process, the test framework and
new debian packages.

A benchmark showed that rereading the same database only needs
about 2ms and the syscalls needed are quite optimal.

The debian folder is now removed from master repository,
but instead a release and debian branch was created.
See doc/GIT for new policy of branches.
Thanks to Christian Amsüss<EMAIL_ADDRESS>for all tips, suggestions and help.
The git branches are done like in arandr.
0.8.2 was skipped because a git tag was placed wrongly
when the new release scheme was tried out on Monday June
18 2012.
The tag was removed later.

kdb export now works nicely, use
 kdb export <path> simpleini
to show key = value pairs.
Additionally kdb umount was added.

A cmake bug was fixed, so that "make test" now
works immediately.

The kdbconfig.h and kdbos.h received some needed cleaning
up. The HAVE_ macros are now set correctly by cmake, Elektra’s
macros are prefixed with KDB_ and not needed macros were
removed.

Some docu was improved and some typos fixed.
Thanks to Erkan Yilmaz<EMAIL_ADDRESS>for
two fixes.

The test framework now has built-in support for comparing keysets and
keys together with its metadata. Because of usage of macros the
linenumber will be stated correctly for comparison.

Additionally also a script test framework was started.

The documentation was updated and improved at some places.

The build system was improved. Now also ALL, NODEP or DEFAULT are
accepted as magic values for a list of plugins.

Most of the tests run automatically on a buildserver:
https://build.libelektra.org/

It gives you an good impression with how many different compilers elektra
is currently tested. Elektra now also compiles with clang.

You can download the release at:
http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.3.tar.gz
md5sum: d6b1d668a1a1e155137d4ebc1bd0d5d7
sha256: 48fab82a6b1e8f0038c43ae9ade4da25b697d0aa74e39b7b94056ab7febc4be1

You can install the debian packages for debian squeeze (i386 and amd64 only) by
adding following lines to your /etc/apt/sources.list:
deb     http://build.libelektra.org/debian/ elektra-release-glue main
deb-src http://build.libelektra.org/debian/ elektra-release-glue main

and install all or some of the packages with:
sudo apt-get install libelektra-core4 libelektra-full4 libelektra-bin libelektra-dev libelektra-test libelektra-xmltool4

Have fun!

---------------

0.8.1 Release

The 0.8.1 brings some bugfixes and many small improvements.

The only new feature is that "kdb export" can now be used with any
storage plugin.  This is useful for backups, but also as replacement of
the former "kdb-ls -l" which showed keys and values.
 kdb export <name> simpleini
now does this job. For a full export of system configuration to xml,
you can use:
 kdb export system xmltool

The "kdb get" and "kdb getmeta" tool now support -n and --no-newline to
suppress the newline at the end of the output.

The cmake installation paths got a overhaul and are now documented
more properly in COMPILE.  Noteworthy is that plugins and include files
can also be installed directly in the system library or include path.
Additionally the build system now handles multiarch systems by supporting
LIB_SUFFIX.

FindPackage of cmake and pkgconfig remain the best methods to use elektra
from external application. New are the examples for such projects in
the folder "external".

The -H and --help support of the kdb tool were still improved, some typos
fixed and some information updated. Additionally the warning output got
some cleanup to be less confusing.

The user experience was improved. The ".kdb" or ".config" directory now
will be created if they do not exist.

The debian packages are now split to have full advantage of the
new plugin system.  The core packages (libelektra, libelektra-dev and
libelektra-bin) do not depend on libxml anymore.  New is the package
libelektra-full, which contains a single dynamic library containing all
plugins statically.  A repository will be announced separately.

There was also some cleanup of old files, like the old highlevel-api
(which does not exist anymore). Finally the API documentation, especially
for plugin developers, was improved.

---------------

0.8.0

Finally it is done, 0.8.0 is finished.
Even though it has a very similar API to 0.7.0
(see APICHANGES) the implementation changed
paradigm-shifting.
0.8.0 introduces a completely new plugin framework,
which allows you to check types and structure
of the keys, notify by dbus, log to syslog,
change the way how filenames are resolved and change
the configuration format and files at run-time.

The C-API, like defined in
 src/include/kdb.h
and also the one to plugins, as defined in
 src/include/kdbplugin.h
is considered to be stable within this 0.8.0 release.

Elektra has a new presence at freedesktop, see
 http://www.freedesktop.org/wiki/Software/Elektra

Download it from:
http://www.markus-raab.org/ftp/elektra/releases/elektra-0.8.0.tar.gz
ftp://www.markus-raab.org/elektra/releases/elektra-0.8.0.tar.gz

---------------

0.7.0

Finally it is done, the 0.7.0 API is finished.
The API covers everything shown in kdb.h and all
releases in 0.7.0 will be 100% ABI and API compatible
supported for at least a year.

Some bugs might break that rule, but there should not be
left many anymore, because every method is at least checked
twice and most have hundred of test cases.
Please report any bugs you find to http://bugs.libelektra.org
- portability and build bugs
- mistakes, misspelling in documentation

This is not valid for kdb-tools, there are lots of bugs
remaining there and a rewrite would be very useful.

For that reason there will be a separate release for
kdb-tools, libelektratools and the backend interface.

The stable APIs of libelektratools and the backend interface
will be announced separately, but they will be part of 0.7.x.

kdb-tool and kdbedit and so will also have separate
releases, but because they are not a library there
is no API or ABI issue there.

Pages related to 0.7.0:
http://www.libelektra.org/GetStartedMounting
http://www.libelektra.org/Tutorial
http://www.libelektra.org/API-Changes0.7
http://www.libelektra.org/Changes0.7

Marketing issues:
- Freshmeat announcment
- Sourceforge upload
- API docu upload
- forums
- newsgroups
- other mailinglists

Download it from:
http://www.markus-raab.org/ftp/elektra-0.7.0.tar.gz
ftp://www.markus-raab.org/elektra-0.7.0.tar.gz

---------------

0.7.0rc5 The last release candidate before 0.7.0

I am proud to present the finished  0.7.0 external API in
kdb.h [0].

A lot changed to 0.6.10 but the fundamentals are clearer then
ever before: 3 Classes with their methods, a clear, easy and
mature API. It is very hard to use it wrong but you get
best results with very short code:

http://www.libelektra.org/Tutorial

Other parts are not finished, like libelektratools, the
kdb-tool and the backend interface. They are not part of
the official 0.7 release and get their own release later.

The reasons to release within the next week are:
 - The API is finished
 - Oyranos needs a stable release from elektra
 - the last release is long ago
 - unstable has been much more stable than stable since some time
 - there have been no commits to the stable branch since
   unstable existed
 - Elektra grows just too complex to wait for all parts to finish

Now some highlights from one month of work from 333 ChangeLog
lines:
 - many many bugs were fixed
 - the core completely compiles with -ansi -pedantic -std=c99
 - all code compiles with -Wall -Werror
 - the test-suite is now complete
 - much cleaner infrastructure within the code
 - many autoconf/automake issues fixed
 - static, dynamic building, linking with defaults backends
   everything works!
 - many new options to stat and remove all keys and so on..
 - environment variables and passwd database allow subtle
   influence of where the user configuration resides
 - kdb info now prints where configuration lies on hard disc

---------------

0.7.0rc4 - 12.05.2008
I am proud to present the fourth release candidate of elektra
0.7.0.

It is now possible to enable and disable Backends and Bindings
with configure switches. The documentation was improved.
The c++ binding now basically works, see the tests for examples.
Ini and Berkleydb backends now compile again.
There were a lot of bug fixes, like mntent.h fix for macOS.

---------------

0.7.0rc3 - 24.04.2008
Call for 0.7 finish

Unfortunately there is not much response about the 0.7 release
candidates but there is still a lot to do to have a mature
library worth to be announced as stable.

Specifically there are following things to do and we really need
help to achieve that faster than end of this year:

There are now only 3 backends working well tested but undistinguished
in handling error scenarios. At least 3 more Backends are needed
also tested in real world applications. Favoured are existing but
not ported backends like berkleydb, ini, winregistry and uniconf.

Working bindings have a lot meaning in how complete and useful
the API is. It would be preferable to have at least 3 bindings
working with at least an example application like kdb-tool.
They could be cpp, python and one open.

A lot of bug squashing is left open. Please don't hesitate to open
and fix more bugs on http://bugs.libelektra.org.

Documentation is not yet completely updated to 0.7. Especially the
homepage has a lot of outdated information, but also the API documentation
needs another eye on it and the tutorial needs a rewrite.

There might be some licencing issues in some parts of elektra,
everything should be BSD, if you find something please open a bug.

A partial blocker is the kdb-tool, where a rewrite would be nice but
is not necessary for 0.7 (the library counts not the environment).

Other things like portability are taken seriously but are not blockers,
they can be fixed later too.

What is really good working in elektra is the infrastructure like
svn, homepage, bug tracking, many thanks to José Luis Tallón for
that!

Now some words about 0.7.0rc3:

Version macros were added to have static information about
the elektra version compiled against. There were many
enhancements in the C++ Binding, the Key Class is now
quite well complete.

While writing the C++ binding I realized that there is need
for keyInc() the opposite of keyDel() to increase the
viability of a key object.

keyVNew() and ksVNew() were added to make it possible to pass
the va_list from the C++ binding.

The blocker bug that libelektra assumes system/elektra/mountpoints
to exist was solved, many thanks to Patrick Sabin. The tests
now work without any preloading without memory leaks.

And lots of bug fixes (Many thanks to Kai-Uwe Behrmann):
- sed changed for macosx compatibility
- fixed signature ssize_t ksToStream
- also set CXXFlags
- fix wrong parent at end in ksToStream
- fix return value of successful kdb import
- string is default type for xml without type=""
- fix extra_dist some missing files
- remove , at end of enumeration lists

The svn id is unstable@1352:
https://svn.libelektra.org/svn/elektra/unstable/

The release candidate is available under:
http://www.markus-raab.org/ftp/elektra-0.7.0rc3.tar.gz

---------------

0.7.0rc2 - 23.03.2008
Second Release Candidate of unstable repository.

We proudly present the second release candidate for Elektra 0.7.0. Many
bugs were fixed, kdbGet() and kdbSet() is now really stable, useful and
well documentated. test_kdb also tests hosts and fstab next to filesys
with 6598 test cases.

kdbSet() now supports a parent key to only set a part of the
configuration passed by the keyset, allowing to e.g. save system and
user configuration separately. It only calls kdbSet_backend() when it
is actually necessary. The splitting works much more efficient with n*b
instead of n^2*b.

The highlevel functions kdbGetKey() and kdbSetKey() now work well with
Capabilities. This allows very easy changing of keys inside backends
even with some lacking capabilities, see GetStartedMounting.

Patrick Sabin and I wrote our bachelor thesis about mounting backends for
configuration. It gives a detailed introduction in problem and choices
and the actual implementation.
See: doc/elektra.pdf doc/elektra.ps.gz

---------------

0.7.0rc1 - 06.12.2007
First Release Candidate of unstable repository.
= Large Changes =

== Multiple Backends ==

Elektra now supports multiple backends at once. That means every path
like user/sw or system/filesystems can reside in a different backend.

Use cases for backend mounting: 1. There are many configurationfiles lying
on every system that can't be replaced for various reasons. These files
can be fade in into the global elektra namespace without any notice by
applications using these files. Backends for /etc/fstab, /etc/mtab and
/etc/passwd exist right now.

2. Users or administrators might get used by ordained files or syntax
without wanting to change the whole configuration using elektra. The
mounting technique allows them to choose.

3. Specific programs may have very complex and large configuration. Binary
files with index may give them a fairly better performance without
missing the connection to the global namespace.

4. Configuration provided by network or local daemons for notification
and caching can't be used for every program. Configuration related to
bootup or some system users need to be available without them, but should
also be accessed by applications needing configuration from network.

If you are not convinced - Its just about choice and you can go on using
only one backend.

See http://www.libelektra.org/Backends what is and might be possible.

== kdbOpen(), kdbClose(), kdbGet() and kdbSet() ==

These 4 core functions do now everything related to backend
communication. All the other functions are build upon it. This makes
backend writing much easier. Removing and Stat works by setting a flag
in a key.

KDB * is now a typedef for the _KDB structure and not a
void* pointer.

== Keyset ==

Starting with ksNew you can give a hint how large the keyset may grow. You
can also give a list of keys which should be added at startup.

ksGenerate() makes use out of that and generates you a keyset in C-Code
which you can use in your applications or for regression testing.

The internal structure of keyset is now a growing (and shrinking)
array. Keys may belong to multiple keysets now. The last ksDel() deletes
the key automatically (reference counter).

This implementation is a lot faster, the benchmark is for 0.7.0rc1 better
then for 0.6.*, even though the mounting logic takes a bit of performance,
but very little and something about zero when no backend is mounted.

== Key ==

The key now uses sizes for name, owner, value and comment. This allows a
complete new technique of serializing: keyCompose(). With that you can
serialise a key without a single malloc(). keySerialize() is rewritten
for the new key struct too.

== Access Types ==

The directory is now marked by the executable flags. That means you can
disallow other users or groups to list your keys.

== Capabilities ==

Some backends fulfill the whole specification of kdbGet_template() and
kdbSet_template() and can be used by any program for any purpose. Other
backends have principle limitations and do not fulfill the specification,
but can do more than enough to be useful.

To handle this problem we created a data structure describing what
capabilities a backend does not have. With that technique you can use the
testing framework from early steps developing the backend on. To do so,
just declare your backend can do nothing and delete step by step while
your backend evolves.

== Testing framework ==

There is now a large testing framework with 11 collections with up to
8128 tests each. Most conditions of the whole sourcecode are checked,
that means if you random change something in the code you have a good
chance that a test case will fail.

There are 2 new flags:
 --enable-valgrind-tests
   Allows you to enable valgrind for testing, a full list of memory
   leaks is printed after every test.
 --enable-gcov
   Use it to see what lines of code are covered by tests.

The testcases are without any memory leak (dozens of leaks are fixed,
especially in xml code).

---------------

0.6.10 - 10.03.2007 Elektra received some stability updated from Patrice
Dumas.

---------------

0.6.6 - 21.12.2006 support for directories with values and comments on
filesys, berkeleydb and daemon backends.

---------------

0.6.4 - 08.09.2006 Tons of improvements and standarizations to the build
system from Patrice Dumas and Yannick.  Many improvements to the daemon
backend from Yannick.  Several other bug fixes.  We are getting closer
to a production daemon.

---------------

0.6.2 - 02.06.2006 - Includes more robust key name handling and
intelligent duplicate "/" removal - Escaping of "/" on key names is
now supported - Better automatic UTF-8 conversions - More tunnings for
better future daemon backend support - More robust berkeleydb backend -
Backends are now installed on /lib/elektra/ - The build system was tunned
to be included as a Fedora Extras package

---------------

0.6.0 - 30.03.2006 Public release of the new API.  Check it out in SF.

repository: domhof/libelektra

repo_name: domhof/libelektra