Skip to content
This repository has been archived by the owner on Apr 20, 2024. It is now read-only.

Commit

Permalink
Merge branch 'readme' into feature/add-controller-explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
steffendsommer committed Oct 5, 2017
2 parents f48431f + 2fd82c5 commit 09942ec
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 54 deletions.
36 changes: 18 additions & 18 deletions Models/NodeRepresentable.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,27 @@ import {{ var }}
{% endif %}

extension {{ type.localName }}: NodeRepresentable {
internal enum NodeKeys: String {
{% for var in type.storedVariables|!annotated:"ignore" %}
case {{ var.annotations.nodeKey|default:var.name }}
{% endfor %}
}
internal enum NodeKeys: String {
{% for var in type.storedVariables|!annotated:"ignore" %}
case {{ var.annotations.nodeKey|default:var.name }}
{% endfor %}
}

// MARK: - NodeRepresentable ({{ type.name }})
func makeNode(in context: Context?) throws -> Node {
var node = Node([:])
// MARK: - NodeRepresentable ({{ type.name }})
func makeNode(in context: Context?) throws -> Node {
var node = Node([:])

try node.set({{ type.name }}.idKey, id)
{% for var in type.storedVariables|!annotated:"ignore" %}
try node.set(NodeKeys.{{ var.annotations.nodeKey|default:var.name }}.rawValue, {{ var.annotations.nodeValue|default:var.name }})
{% endfor %}
{% if type.based.Timestampable %}
try node.set({{ type.localName }}.createdAtKey, createdAt)
try node.set({{ type.localName }}.updatedAtKey, updatedAt)
{% endif %}
try node.set({{ type.name }}.idKey, id)
{% for var in type.storedVariables|!annotated:"ignore" %}
try node.set(NodeKeys.{{ var.annotations.nodeKey|default:var.name }}.rawValue, {{ var.annotations.nodeValue|default:var.name }})
{% endfor %}
{% if type.based.Timestampable %}
try node.set({{ type.localName }}.createdAtKey, createdAt)
try node.set({{ type.localName }}.updatedAtKey, updatedAt)
{% endif %}

return node
}
return node
}
}

// sourcery:end
Expand Down
42 changes: 21 additions & 21 deletions Models/Preparation.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,30 @@ import {{ var }}
{% endif %}

extension {{ type.localName }}: Preparation {
internal enum DatabaseKeys {
static let id = {{ type.localName }}.idKey
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation" %}
static let {{ var.annotations.databaseKey|default:var.name }} = "{{ var.annotations.databaseKey|default:var.name }}"
{% endfor %}
}
internal enum DatabaseKeys {
static let id = {{ type.localName }}.idKey
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation" %}
static let {{ var.annotations.databaseKey|default:var.name }} = "{{ var.annotations.databaseKey|default:var.name }}"
{% endfor %}
}

// MARK: - Preparations ({{ type.name }})
internal static func prepare(_ database: Database) throws {
try database.create(self) {
$0.id()
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation" %}
$0.{% if var|annotated:"preparation" %}{{ var.annotations.preparation }}{% elif var|annotated:"enumName" %}enum{% else %}{{ var.typeName.description|lowercase|replace:"?","" }}{% endif %}{% if var.annotations.preparation == "foreignId" %}(for: {{ var.annotations.foreignTable }}.self, optional: {% if var.isOptional %}true{% else %}false{% endif %}, unique: {{ var.annotations.unique }}, foreignIdKey: {% if var.annotations.foreignIdKey %}"{{ var.annotations.foreignIdKey }}"{% else %}DatabaseKeys.{{ var.name }}{% if var.annotations.foreignKeyName %}, foreignKeyName: "{{ var.annotations.foreignKeyName }}"{% endif %}{% endif %}){% elif var.annotations.enumName %}(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}, options: {{ var.annotations.enumName }}.allDescription){% else %}(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}{% if var.annotations.type %}, type: "{{ var.annotations.type }}"{% endif %}{% if var.isOptional %}, optional: true{% endif %}{% if var.annotations.unique %}, unique: true{% endif %}){% endif %}
{% endfor %}
}
// MARK: - Preparations ({{ type.name }})
internal static func prepare(_ database: Database) throws {
try database.create(self) {
$0.id()
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation" %}
$0.{% if var|annotated:"preparation" %}{{ var.annotations.preparation }}{% elif var|annotated:"enumName" %}enum{% else %}{{ var.typeName.description|lowercase|replace:"?","" }}{% endif %}{% if var.annotations.preparation == "foreignId" %}(for: {{ var.annotations.foreignTable }}.self, optional: {% if var.isOptional %}true{% else %}false{% endif %}, unique: {{ var.annotations.unique }}, foreignIdKey: {% if var.annotations.foreignIdKey %}"{{ var.annotations.foreignIdKey }}"{% else %}DatabaseKeys.{{ var.name }}{% if var.annotations.foreignKeyName %}, foreignKeyName: "{{ var.annotations.foreignKeyName }}"{% endif %}{% endif %}){% elif var.annotations.enumName %}(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}, options: {{ var.annotations.enumName }}.allDescription){% else %}(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}{% if var.annotations.type %}, type: "{{ var.annotations.type }}"{% endif %}{% if var.isOptional %}, optional: true{% endif %}{% if var.annotations.unique %}, unique: true{% endif %}){% endif %}
{% endfor %}
}

{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation"|annotated:"index" %}
try database.index(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}, for: {{ type.name }}.self)
{% endfor %}
}
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignorePreparation"|annotated:"index" %}
try database.index(DatabaseKeys.{% if var.annotations.databaseKey %}{{ var.annotations.databaseKey }}{% else %}{{ var.name }}{% endif %}, for: {{ type.name }}.self)
{% endfor %}
}

internal static func revert(_ database: Database) throws {
try database.delete(self)
}
internal static func revert(_ database: Database) throws {
try database.delete(self)
}
}
// sourcery:end
{% endfor %}
30 changes: 15 additions & 15 deletions Models/RowConvertible.stencil
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ import Vapor
import Fluent

extension {{ type.localName }}: RowConvertible {
// MARK: - RowConvertible ({{ type.name }})
convenience internal init (row: Row) throws {
try self.init(
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignoreRowConvertible" %}
{{ var.name }}: row.get(DatabaseKeys.{{ var.annotations.databaseKey|default:var.name }}){% if not forloop.last %},{% endif %}
{% endfor %}
)
}
// MARK: - RowConvertible ({{ type.name }})
convenience internal init (row: Row) throws {
try self.init(
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignoreRowConvertible" %}
{{ var.name }}: row.get(DatabaseKeys.{{ var.annotations.databaseKey|default:var.name }}){% if not forloop.last %},{% endif %}
{% endfor %}
)
}

internal func makeRow() throws -> Row {
var row = Row()
internal func makeRow() throws -> Row {
var row = Row()

{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignoreRowConvertible" %}
try row.set(DatabaseKeys.{{ var.annotations.databaseKey|default:var.name }}, {{ var.name }})
{% endfor %}
{% for var in type.storedVariables|!annotated:"ignore"|!annotated:"ignoreRowConvertible" %}
try row.set(DatabaseKeys.{{ var.annotations.databaseKey|default:var.name }}, {{ var.name }})
{% endfor %}

return row
}
return row
}
}
// sourcery:end
{% endfor %}
185 changes: 185 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@ This collection of templates is related to models and automating their conversio
## Model
Automatically generates an initializer and an enum for MySQL enum types.

Example:
```swift
final class User: Model {
var name: String
var age: Int?
}
```

Becomes:
```swift
// sourcery: model
final class User: Model {
var name: String
var age: Int?

// sourcery:inline:auto:User.Models
let storage = Storage()


internal init(
name: String,
age: Int? = nil
) {
self.name = name
self.age = age
}
// sourcery:end
}
```

#### Annotations

| Key | Description |
| ----------- | -----------------------------------------------------------------------|
| `enumName` | Generate a Swift enum for MySQL with accessors for a list of all cases.|
Expand All @@ -23,6 +55,45 @@ Automatically generates an initializer and an enum for MySQL enum types.
## Preparation
Generates a list of database keys, automates `prepare` and `revert` functions.

Example:
```swift
final class User: Model {
var name: String
var age: Int?
}
```

Becomes:
```swift
import Vapor
import Fluent

extension User: Preparation {
internal enum DatabaseKeys {
static let id = User.idKey
static let name = "name"
static let age = "age"
}

// MARK: - Preparations (User)
internal static func prepare(_ database: Database) throws {
try database.create(self) {
$0.id()
$0.string(DatabaseKeys.name)
$0.int(DatabaseKeys.age, optional: true)
}

}

internal static func revert(_ database: Database) throws {
try database.delete(self)
}
}

```

#### Annotations

| Key | Description |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------|
| `databaseKey` | Set the database key (default is the name of the member). |
Expand All @@ -40,6 +111,41 @@ Generates a list of database keys, automates `prepare` and `revert` functions.
## RowConvertible
Automates `init (row: Row)` and `makeRow` boilerplate.

Example:
```swift
final class User: Model {
var name: String
var age: Int?
}
```

Becomes:
```swift
import Vapor
import Fluent

extension User: RowConvertible {
// MARK: - RowConvertible (User)
convenience internal init (row: Row) throws {
try self.init(
name: row.get(DatabaseKeys.name),
age: row.get(DatabaseKeys.age)
)
}

internal func makeRow() throws -> Row {
var row = Row()

try row.set(DatabaseKeys.name, name)
try row.set(DatabaseKeys.age, age)

return row
}
}
```

#### Annotations

| Key | Description |
| ---------------------- | --------------------------------------------------------------------------------- |
| `databaseKey` | Set the database key (default is the name of the member). |
Expand All @@ -49,6 +155,40 @@ Automates `init (row: Row)` and `makeRow` boilerplate.
## NodeRepresentable
Generates a list of node keys and `makeNode(in context: Context?)`.

Example:
```swift
final class User: Model {
var name: String
var age: Int?
}
```

Becomes:
```swift
import Vapor
import Fluent

extension User: NodeRepresentable {
internal enum NodeKeys: String {
case name
case age
}

// MARK: - NodeRepresentable (User)
func makeNode(in context: Context?) throws -> Node {
var node = Node([:])

try node.set(User.idKey, id)
try node.set(NodeKeys.name.rawValue, name)
try node.set(NodeKeys.age.rawValue, age)

return node
}
}
```

#### Annotations

| Key | Description |
| ------------------------- | ------------------------------------------------------------------------------------|
| `nodeKey` | Set the key for node (de)serialization. |
Expand All @@ -58,6 +198,46 @@ Generates a list of node keys and `makeNode(in context: Context?)`.
## JSONConvertible
Generates a list of JSON keys, `init(json: JSON)` and `makeJSON`.

Example:
```swift
final class User: Model {
var name: String
var age: Int?
}
```

Becomes:
```swift
extension User: JSONConvertible {
internal enum JSONKeys: String {
case name
case age
}

// MARK: - JSONConvertible (User)
internal convenience init(json: JSON) throws {
try self.init(
name: json.get(JSONKeys.name.rawValue),
age: json.get(JSONKeys.age.rawValue)
)
}

internal func makeJSON() throws -> JSON {
var json = JSON()

try json.set(User.idKey, id)
try json.set(JSONKeys.name.rawValue, name)
try json.set(JSONKeys.age.rawValue, age)

return json
}
}

extension User: ResponseRepresentable {}
```

#### Annotations

| Key | Description |
| ----------------------- | ----------------------------------------------------------------------------------|
| `jsonValue` | Set the value for JSON serialization. |
Expand All @@ -70,6 +250,8 @@ These templates are related to unit testing with XCTest.
## LinuxMain
Generates a static `allTests` for every `XCTestCase` and registers them in the `LinuxMain.swift`.

#### Annotations

| Key | Description |
| ----------------------| ----------------------------------------------------------------- |
| `excludeFromLinuxMain`| Prevents the test case from being included in the generated code. |
Expand All @@ -78,6 +260,9 @@ Generates a static `allTests` for every `XCTestCase` and registers them in the `
These templates are for controllers and route collections.

## Route collection

#### Annotations

| Key | Description |
| ------------| ----------- |
| `controller`| |
Expand Down

0 comments on commit 09942ec

Please sign in to comment.