A domain-specific language is a computer language specialized to a particular application domain.
Using imperative programming we need to describe how to solve problem.
Using declarative programming we need to describe what needs to be solved.
List<Session> results = []
for (Session candidate in sessions) {
if (candidate.speaker == me) {
results.add(candidate)
}
}
select * from speaker
where sp.speaker = :me
Defines own syntax with its own parser.
Uses existing general purpose programming language
select * from session
where speaker = :me
create.select()
.from(SESSION)
.where(SESSION.SPEAKER.eq(me));
create.select(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME, count())
.from(AUTHOR)
.join(BOOK).on(AUTHOR.ID.equal(BOOK.AUTHOR_ID))
.where(BOOK.LANGUAGE.eq("DE"))
.and(BOOK.PUBLISHED.gt(date("2008-01-01")))
.groupBy(AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
.having(count().gt(5))
.orderBy(AUTHOR.LAST_NAME.asc().nullsFirst())
.limit(2)
.offset(1)
PoiSpreadsheetBuilder.create(file).build {
sheet('Sample') {
row {
cell 'A'
cell 'B'
cell 'C'
}
row {
cell 1
cell 2
cell 3
}
}
}
void 'upload file with message'() {
expect:
gru.test {
post '/moons/upload', {
upload {
params message: 'Hello'
file 'theFile', 'hello.txt', inline('Hello World'), 'text/plain'
}
executes controller.&postWithMessageAndImage
}
expect {
json 'uploadResult.json'
}
}
}
static <U extends ControllerUnitTest> RequestDefinitionBuilder executes(
RequestDefinitionBuilder self,
Closure method
) {
if (!(method instanceof MethodClosure)) {
throw new IllegalArgumentException('Closure must be method closure.')
}
self.command(UrlMappingsMinion) {
action = method as MethodClosure
}
}
[note: You can stick notes on diagrams too!{bg:skyblue}]
[Customer]<>1-orders 0..*>[Order]
[Order]++*-*>[LineItem]
[Order]-1>[DeliveryMethod]
[Order]*-*>[Product]
[Category]<->[Product]
[DeliveryMethod]^[National]
[DeliveryMethod]^[International]