| Package | Description |
|---|---|
| energy.usef.agr.controller |
Controller classes of the Aggregator.
|
| energy.usef.agr.model |
Model classes of the Aggregator.
|
| energy.usef.agr.repository |
Repository classes of the Aggregator.
|
| energy.usef.agr.service.business |
Business classes of the Aggregator.
|
| energy.usef.agr.transformer |
Package contains helper classes to transform between our Model and the DTO's
|
| energy.usef.agr.workflow.settlement.receive |
This package contains the workflow classes for Receiving Settlements on the Aggregator side.
|
| energy.usef.brp.controller |
Controller classes of the Balance Responsible Party.
|
| energy.usef.brp.service.business |
The package which contains all the business services for the BRP.
|
| energy.usef.brp.workflow.plan.flexorder.acknowledge |
Classes for flex order acknowledgment in the plan phase for the Balance Responsible Party.
|
| energy.usef.brp.workflow.transformer |
Transformer classes of the Balance Responsible Party.
|
| energy.usef.core.controller |
Controller classes for the transport core.
|
| energy.usef.core.model |
Model classes for the transport core.
|
| energy.usef.core.repository |
Package for the core repository classes.
|
| energy.usef.core.service.business |
Package for the core business service classes.
|
| energy.usef.core.service.notification |
Notification classes for the transport core.
|
| energy.usef.core.service.validation |
Package for global business validations.
|
| energy.usef.core.util |
Package for the core utility classes.
|
| energy.usef.core.workflow.settlement | |
| energy.usef.core.workflow.transformer |
Transformer classes for the workflow.
|
| energy.usef.cro.controller |
Controller classes for the Common Reference Operator.
|
| energy.usef.dso.controller |
Controller classes of the Distribution System Operator.
|
| energy.usef.dso.model |
Model classes of the Distribution System Operator.
|
| energy.usef.dso.repository |
Repository classes of the Distribution System Operator.
|
| energy.usef.dso.service.business |
Business classes of the Distribution System Operator.
|
| energy.usef.dso.workflow.plan.connection.forecast |
Connection forecast classes of the Distribution System Operator.
|
| energy.usef.mdc.controller |
Contains Controller Classes.
|
| energy.usef.mdc.model |
This package contains the model entities for the MDC role of USEF.
|
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| Class and Description |
|---|
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| ConnectionGroup
Entity representing a group of
Connection . |
| DocumentType
An enumeration to represent a document type of
PlanboardMessage . |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PrognosisType
An enumeration to represent if a
PtuPrognosis type. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuFlexOrder
Entity class
PtuFlexOrder : This class is a representation of a FlexOrder. |
PtuFlexRequest
PtuFlexRequest entity class represents the connection on which an aggregator can have a customer. |
| Class and Description |
|---|
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| Class and Description |
|---|
| Connection
Connection entity for the planboard.
|
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| DispositionAvailableRequested
Enumeration of the disposition values for a Prognosis.
|
| Document
Entity class
Document : This class is a base class for documents inside a PtuContainer . |
| DocumentStatus
Enumeration of the different statuses for a
PlanboardMessage entity. |
| DocumentType
An enumeration to represent a document type of
PlanboardMessage . |
| Exchange |
| FlexOrderSettlement
Entity carrying information about the settlement of one flex order.
|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| MessageDirection
An enumeration to represent if a
Message is inbound or outbound. |
| MessageType
An enumeration to represent the type of
Message . |
| PhaseType
Enumeration of the different USEF phases.
|
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PrognosisType
An enumeration to represent if a
PtuPrognosis type. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuContainerState
An enumeration to represent if a
PtuContainer phase type. |
| PtuSettlement
Entity exposing the information related the settlement of a flex order for one PTU.
|
| RegimeType
An enumeration to represent if a
PtuContainer regime type. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| AgrConnectionGroup
This repository is used to manage
AgrConnectionGroup . |
| BrpConnectionGroup
Subclass of
ConnectionGroup representing connections grouped with a BRP. |
| CongestionPointConnectionGroup
Subclass of
ConnectionGroup representing connections grouped in a Congestion Point. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| ConnectionGroupState
Join table between
ConnectionGroup and Connection . |
| Document
Entity class
Document : This class is a base class for documents inside a PtuContainer . |
| DocumentStatus
Enumeration of the different statuses for a
PlanboardMessage entity. |
| DocumentType
An enumeration to represent a document type of
PlanboardMessage . |
| FlexOrderSettlement
Entity carrying information about the settlement of one flex order.
|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| MessageDirection
An enumeration to represent if a
Message is inbound or outbound. |
| PhaseType
Enumeration of the different USEF phases.
|
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PrognosisType
An enumeration to represent if a
PtuPrognosis type. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuContainerState
An enumeration to represent if a
PtuContainer phase type. |
| PtuFlexOffer
Entity class
PtuFlexOffer : This class is a representation of a FlexOffer. |
| PtuFlexOrder
Entity class
PtuFlexOrder : This class is a representation of a FlexOrder. |
PtuFlexRequest
PtuFlexRequest entity class represents the connection on which an aggregator can have a customer. |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| PtuState
Entity class
PtuState : contains the regime and PTU container state data for a PTU container and a connection group. |
| RegimeType
An enumeration to represent if a
PtuContainer regime type. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| CongestionPointConnectionGroup
Subclass of
ConnectionGroup representing connections grouped in a Congestion Point. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| ConnectionGroupState
Join table between
ConnectionGroup and Connection . |
| DocumentStatus
Enumeration of the different statuses for a
PlanboardMessage entity. |
| DocumentType
An enumeration to represent a document type of
PlanboardMessage . |
| FlexOrderSettlement
Entity carrying information about the settlement of one flex order.
|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| MessageDirection
An enumeration to represent if a
Message is inbound or outbound. |
| MessageError
Entity class
MessageError : When a Message is sent an error may occur, this will be stored in this entity. |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PrognosisType
An enumeration to represent if a
PtuPrognosis type. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuContainerState
An enumeration to represent if a
PtuContainer phase type. |
| PtuFlexOffer
Entity class
PtuFlexOffer : This class is a representation of a FlexOffer. |
| PtuFlexOrder
Entity class
PtuFlexOrder : This class is a representation of a FlexOrder. |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| PtuState
Entity class
PtuState : contains the regime and PTU container state data for a PTU container and a connection group. |
| RegimeType
An enumeration to represent if a
PtuContainer regime type. |
| Class and Description |
|---|
| MessageType
An enumeration to represent the type of
Message . |
| Class and Description |
|---|
| Document
Entity class
Document : This class is a base class for documents inside a PtuContainer . |
| DocumentType
An enumeration to represent a document type of
PlanboardMessage . |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuContainerState
An enumeration to represent if a
PtuContainer phase type. |
| PtuFlexOffer
Entity class
PtuFlexOffer : This class is a representation of a FlexOffer. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| DocumentStatus
Enumeration of the different statuses for a
PlanboardMessage entity. |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| Class and Description |
|---|
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| FlexOrderSettlement
Entity carrying information about the settlement of one flex order.
|
| PtuFlexOffer
Entity class
PtuFlexOffer : This class is a representation of a FlexOffer. |
| PtuFlexOrder
Entity class
PtuFlexOrder : This class is a representation of a FlexOrder. |
PtuFlexRequest
PtuFlexRequest entity class represents the connection on which an aggregator can have a customer. |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| DispositionAvailableRequested
Enumeration of the disposition values for a Prognosis.
|
| FlexOrderSettlement
Entity carrying information about the settlement of one flex order.
|
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuFlexOffer
Entity class
PtuFlexOffer : This class is a representation of a FlexOffer. |
| PtuFlexOrder
Entity class
PtuFlexOrder : This class is a representation of a FlexOrder. |
PtuFlexRequest
PtuFlexRequest entity class represents the connection on which an aggregator can have a customer. |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| PtuSettlement
Entity exposing the information related the settlement of a flex order for one PTU.
|
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| CongestionPointConnectionGroup
Subclass of
ConnectionGroup representing connections grouped in a Congestion Point. |
| Connection
Connection entity for the planboard.
|
| DispositionAvailableRequested
Enumeration of the disposition values for a Prognosis.
|
| Document
Entity class
Document : This class is a base class for documents inside a PtuContainer . |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| Class and Description |
|---|
| CongestionPointConnectionGroup
Subclass of
ConnectionGroup representing connections grouped in a Congestion Point. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| Class and Description |
|---|
| AcknowledgementStatus
An enumeration to represent if a
PtuFlexRequest acknowledgement status. |
| CongestionPointConnectionGroup
Subclass of
ConnectionGroup representing connections grouped in a Congestion Point. |
| Connection
Connection entity for the planboard.
|
| ConnectionGroup
Entity representing a group of
Connection . |
| PlanboardMessage
Entity class
PlanboardMessage : This class is a representation of a PlanboardMessage. |
| PtuContainer
Entity class
PtuContainer : This class is a representation of a PTUContainer. |
| PtuPrognosis
Entity class
PtuPrognosis : This class is a representation of a Prognosis. |
| PtuState
Entity class
PtuState : contains the regime and PTU container state data for a PTU container and a connection group. |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
| Class and Description |
|---|
| Message
Entity class
Message : This class is a representation of a Message send or received. |
Copyright © 2016. All rights reserved.


Treasurer
Asha for Education UIUC ChapterManaged incoming and outgoing finances for the organization and coordinated with the Asha Central team to ensure efficient financial management of the chapter.
Managed incoming and outgoing finances for the organization and coordinated with the Asha Central team to ensure efficient financial management of the chapter.
Organized large-scale (~2.5k attendees) fund-raising events for Asha for Education. Funds were used to finance educational projects for underprivileged students in India.
Supervised efforts of a team of 12 members.


Money Play. How should Red play 64?
pips Red=150 White=134
(CorrectAnswer= 0/0, ErrorScore= 0)
The best play here is bar/21, 13/7 leaving Red one roll away from having a very strong five-point prime. It puts huge pressure on White to roll an immediate six (which is duplicated). The way forward after bar/21, 8/2* is not so clear as Red only has nine checkers in the attack zone.
Hitting is a bad mistake but not quite a blunder.
Hitting is a bad mistake but not quite a blunder.
1. Cubeful 2-ply bar/21 13/7 Eq.: +0.229 0.558 0.177 0.005 - 0.442 0.117 0.004 2. Cubeful 2-ply bar/21 8/2* Eq.: +0.183 (-0.046) 0.534 0.184 0.005 - 0.466 0.120 0.004 3. Cubeful 0-ply bar/15 Eq.: +0.022 (-0.207) 0.503 0.147 0.004 - 0.497 0.130 0.006 4. Cubeful 0-ply bar/21 7/1 Eq.: -0.170 (-0.400) 0.443 0.131 0.004 - 0.557 0.137 0.005


|
| | Builder (TSliderWidget component) |
| |
| virtual TBuilder | ClickToChange (bool clickToChange) |
| | Determines whether or not clicking on the Slider axis will change the slider. Defaults to true More...
|
| |
| virtual TBuilder | PublishOnComplete (bool publishOnComplete) |
| | This controls when the value of the slider is published to the ViewModel . More...
|
| |
| virtual TBuilder | Value (object value) |
| | A value to initialize this field with. More...
|
| |
| virtual TBuilder | MaxValue (double maxValue) |
| | The maximum value for the Slider. Defaults to 100. More...
|
| |
| virtual TBuilder | MinValue (double minValue) |
| | The minimum value for the Slider. Defaults to 0. More...
|
| |
| virtual TBuilder | Listeners (Action< SliderWidgetListeners > action) |
| | Client-side JavaScript Event Handlers More...
|
| |
| virtual TBuilder | DirectEvents (Action< SliderWidgetDirectEvents > action) |
| | Server-side DirectEventHandlers More...
|
| |
| virtual TBuilder | DecimalPrecision (int decimalPrecision) |
| | The number of decimal places to which to round the Slider's value. Defaults to 0. More...
|
| |
| virtual TBuilder | Vertical (bool vertical) |
| | Orient the Slider vertically rather than horizontally, defaults to false.  More...
|
| |
| virtual TBuilder | RippleObject (object rippleObject) |
| | Set to truthy, Color or Object value for the ripple. More...
|
| |
| virtual TBuilder | RippleString (string rippleString) |
| | Set to truthy, Color or Object value for the ripple. More...
|
| |
| virtual TBuilder | SetRipple (bool? ripple) |
| |
| virtual TBuilder | SetRipple (object ripple) |
| |
| virtual TBuilder | SetRipple (string ripple) |
| |
| virtual TBuilder | ReplaceCls (string oldCls, string newCls, string prefix=null, string suffix=null) |
| |
| virtual TBuilder | ReplaceCls (string[] oldCls, string newCls, string prefix=null, string suffix=null) |
| |
| virtual TBuilder | ReplaceCls (string oldCls, string[] newCls, string prefix=null, string suffix=null) |
| |
| virtual TBuilder | ReplaceCls (string[] oldCls, string[] newCls, string prefix=null, string suffix=null) |
| |


Feel free to add me and connect with me on my LinkedIn.
Double Major in Immunology and Cell Molecular Biology '16
Certified in 2012 by the American Go Association
Eiji Nambara's Lab at University of Toronto (CSB)


Konrad Zuse begins work on Plankalkül (Plan Calculus), the first algorithmic programming language, with the goal of creating the theoretical preconditions for the solution of general problems. Seven years earlier, Zuse had developed and built the world´s first binary digital computer, the Z1. He completed the first fully functional program-controlled electromechanical digital computer, the Z3, in 1941. Only the Z4 — the most sophisticated of his creations — survived World War II.
Konrad Zuse begins work on Plankalkül (Plan Calculus), the first algorithmic programming language, with the goal of creating the theoretical preconditions for the solution of general problems. Seven years earlier, Zuse had developed and built the world´s first binary digital computer, the Z1. He completed the first fully functional program-controlled electromechanical digital computer, the Z3, in 1941. Only the Z4 — the most sophisticated of his creations — survived World War II.


--- layout: base title: Network Upgrade ---
The planned upgrade of the BCHA network has successfully been completed. The first post-upgrade block is block number 686621.
If you forgot to upgrade, your node may have marked the upgraded chain as invalid. In order to fix this problem, simply upgrade to Bitcoin ABC version 0.23.4 or greater, available at our Releases page.
The May 15th 2021 upgrade did not include any new protocol features. However, because of the automatic replay protection that is part of the 6-month upgrade cadence, it is necessary for all full node operators to upgrade to 0.23.x.
The network upgrade only affects full-nodes. This means that other BCHA software, including wallets such as Electrum ABC are not affected by the network upgrade.


About Me
My name is Russ, I work as a software developer at Epic Systems in Verona, WI. This site is somewhat of a mix between a blog and some more technical stuff. I may throw in some entries on web development, python, Japanese, mathematics, or whatever interests me at the time.
Demos
This is where I keep most of my demos, some of them are more complete than others.
Short Japanese Lesson
The Japanese alphabet is broken up into two distinct parts. Hiragana(ひらがな)/katakana(カタカナ) together make up the gana and kanji (漢字) which are characters adopted from China.
Basic Radicals
Here are the basic radicals used in kanji. Most of these radicals by themselves have meaning. They can also be used to make more complex kanji. These radicals are either used to add meaning to a new kanji character or help with its pronunciation. For example, 語 means language. In this character we see 話 (talk), which gives the character meaning. We also see 五 (five) which does not aid in its meaning, but is included because both 語 and 五 are pronounced "go."- 口 (くち) mouth
- 水/氵 (みず) water
- 木 (き) tree
- 人/亻 (ひと) person
- 手/扌 (て) hand
- 心/忄 (こころ) heart
- 言 (こと) word
- 日 (ひ/にち) sun/day
- 糸・幺 (いと) thread
- 肉･月 (にく・つき) meat/organ (moon)
- 土 (つち) ground
- 道 go/road radical
- 艹 grass/plant radical
- 宀 roof/crown radical
- 貝 (かい) shell
- 女 (おんな) woman
- 阝 village (right) wall (left) radical
- 金 (きん) gold/metal
- 一 (いち) one
- 刀/刂 (かたな) sword
- 十 (じゅう) ten
- 田 (た) rice field
- 火/灬 (ひ/か) fire
- 大 (おお) big
- 山 (やま) mountain
- 食 (しょく) meal
- 車 (くるま) vehicle
- 彳 walking person radical
- 目 (め) eye
- 雨 (あめ) rain
- 犬 (いぬ) dog
- 玉（王） (たま・おう) ball (king)
- 石 (いし) stone
- 力 (ちから) power
- 衣/衤 (ころも) garment
- 弓 (ゆみ) bow
- 竹 (たけ) bamboo
- 又 (また) again
- 攵/夂 action radical
- 示/礻 (しめす) show on an altar radical
- 酉 (とり) alcohol radical
- 囗 (くにがまえ) enclosure radical
- 禾 grain radical
- 广 building on a cliff radical
- 疒 sickness radical
- 巾 (きん/はば) cloth radical
- 尸 (し) corpse radical
- 寸 (すん) inch/sundial degree radical


Database: Query Builder
- Introduction
- Retrieving Results
- Selects
- Raw Expressions
- Joins
- Unions
- Where Clauses
- Ordering, Grouping, Limit, & Offset
- Conditional Clauses
- Inserts
- Updates
- Deletes
- Pessimistic Locking
Introduction
Laravel's database query builder provides a convenient, fluent interface to creating and running database queries. It can be used to perform most database operations in your application and works on all supported database systems.
The Laravel query builder uses PDO parameter binding to protect your application against SQL injection attacks. There is no need to clean strings being passed as bindings.
{note} PDO does not support binding column names. Therefore, you should never allow user input to dictate the column names referenced by your queries, including "order by" columns, etc. If you must allow the user to select certain columns to query against, always validate the column names against a white-list of allowed columns.
Retrieving Results
Retrieving All Rows From A Table
You may use the table
method on the DB
facade to begin a query. The table
method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get
method:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @return Response
*/
public function index()
{
$users = DB::table('users')->get();
return view('user.index', ['users' => $users]);
}
}
The get
method returns an Illuminate\Support\Collection
containing the results where each result is an instance of the PHP stdClass
object. You may access each column's value by accessing the column as a property of the object:
foreach ($users as $user) {
echo $user->name;
}
Retrieving A Single Row / Column From A Table
If you just need to retrieve a single row from the database table, you may use the first
method. This method will return a single stdClass
object:
$user = DB::table('users')->where('name', 'John')->first();
echo $user->name;
If you don't even need an entire row, you may extract a single value from a record using the value
method. This method will return the value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
To retrieve a single row by its id
column value, use the find
method:
$user = DB::table('users')->find(3);
Retrieving A List Of Column Values
If you would like to retrieve a Collection containing the values of a single column, you may use the pluck
method. In this example, we'll retrieve a Collection of role titles:
$titles = DB::table('roles')->pluck('title');
foreach ($titles as $title) {
echo $title;
}
You may also specify a custom key column for the returned Collection:
$roles = DB::table('roles')->pluck('title', 'name');
foreach ($roles as $name => $title) {
echo $title;
}
Chunking Results
If you need to work with thousands of database records, consider using the chunk
method. This method retrieves a small chunk of the results at a time and feeds each chunk into a Closure
for processing. This method is very useful for writing Artisan commands that process thousands of records. For example, let's work with the entire users
table in chunks of 100 records at a time:
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
foreach ($users as $user) {
//
}
});
You may stop further chunks from being processed by returning false
from the Closure
:
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
// Process the records...
return false;
});
If you are updating database records while chunking results, your chunk results could change in unexpected ways. So, when updating records while chunking, it is always best to use the chunkById
method instead. This method will automatically paginate the results based on the record's primary key:
DB::table('users')->where('active', false)
->chunkById(100, function ($users) {
foreach ($users as $user) {
DB::table('users')
->where('id', $user->id)
->update(['active' => true]);
}
});
{note} When updating or deleting records inside the chunk callback, any changes to the primary key or foreign keys could affect the chunk query. This could potentially result in records not being included in the chunked results.
Aggregates
The query builder also provides a variety of aggregate methods such as count
, max
, min
, avg
, and sum
. You may call any of these methods after constructing your query:
$users = DB::table('users')->count();
$price = DB::table('orders')->max('price');
You may combine these methods with other clauses:
$price = DB::table('orders')
->where('finalized', 1)
->avg('price');
Determining If Records Exist
Instead of using the count
method to determine if any records exist that match your query's constraints, you may use the exists
and doesntExist
methods:
return DB::table('orders')->where('finalized', 1)->exists();
return DB::table('orders')->where('finalized', 1)->doesntExist();
Selects
Specifying A Select Clause
You may not always want to select all columns from a database table. Using the select
method, you can specify a custom select
clause for the query:
$users = DB::table('users')->select('name', 'email as user_email')->get();
The distinct
method allows you to force the query to return distinct results:
$users = DB::table('users')->distinct()->get();
If you already have a query builder instance and you wish to add a column to its existing select clause, you may use the addSelect
method:
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
Raw Expressions
Sometimes you may need to use a raw expression in a query. To create a raw expression, you may use the DB::raw
method:
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
{note} Raw statements will be injected into the query as strings, so you should be extremely careful to not create SQL injection vulnerabilities.
Raw Methods
Instead of using DB::raw
, you may also use the following methods to insert a raw expression into various parts of your query.
selectRaw
The selectRaw
method can be used in place of select(DB::raw(...))
. This method accepts an optional array of bindings as its second argument:
$orders = DB::table('orders')
->selectRaw('price * ? as price_with_tax', [1.0825])
->get();
whereRaw / orWhereRaw
The whereRaw
and orWhereRaw
methods can be used to inject a raw where
clause into your query. These methods accept an optional array of bindings as their second argument:
$orders = DB::table('orders')
->whereRaw('price > IF(state = "TX", ?, 100)', [200])
->get();
havingRaw / orHavingRaw
The havingRaw
and orHavingRaw
methods may be used to set a raw string as the value of the having
clause. These methods accept an optional array of bindings as their second argument:
$orders = DB::table('orders')
->select('department', DB::raw('SUM(price) as total_sales'))
->groupBy('department')
->havingRaw('SUM(price) > ?', [2500])
->get();
orderByRaw
The orderByRaw
method may be used to set a raw string as the value of the order by
clause:
$orders = DB::table('orders')
->orderByRaw('updated_at - created_at DESC')
->get();
Joins
Inner Join Clause
The query builder may also be used to write join statements. To perform a basic "inner join", you may use the join
method on a query builder instance. The first argument passed to the join
method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. You can even join to multiple tables in a single query:
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
Left Join / Right Join Clause
If you would like to perform a "left join" or "right join" instead of an "inner join", use the leftJoin
or rightJoin
methods. These methods have the same signature as the join
method:
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
$users = DB::table('users')
->rightJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
Cross Join Clause
To perform a "cross join" use the crossJoin
method with the name of the table you wish to cross join to. Cross joins generate a cartesian product between the first table and the joined table:
$users = DB::table('sizes')
->crossJoin('colours')
->get();
Advanced Join Clauses
You may also specify more advanced join clauses. To get started, pass a Closure
as the second argument into the join
method. The Closure
will receive a JoinClause
object which allows you to specify constraints on the join
clause:
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
If you would like to use a "where" style clause on your joins, you may use the where
and orWhere
methods on a join. Instead of comparing two columns, these methods will compare the column against a value:
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
Sub-Query Joins
You may use the joinSub
, leftJoinSub
, and rightJoinSub
methods to join a query to a sub-query. Each of these methods receive three arguments: the sub-query, its table alias, and a Closure that defines the related columns:
$latestPosts = DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
->where('is_published', true)
->groupBy('user_id');
$users = DB::table('users')
->joinSub($latestPosts, 'latest_posts', function ($join) {
$join->on('users.id', '=', 'latest_posts.user_id');
})->get();
Unions
The query builder also provides a quick way to "union" two queries together. For example, you may create an initial query and use the union
method to union it with a second query:
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
{tip} The
unionAll
method is also available and has the same method signature asunion
.
Where Clauses
Simple Where Clauses
You may use the where
method on a query builder instance to add where
clauses to the query. The most basic call to where
requires three arguments. The first argument is the name of the column. The second argument is an operator, which can be any of the database's supported operators. Finally, the third argument is the value to evaluate against the column.
For example, here is a query that verifies the value of the "votes" column is equal to 100:
$users = DB::table('users')->where('votes', '=', 100)->get();
For convenience, if you want to verify that a column is equal to a given value, you may pass the value directly as the second argument to the where
method:
$users = DB::table('users')->where('votes', 100)->get();
You may use a variety of other operators when writing a where
clause:
$users = DB::table('users')
->where('votes', '>=', 100)
->get();
$users = DB::table('users')
->where('votes', '<>', 100)
->get();
$users = DB::table('users')
->where('name', 'like', 'T%')
->get();
You may also pass an array of conditions to the where
function:
$users = DB::table('users')->where([
['status', '=', '1'],
['subscribed', '<>', '1'],
])->get();
Or Statements
You may chain where constraints together as well as add or
clauses to the query. The orWhere
method accepts the same arguments as the where
method:
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
Additional Where Clauses
whereBetween / orWhereBetween
The whereBetween
method verifies that a column's value is between two values:
$users = DB::table('users')
->whereBetween('votes', [1, 100])->get();
whereNotBetween / orWhereNotBetween
The whereNotBetween
method verifies that a column's value lies outside of two values:
$users = DB::table('users')
->whereNotBetween('votes', [1, 100])
->get();
whereIn / whereNotIn / orWhereIn / orWhereNotIn
The whereIn
method verifies that a given column's value is contained within the given array:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
The whereNotIn
method verifies that the given column's value is not contained in the given array:
$users = DB::table('users')
->whereNotIn('id', [1, 2, 3])
->get();
whereNull / whereNotNull / orWhereNull / orWhereNotNull
The whereNull
method verifies that the value of the given column is NULL
:
$users = DB::table('users')
->whereNull('updated_at')
->get();
The whereNotNull
method verifies that the column's value is not NULL
:
$users = DB::table('users')
->whereNotNull('updated_at')
->get();
whereDate / whereMonth / whereDay / whereYear / whereTime
The whereDate
method may be used to compare a column's value against a date:
$users = DB::table('users')
->whereDate('created_at', '2016-12-31')
->get();
The whereMonth
method may be used to compare a column's value against a specific month of a year:
$users = DB::table('users')
->whereMonth('created_at', '12')
->get();
The whereDay
method may be used to compare a column's value against a specific day of a month:
$users = DB::table('users')
->whereDay('created_at', '31')
->get();
The whereYear
method may be used to compare a column's value against a specific year:
$users = DB::table('users')
->whereYear('created_at', '2016')
->get();
The whereTime
method may be used to compare a column's value against a specific time:
$users = DB::table('users')
->whereTime('created_at', '=', '11:20:45')
->get();
whereColumn / orWhereColumn
The whereColumn
method may be used to verify that two columns are equal:
$users = DB::table('users')
->whereColumn('first_name', 'last_name')
->get();
You may also pass a comparison operator to the method:
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
The whereColumn
method can also be passed an array of multiple conditions. These conditions will be joined using the and
operator:
$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at']
])->get();
Parameter Grouping
Sometimes you may need to create more advanced where clauses such as "where exists" clauses or nested parameter groupings. The Laravel query builder can handle these as well. To get started, let's look at an example of grouping constraints within parenthesis:
DB::table('users')
->where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();
As you can see, passing a Closure
into the where
method instructs the query builder to begin a constraint group. The Closure
will receive a query builder instance which you can use to set the constraints that should be contained within the parenthesis group. The example above will produce the following SQL:
select * from users where name = 'John' and (votes > 100 or title = 'Admin')
{tip} You should always group
orWhere
calls in order to avoid unexpected behavior when global scopes are applied.
Where Exists Clauses
The whereExists
method allows you to write where exists
SQL clauses. The whereExists
method accepts a Closure
argument, which will receive a query builder instance allowing you to define the query that should be placed inside of the "exists" clause:
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
The query above will produce the following SQL:
select * from users
where exists (
select 1 from orders where orders.user_id = users.id
)
JSON Where Clauses
Laravel also supports querying JSON column types on databases that provide support for JSON column types. Currently, this includes MySQL 5.7, PostgreSQL, SQL Server 2016, and SQLite 3.9.0 (with the JSON1 extension). To query a JSON column, use the ->
operator:
$users = DB::table('users')
->where('options->language', 'en')
->get();
$users = DB::table('users')
->where('preferences->dining->meal', 'salad')
->get();
You may use whereJsonContains
to query JSON arrays (not supported on SQLite):
$users = DB::table('users')
->whereJsonContains('options->languages', 'en')
->get();
MySQL and PostgreSQL support whereJsonContains
with multiple values:
$users = DB::table('users')
->whereJsonContains('options->languages', ['en', 'de'])
->get();
You may use whereJsonLength
to query JSON arrays by their length:
$users = DB::table('users')
->whereJsonLength('options->languages', 0)
->get();
$users = DB::table('users')
->whereJsonLength('options->languages', '>', 1)
->get();
Ordering, Grouping, Limit, & Offset
orderBy
The orderBy
method allows you to sort the result of the query by a given column. The first argument to the orderBy
method should be the column you wish to sort by, while the second argument controls the direction of the sort and may be either asc
or desc
:
$users = DB::table('users')
->orderBy('name', 'desc')
->get();
latest / oldest
The latest
and oldest
methods allow you to easily order results by date. By default, result will be ordered by the created_at
column. Or, you may pass the column name that you wish to sort by:
$user = DB::table('users')
->latest()
->first();
inRandomOrder
The inRandomOrder
method may be used to sort the query results randomly. For example, you may use this method to fetch a random user:
$randomUser = DB::table('users')
->inRandomOrder()
->first();
groupBy / having
The groupBy
and having
methods may be used to group the query results. The having
method's signature is similar to that of the where
method:
$users = DB::table('users')
->groupBy('account_id')
->having('account_id', '>', 100)
->get();
You may pass multiple arguments to the groupBy
method to group by multiple columns:
$users = DB::table('users')
->groupBy('first_name', 'status')
->having('account_id', '>', 100)
->get();
For more advanced having
statements, see the havingRaw
method.
skip / take
To limit the number of results returned from the query, or to skip a given number of results in the query, you may use the skip
and take
methods:
$users = DB::table('users')->skip(10)->take(5)->get();
Alternatively, you may use the limit
and offset
methods:
$users = DB::table('users')
->offset(10)
->limit(5)
->get();
Conditional Clauses
Sometimes you may want clauses to apply to a query only when something else is true. For instance you may only want to apply a where
statement if a given input value is present on the incoming request. You may accomplish this using the when
method:
$role = $request->input('role');
$users = DB::table('users')
->when($role, function ($query, $role) {
return $query->where('role_id', $role);
})
->get();
The when
method only executes the given Closure when the first parameter is true
. If the first parameter is false
, the Closure will not be executed.
You may pass another Closure as the third parameter to the when
method. This Closure will execute if the first parameter evaluates as false
. To illustrate how this feature may be used, we will use it to configure the default sorting of a query:
$sortBy = null;
$users = DB::table('users')
->when($sortBy, function ($query, $sortBy) {
return $query->orderBy($sortBy);
}, function ($query) {
return $query->orderBy('name');
})
->get();
Inserts
The query builder also provides an insert
method for inserting records into the database table. The insert
method accepts an array of column names and values:
DB::table('users')->insert(
['email' =><EMAIL_ADDRESS>'votes' => 0]
);
You may even insert several records into the table with a single call to insert
by passing an array of arrays. Each array represents a row to be inserted into the table:
DB::table('users')->insert([
['email' =><EMAIL_ADDRESS>'votes' => 0],
['email' =><EMAIL_ADDRESS>'votes' => 0]
]);
Auto-Incrementing IDs
If the table has an auto-incrementing id, use the insertGetId
method to insert a record and then retrieve the ID:
$id = DB::table('users')->insertGetId(
['email' =><EMAIL_ADDRESS>'votes' => 0]
);
{note} When using PostgreSQL the
insertGetId
method expects the auto-incrementing column to be namedid
. If you would like to retrieve the ID from a different "sequence", you may pass the column name as the second parameter to theinsertGetId
method.
Updates
In addition to inserting records into the database, the query builder can also update existing records using the update
method. The update
method, like the insert
method, accepts an array of column and value pairs containing the columns to be updated. You may constrain the update
query using where
clauses:
DB::table('users')
->where('id', 1)
->update(['votes' => 1]);
Update Or Insert
Sometimes you may want to update an existing record in the database or create it if no matching record exists. In this scenario, the updateOrInsert
method may be used. The updateOrInsert
method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs containing the columns to be updated.
The updateOrInsert
method will first attempt to locate a matching database record using the first argument's column and value pairs. If the record exists, it will be updated with the values in the second argument. If the record can not be found, a new record will be inserted with the merged attributes of both arguments:
DB::table('users')
->updateOrInsert(
['email' =><EMAIL_ADDRESS>'name' => 'John'],
['votes' => '2']
);
Updating JSON Columns
When updating a JSON column, you should use ->
syntax to access the appropriate key in the JSON object. This operation is only supported on MySQL 5.7+:
DB::table('users')
->where('id', 1)
->update(['options->enabled' => true]);
Increment & Decrement
The query builder also provides convenient methods for incrementing or decrementing the value of a given column. This is a shortcut, providing a more expressive and terse interface compared to manually writing the update
statement.
Both of these methods accept at least one argument: the column to modify. A second argument may optionally be passed to control the amount by which the column should be incremented or decremented:
DB::table('users')->increment('votes');
DB::table('users')->increment('votes', 5);
DB::table('users')->decrement('votes');
DB::table('users')->decrement('votes', 5);
You may also specify additional columns to update during the operation:
DB::table('users')->increment('votes', 1, ['name' => 'John']);
Deletes
The query builder may also be used to delete records from the table via the delete
method. You may constrain delete
statements by adding where
clauses before calling the delete
method:
DB::table('users')->delete();
DB::table('users')->where('votes', '>', 100)->delete();
If you wish to truncate the entire table, which will remove all rows and reset the auto-incrementing ID to zero, you may use the truncate
method:
DB::table('users')->truncate();
Pessimistic Locking
The query builder also includes a few functions to help you do "pessimistic locking" on your select
statements. To run the statement with a "shared lock", you may use the sharedLock
method on a query. A shared lock prevents the selected rows from being modified until your transaction commits:
DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
Alternatively, you may use the lockForUpdate
method. A "for update" lock prevents the rows from being modified or from being selected with another shared lock:
DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();


OpenSlides is the all-in-one solution for the digital organisation of your assemblies and conferences. Manage and project agenda, motions, elections, documents, lists of speakers and participants with our web-based assembly system – pure, modern and always up-to-date.
Create the right conditions for open communication without losing the focus. For this purpose OpenSlides provides you a modern and powerful tool. Supplement your agenda immediately, react to motion changes in real time and give your delegates controlled access to the system.
Actively integrate the plenum. Open the mobile access to OpenSlides – for get important documents, submit and read motions or check election results.
Accelerate your processes via consistently management with only one software. OpenSlides consolidates the procedure – starting with the preparations of motions and elections up to the final protocol.

Complement, change or move automatically numbered agenda items via drag & drop in the running system. Connect single items with lists of speakers and speaking times and show inofficial items like breaks for better scheduling.
Learn moreCapture motions with applicant and text. Assign categories and motion numbers. Log the resolution and polling results during the motion discussion. The flexible filtering helps you while searching in all motions and their changes.
Learn morePropose candidates off the list of participants. Generate ad-hoc personalized ballots for secret elections. Log and project the counted votes – for all participants accessible in OpenSlides.
Learn moreOpenSlides is designed for working with multiple screens and comes with a powerful projector management. The web interface allows the projection and editing of slides while the projectors are running in full screen.
Learn moreManaging of delegates and their attendance as well as the elaborate permission management are uncomplicated and intuitive. Every area of OpenSlides can be made accessible for certain groups.
No matter if file upload or comment function – OpenSlides is equipped with a multitude of practicable tools. Moreover, we develop custom solutions for our clients.
More featuresYou want to use OpenSlides for your next assembly, but don't want to care about the technical details? Order a fitting hosting package now!
You need individual support at your assembly and professional consultation from the OpenSlides developers? You're missing a function or you want something changed? Arrange an initial consultation now! Our chargeable services:
You want to install OpenSlides on your own server? We offer our software as PyPI package and as source code. Please note that we can offer technical support for our hosting solutions only.
» Installation guide
We pledged ourselves to the principles of a Open Source, liberal and free of charge exchange of our software and even represent this in our name. OpenSlides is usable under the MIT license. Help us to further improve the code.
GitHubYou want to get announcements about new OpenSlides releases? Sign up now for our newsletter:


A Window to the World
William Henry Gates III - better known to the world as Bill - was born in October of 1955. By the time he was 13, he was fascinated by computers and took advantage of programs at his school to get access to the school’s computer systems. He wrote games likes tic-tac-toe in BASIC and later, when he demonstrated his expertise in programming, was enlisted to help a contractor for his school develop payroll programs and class scheduling software.


The probability of meeting people with COVID19 in your venue is:
An example thresholds - use with caution and apply contextual information.
Venue no. planning - the statistical calculations do not consider variation due to mobility


PLAY IT AGAIN, SAM A film review by Ted Prigge Copyright 1997 Ted Prigge
Director: Herbert Ross Writer: Woody Allen (based on his play) Starring: Woody Allen, Diane Keaton, Tony Roberts, Jerry Lacy
Okay, I admit it. I've tried to flirt with girls using movie cliches. There I said it. Does it work? Kinda, sometimes. But I'm an insecure neurotic, and I think they really aren't gonna dig me if I be myself. Now that my self-analyzation is done, I will say that Woody Allen's play "Play it Again, Sam" features a protgonist who's probably more insecure than I am (or anyone else really) or loves movies and thinks that his role model for being a "swinger" should be Humphrey Bogart. And much of the film has the protagonist chatting with a figmented Bogart, with the latter giving the former advice like, "I never knew a woman who didn't understand a slap in the face or a slug form a .45," or "Somewheres in life you got turned around; Its her job to smell good for you."
Woody didn't direct this wonderfully engaging romantic comedy, as many believe. Verstatile director, Herbert Ross, who can direct neurotic comedies like this and "The Goodbye Girl" and still do fluff like "Footloose" and "Steel Magnolias" did, and he somehow manages to get the right feel for it, even if it takes place in Woody's vision of the 10th ring of Dante's Hell - California (San Francisco to be exact). And this is the first time we ever see Diane and Woody together as a comic duo on celluloid (although I think they did it on Broadway together). And Tony Roberts is also on for the first time with Woody as (GASP!) his best friend.
The plot centers around Allan (the Woodster), who has just broken up with his wife, Nancy (Susan Anspatch). He's incredily depressed and he's a major hypochondriac ("I'm turning into an aspirin junkie. Soon I'll be burning the cotton at the top to get the extra"). He's also a film geek (making us look good) who writes for a film magazine. In the beginning, the film shows the final scene of "Casablanca," then pulls back to show Allan watching in literal awe with his mouth wide open at the greatness of the film. Once the film's over, he leaves and his voice-over narration tells us the exposition (which I have already done for you, thank you very much).
His best friend, Dick (Tony), and his wife, Linda (Diane), come over to help him but he just can't get over his wife leaving him. They somehow manage to get him to try to move on by setting him up on dates. The first one is a comical disaster, with him overdoing everything and being so nervous that he ends up breaking records, lamps and knocking down chairs and what-not in his messy apartment. His second one, with a famed nymphomaniac, ends tragically (and ironically) when he tries to take advantage of her.
Meanwhile, he becomes closer to Linda as Dick is a workaholic and is always leaving his number at his office wherever he goes (in a running gag). And before we know it, Dick has gone off on a business trip and Allan and Linda realize they are in love...or at least temporary/sorta love. They sleep together and plan to live together and all, but he realizes he would be hurting a friend...and that he is in "Casablanca." In one of the funniest scenes of the whole 70s as a decade, Allan gives Linda the "Maybe not today, maybe not tomorrow..." speech from the finale of "Casablanca" (Linda even dons the Ingrid Bergman hat as she leaves her apartment to chase after Dick). In the end, Allan has moved on and realized to be himself.
It would be fluff, but it is handled so hysterially that it has been given the title of "classic." This film came right in the middle of his slapstick period, so that may be the reason why Woody didn't direct it. But his writing is perfectly on and his knack for creating comical situations and realistically funny characters is also as good as his later material. This is one of his most perfectly realized films, even if he didn't direct it, and also one of my favorites.
MY RATING (out of 5): *****
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


!/0 (cut)
'!/0 (cut)' – removes choice points
FORMS
FirstGoal, !, SecondGoal
FirstGoal, !; SecondGoal
DESCRIPTION
Discards all choice points made since the parent goal started execution,
including the choice points, if any, created by calling the parent goal. In the
following two cases, a cut in Condition will remove all choice points created by the Condition, any subgoals to the left of the Condition, and the choice point for the parent goal.
Condition = (Things, !, MoreThings)
Condition->TrueGoal; FalseGoal
call(Condition)
In other words,
->
call/1
;
:
,
are transparent to cut. The ISO Prolog Standard requires that call/1 be opaque to cut. At this time, ALS Prolog deviates from the standard.
EXAMPLES
In the following example, the solution eats(chris,pizza)causes a cut to be executed. This removes the choice point for the goal eats/2. As a result, the solution eats(mick,pizza) is not found, even though Mick will eat anything.
?- [user].
Consulting user.
eats(chris,pizza) :- !.
eats(mick,Anything).
user consulted.
yes.
?- eats(Person,pizza).
Person = chris;
no.
The next example shows that not/1 is opaque to cut. This means that a ‘!’ inside the call to not/1 will not cut out the choicepoint for not/2, or any other choicepoints created by goals to the left of not/2.
?- not((!,fail)).
yes.
Notice the extra pair of parentheses above. This is to prevent the parser from
creating a goal to not/2 instead of not/1. In the next example, the transparency of call/1 with respect to cut is shown:
?- [user].
Consulting user.
cool(peewee) :- call((!,fail)).
cool(X).
user consulted.
yes.
?- cool(peewee).
no.
?- cool(bugsbunny).
yes.
peewee is not cool because the ‘!’ removed the choicepoint for cool/1. The fail after the ‘!’ prevented cool/1 from succeeding. The rationale for having cut behave this way is so that:
cool(peewee) :- call((!,fail)).
will be equivalent to
cool(peewee) :- !,fail.
The next example shows the transparency of -> with respect to cut.
?- [-user].
Reconsulting user.
cool(X) :- (X=peewee,!) -> fail.
cool(X).
user reconsulted.
yes.
?- cool(peewee).
no.
Again, peewee is not considered cool. In the goal
?- cool(peewee).
the ‘!’ after X=peewee cuts the choicepoint for cool/1. The condition succeeds, causing fail to be executed. However, the second clause is never reached because the
choicepoint has been cut away. Consequently, the goal fails. The goal
?- cool(daffyduck).
succeeds because the ‘!’ is never reached in the condition of ->. The -> fails because there is no else subgoal. This causes the next clause for cool/1 to be executed. This clause always succeeds, therefore daffyduck is considered cool.
SEE ALSO
->/2, not/1,
[Bowen 91, 7.1], [Sterling 86, 11], [Bratko 86, 5.1], [Clocksin 81, 4.2].


fulforddata package¶
Subpackages¶
Submodules¶
fulforddata.constants module¶
fulforddata.nexus module¶
-
class
fulforddata.nexus.
Nexus
(template)[source]¶ Bases:
object
-
add
(unpackers, *args)[source]¶ - Adds valid entries (passed later) in format given by unpackers
- to self.entries.
Invalid entries added to self.rejects Un-unpackable entries added to self.packed
Passes extra args to each getter.
-
get_dictionaries
(form, *args)[source]¶ Given dictionary (form), runs accessor values on each of the entries stored.
- Example form is {
“time”: access(“x”), “measures”: {
“pirates”: access(“y1”, default=0), “CO 2”: access(“y2”, mapping=lambda n: round(n, 3))}
}
-
get_rows
(columns, fill='', *args)[source]¶ Returns data as rows according to given columns
Examples given use columns: [
(0, access(“x”, default=0, mapping=IDENTITY)), (2, access(“y”, mapping=abs))]
(Columns can also be a dictionary)
-


Turbolinks
Crystal engine for Turbolinks integration. Extends HTTP::Handler
, so you can use it as middleware in any web application. Don't forget to grab the frontend code for Turbolinks.
Installation
Add this to your application's shard.yml
:
dependencies:
turbolinks:
github: bentranter/turbolinks
Usage
Turbolinks extends HTTP::Handler
, so it can be used as HTTP middleware. You can use it with the standard library like so:
require "http/server"
require "turbolinks"
HTTP::Server.new("<IP_ADDRESS>", 3000, [
Turbolinks::Handler.new,
]).listen
or with a framework that supports standard HTTP middleware. For example, you can use Turbolinks with Kemal like so:
require "kemal"
require "turbolinks"
# Calling `add_handler` is Kemal's way of registering HTTP middleware.
add_handler Turbolinks::Handler.new
get "/"
"Served by Turbolinks!"
end
Kemal.run
A Note About Security
A common pattern if you're coming from the Rails world (and using something like rails-ujs) a common approach is to handle a POST
request, and then redirect to another route. Turbolinks handles this case by intercepting the redirection after the POST
request executes, and then responding with a JavaScript snippet to execute Turbolinks.visit("#{location}")
for the location to redirect to.
While this is typically safe, if your handler allows the user to input this location
, you open yourself up to JavaScript injection. Lets look at two examples where a user is leaving a comment, submitted through a form post
request.
require "kemal"
require "turbolinks"
add_handler Turbolinks::Handler.new
# Unsafe approach!
post "/unsafe-comment" do |env|
title = env.params.body["title"]
comment = env.params.body["comment"]
# Imagine `new_comment` does something to handle a new commment, for
# example's sake.
new_comment(title, comment)
# This is dangerous because the value of `title` here could be anything --
# including malicious JavaScript. Since the frontend will excute JavaScript
# containing the value of this redirect here, any malicious JavaScript will
# execute.
env.redirect "/comments/#{title}"
end
# Safe approach.
post "/safe-comment" do |env|
title = env.params.body["title"]
comment = env.params.body["comment"]
# Imagine `new_comment` does something to handle a new commment, for
# example's sake.
comment_id = new_comment(title, comment)
# This is safe because there's no way for the user submitted `title` or
# `comment` to be available in the returned JavaScript -- you generate an
# ID, and redirect to that route.
env.redirect "/comments/#{comment_id}"
end
Kemal.run
If you must do something like the unsafe approach, you'll need to sanitize the input yourself.
A Note For Non rails-ujs
Users
In order for form submissions not to trigger a full page reload, you'll need to ensure that those submissions are submitted as AJAX requests. While a library like Rails-UJS or JQuery-UJS would handle this for you, it's straightforward to implement this yourself. The following JavaScript snippet adds bare-minimum support for AJAX form submissions that work with Turbolinks, but I encourage to look at what rails-ujs
does as well.
(function() {
"use strict";
/*
* For Google Analytics, you need this:
* <body>
* <script>_gaq.push(['_trackPageview']);</script>
* ...the rest of the body here...
* </body>
* See https://coderwall.com/p/ypzfdw/faster-page-loads-with-turbolinks for
* more info.
*/
/*
* By default, Turbolinks submits forms normally. While this may feel
* frustrating as a consumer of the library, it makes sense:
* - No specialized logic on the backend
* - Cache is purged since the page refreshed.
* However, that's not always what you want. By using the functionality
* below, forms are submitted via AJAX, as recommended in the Turbolinks
* documentation.
*/
document.addEventListener("DOMContentLoaded", function() {
/**
* submit sends an HTTP request via XHR.
* @param {*Object} formEl - the form element to submit via XHR.
*/
function submit(formEl) {
var xhr = new XMLHttpRequest();
xhr.open(formEl.method, formEl.action, true);
/* See
* https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/ajax.coffee
* for a more in-depth usage.
*/
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var script = document.createElement("script");
script.innerText = xhr.responseText;
document.head.appendChild(script).parentNode.removeChild(script);
}
}
/* Set relevant headers that some backends check for */
xhr.setRequestHeader("Turbolinks-Referrer", window.location.href);
xhr.setRequestHeader("X-Requested-With", "xhr");
xhr.send(new FormData(formEl));
return false;
}
/* Intercept **any** submit event to submit via XHR instead. */
document.addEventListener("submit", function(e) {
e.preventDefault();
if (e.srcElement) {
submit(e.srcElement);
}
});
});
})();
Development
Turbolinks follows the typical Crystal project structure, so cloning the repo and making changes is all you need to do. However, you're encouraged to run this backend alongside the Turbolinks frontend to make sure it works as expected, especially when compared to the Rails backend. The Turbolinks frontend is available at github.com/turbolinks/turbolinks, and the Rails gem is available at github.com/turbolinks/turbolinks-rails.
Contributing
- Fork it ( https://github.com/[your-github-name]/turbolinks/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Make sure the tests pass, adding any necessary new tests
- Format your code with
crystal tool format
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
Contributors
- bentranter Ben Tranter - creator, maintainer
License
The MIT License (MIT). Copyright (c) 2017-2020 Ben Tranter. See the LICENSE for more info.


Developing enterprise software applications with security requirements can be a cumbersome and error-prone process. In such applications often the security is spread all over the application code. This makes it difficult to understand how things work and hard to maintain security in such code.
With model-driven development business logic should be expressed in the objects of your domain model. As for now there is no convenient way to express access control requirements through your domain model. Hence access control-code is normally written into the service layer or data-access layer.
JPA Security offers a way to express access control through your domain model and additionally supplies a solution to completely separate access control logic from business logic, improving performance and maintainability. JPA Security provides an interface to define security requirements of your domain model via configuration (Annotations or XML).
Due to it's smooth integration into current Java standards, it may be integrated into every layer of your application. It enables you to configure rules defining access control for your Entity Beans and Embeddables based on the current security context (i.e. the currently authenticated user and/or its roles in the application).
JPA Security uses the notion of security unit to refer to a set of Java bean classes and their corresponding access rules. In the current version of JPA Security a security unit directly corresponds to a persistence unit of JPA. The content of a security unit is defined at deployment time and may not change at runtime.
In contrast to the security unit, the security context starts at runtime with the authentication of a user. As of version 0.4.0 of JPA Security the content of this context is completely customizable and you can do so by implementing the SecurityContext interface. The security context contains information like i.e. the current user, its roles and/or the current tenant, but any kind of context information that is needed to specify the authorization of the current user to access beans may be made available through the security context.
JPA Security smoothly integrates with existing authentication solutions like specified in the servlet specification, with EJB or Spring Security. JPA Security may be configured to take the current user and its roles provided by this technologies and fill the security context with it.
Authorization is the process of giving someone permission to do or see something. It is used to determine what the authenticated user is allowed to do in the application and what data he is allowed to see.
There are different ways of organizing authorization. Widely used approaches are role-based authorization or access control lists.
Access Control is the process of allowing and forbidding access to resources based on the authorization of the current security context. There are different levels of access control.
In JPA Security the access to entities and embeddables is defined by access rules. There is one set of access rules per security unit. This set of access rules applies to every JPA query and every entity and embeddable you get out of an EntityManager of the persistence unit that corresponds to that security unit.
The following rule restricts the read access to accounts, where the owner is equal to the current user. In other words: every user can read only its own accounts.
GRANT READ ACCESS TO Account account WHERE account.owner = CURRENT_PRINCIPAL
In the previous example the CURRENT_PRINCIPAL is provided by the currently active security context. When the access rule is evaluated, the CURRENT_PRINCIPAL is received from the security context and the rule is evaluated against this principal
JPA Security allows the definition of rules that grant create, read, update and/or delete access. Currently there is no explicit way to deny access. Although this is not needed, since every entity or embeddable to which no access is granted may not be accessed. An exception from this behavior are classes for which no access rule exists at all. Objects of such class may be accessed without any restriction.
The general syntax of an access rule of JPA Security looks like GRANT [CREATE] [READ] [UPDATE] [DELETE] ACCESS TO entity_name alias [where_clause], where entity_name must be an entity or embeddable of the persistence unit (according to the JPA Specification, defaults to the class name if not otherwise specified) and the alias is an alias for that entity or embeddable that may be used in the where clause.
The syntax of the where_clause is derived from the syntax of WHERE clauses of JPQL, the query language of JPA. Within the clause any alias may be used that is defined by your current security context. The build-in security contexts define two aliases, which are CURRENT_PRINCIPAL and CURRENT_ROLES. The CURRENT_PRINCIPAL alias will be evaluated to the currently authenticated principal during runtime and the CURRENT_ROLES alias will be expanded to a list of roles that the current principal belongs to. No input parameters may be used in the WHERE clause of access rules. If you need more aliases to be defined (i.e. CURRENT_TENANT), you will have to implement your own security context like described later.
With JPA Security there are two predefined ways to provide access rules: via XML configuration or via Annotations. In a later chapter we will see how to implement your own way of providing access rules.
One predefined way to provide access rules in JPA Security is via a file called security.xml, which is located in the META-INF directory of your application. Below is an example of the structure of such file:
<security xmlns="http://jpasecurity.sf.net/xml/ns/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jpasecurity.sf.net/xml/ns/security http://jpasecurity.sf.net/xml/ns/security/security_1_0.xsd" version="1.0"> <persistence-unit name="..."> <access-rule>...</access-rule> ... </persistence-unit> </security>
The other predefined way to provide access rules in JPA Security is via Annotations. You may annotate your entity classes with one of the following two annotations: javax.annotation.security.RolesAllowed and org.jpasecurity.security.rules.Permit.
Note that the semantics of the @RolesAllowed annotation slightly differs between the EJB Specification and JPA Security: If you annotate a class with the @RolesAllowed annotation this means for EJB any access to any method of an instance of that class will cause a SecurityException, if the current user is not in one of the roles allowed. JPA Security goes a step further: The current user will not retrieve this object from database if he is not in one of the roles allowed. JPA Security does not support the @RolesAllowed annotation at method-level.
The @Permit annotation has two optional parameters:
Example:
@Permit(access = AccessType.READ, rule = "owner = CURRENT_PRINCIPAL") public class Account { ... }
Read-access rules are applied to every entity or embeddable that is accessed via a JPA-Security-enabled EntityManager or via object-navigation through objects obtained from such EntityManager. When the object is accessed via JPQL, the access rules are applied directly to the JPQL-query, allowing the filtering to take place within the database. When the object is accessed via object-navigation, JPA Security tries to avoid database-calls and evaluates the rules in memory. When in-memory-evaluation is not applicable and the entity-manager is still open, a query is performed to evaluate the query. In the next section you can read, in which cases in-memory-evaluation is applicable and where not. When in-memory-evaluation is not applicable and the entity-manager is already closed, a SecurityException will be thrown.
Update-access rules are applied on flush() or commit(). Again the default-behaviour is in-memory-evaluation then, falling back to a query like described above.
Create-access rules and delete-access rules are applied when the appropriate action is performed with the entity-manager (either direct or by cascading). In-memory-evaluation applies like described above.
For all cases JPA Security is clever enough to apply the appropriate access rules for sub- and superclasses, too.
Every access rule that does not contain any sub-select can be evaluated in memory. For queries that contain sub-selects it depends on the kind of the sub-select and the content of the (first-level) entity-manager-cache of JPA Security. Sub-selects where all aliases from within the sub-select can directly replaced with an alias from outside can be evaluated in memory. Thus the following access rule can be evaluated in memory:
GRAND ACCESS TO TestBean bean WHERE EXISTS (SELECT b FROM TestBean b WHERE b = bean AND b.accessControlList = CURRENT_PRINCIPAL)
Since the alias from within the sub-select cannot directly replaced by the alias from outside, the following query cannot be evaluated in memory:
GRAND ACCESS TO TestBean bean WHERE EXISTS (SELECT entry FROM AccessControlListEntry entry WHERE bean.accessControlList = entry.accessControlList AND entry IN (CURRENT_ROLES)
Although there can be no guarantee in general that the last query can be evaluated in memory, in-memory-evaluation can still be achieved by ensuring that the entities that are needed to evaluate the sub-select are contained in the (first-level) entity-manager-cache. For example the last rule can be evaluated in memory if there exists an AccessContolListEntry in the cache that meets the specified where-clause. Remember, that on persist the check will be done before the persist-operation is cascaded. So when you want to persist a TestBean that contains an accessControlList with entries that match the where-clause, you have to persist the entries before you persist the TestBean to ensure the entries are in the cache.
Authentication is the process of determining and verifying the identity of someone or something. In multi-user applications, the process of authentication for an application is needed to get knowledge about the person that is currently using the application. The widely used process for authentication is a login process during which the user is asked for his username and password. A user that knows one of this username/password-tuples is assumend to be the person belonging to that username. Besides username/password authentication there are other methods like public-key-authentication with a digital certificate, to name just one.
JPA Security uses an implementation of the org.jpasecurity.configuration.SecurityContext interface to be aware of the currently authenticated user and other related information (like its roles, tenant, ...) at runtime.
By default JPA Security will try to auto-detect your security context. This is done via the indirection of an authentication provider. An authentication provider provides access to the current authenticated user and its roles. The detection follows the following rules (The first matching rule is taken):
When the described auto-detection strategy does not work for your environment, you may specify the class name of any implementation of the org.jpasecurity.configuration.SecurityContext interface as value of the persistence-property org.jpasecurity.security.context in your persistence.xml. To provide backward compatibility to JPA Security 0.3 org.jpasecurity.security.authentication.provider is also valid, if you specify a class name of an implementation of the org.jpasecurity.configuration.AuthenticationProvider interface, but any specification of the org.jpasecurity.security.context property will take precedence.
In order to use JPA Security you have to enable it for your persistence unit. This can be done by modifying your "persistence.xml" to point to JPA Security. Additionally you have to configure JPA Security to use your original persistence provider.
persistence.xml ExampleSupposed you have an existing JPA application. Your persistence.xml may look similar to this:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="your-persistence-unit-name" transaction-type="..."> <provider>your.persistence.provider.ClassName</provider> <class>your.persistent.ClassName</class> <!-- More class-mappings go here --> ... <properties> <!-- persistence-provider-specific properties go here --> ... </properties> </persistence-unit> </persistence>
After integrating JPA Security your "persistence.xml" may look like this:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="your-persistence-unit-name" transaction-type="..."> <provider>org.jpasecurity.persistence.SecurePersistenceProvider</provider> <class>your.persistent.ClassName</class> <!-- More class-mappings go here --> ... <properties> <property name="org.jpasecurity.persistence.provider" value="your.persistence.provider.ClassName" /> <!-- persistence-provider-specific properties go here --> ... </properties> </persistence-unit> </persistence>
We changed the <provider> tag to point to JPA Security's implementation of the PersistenceProvider interface and added the property org.jpasecurity.persistence.provider to point to your original persistence provider. That is all you need to integrate JPA Security.
To use Java EE authentication information for JPA Security you may integrate JPA Security like described in the previous chapter and specify org.jpasecurity.security.authentication.EjbAuthenticationProvider as authentication provider in your persistence properties. You need to define all the roles your application is using with the @DeclareRoles annotation at at least one of your entity beans in order to make the EjbAuthenticationProvider work correctly.
If you do not have a version of a spring-security.jar in your classpath usually you do not need to define your own authentication provider as the auto-detection mechanism of JPA Security should automatically install the EjbAuthenticationProvider.
To use Servlet authentication information for JPA Security within your JSF application you may integrate JPA Security like described in the previous chapter and specify org.jpasecurity.jsf.authentication.JsfAuthenticationProvider as authentication provider in your persistence properties. You need to define all the roles your application is using with the @DeclareRoles annotation at at least one of your entity beans in order to make the JsfAuthenticationProvider work correctly.
If you do not have a version of a spring-security.jar in your classpath usually you do not need to define your own authentication provider as the auto-detection mechanism of JPA Security should automatically install the EjbAuthenticationProvider (if you are in a Java EE server) or the JsfAuthenticationProvider if you are using JSF outside a Java EE server, both using Servlet authentication information.
You need to have the jpasecurity-jsf module in your classpath in order to make the JsfAuthenticationProvider work.
If you are using the Spring-framework with Spring Security, you don't have to follow the chapter Getting started with JPA Security (also you can do and specify the org.jpasecurity.security.authentication.SpringAuthenticationProvider in your persistence.properties).
The easiest way to integrate Spring-Security is to simply replace your LocalEntityManagerFactoryBean or LocalContainerEntityManagerFactoryBean in your Spring configuration with the appropriate counterpart in the org.jpasecurity.spring.persistence package (which are SecureLocalEntityManagerFactoryBean and SecureContainerEntityManagerFactoryBean).
The autodetection mechanism of JPA Security will automatically detect that you are using Spring Security, but you can specify your security context or authentication provider as bean property of the Secure*EntityManagerFactoryBean in your spring configuration.
You need to have the jpasecurity-spring module in your classpath to use spring security.
If you neither use Java EE authentication nor Servlet authentication (via JSF) nor Spring-Security you either have to provide your own implementation of the org.jpasecurity.configuration.SecurityContext interface or you have to use one of the build-in authentication providers, which are DefaultAuthenticationProvider and StaticAuthenticationProvider.
Both provide methods to authenticate users and roles and methods to apply runAs behavior. The DefaultAuthenticationProvider may be used in server-site applications where the authentication is on a per-thread-basis whereas the StaticAuthenticationProvider may be used on client-site applications where authentication per vm is intended.
You may take a look at the simple tutoral to see an example of using the StaticAuthenticationProvider. In the next chapter you will learn how to provide a custom security context or authentication provider.
JPA Security is configured via the persistence properties in your persistence.xml. Below is a list of persistence properties that are supported out of the box by JPA Security.
As stated before you may implement your own way of providing access rules (i.e. via JDBC). You have to implement the interface org.jpasecurity.security.rules.AccessRulesProvider and specify the property org.jpasecurity.security.rules.provider in your persistence.xml with the classname of your implementation of the interface org.jpasecurity.security.rules.AccessRulesProvider. Take a look at its javadoc documentation for further reference.
Your custom access rules provider may need additional configuration parameters. You can define them via the persistence properties in your persistence.xml. All you have to do, is to implement the interface org.jpasecurity.persistence.PersistenceInformationReceiver. Then you will have the persistence properties injected when your persistence provider is initialized.
When you take a look at the methods of org.jpasecurity.rules.AccessRulesProvider, you may notice that you need to create objects of type org.jpasecurity.security.AccessRule. This objects may be created using a org.jpasecurity.jpql.parser.JpqlParser in conjunction with an org.jpasecurity.security.rules.AccessRulesCompiler, but you may subclass org.jpasecurity.security.rules.AbstractAccessRulesProvider to inherit this functionality. Then you have to override initializeAccessRules and call compileRules from within.
The following code shows how to implement an access rules provider that reads its access rules from a database. You may specify the needed parameters in your persistence.xml.
public class JdbcAccessRulesProvider extends AbstractAccessRulesProvider { public static final String ACCESS_RULES_JDBC_URL_PROPERTY = "org.jpasecurity.security.rules.jdbc.url"; public static final String ACCESS_RULES_JDBC_USERNAME_PROPERTY = "org.jpasecurity.security.rules.jdbc.username"; public static final String ACCESS_RULES_JDBC_PASSWORD_PROPERTY = "org.jpasecurity.security.rules.jdbc.password"; public static final String ACCESS_RULES_JDBC_TABLE_PROPERTY = "org.jpasecurity.security.rules.jdbc.table"; public static final String ACCESS_RULES_JDBC_COLUMN_PROPERTY = "org.jpasecurity.security.rules.jdbc.column"; protected void initializeAccessRules() { Map<String, String> properties = getPersistenceProperties(); String url = getPersistenceProperty(ACCESS_RULES_JDBC_URL_PROPERTY); String username = getPersistenceProperty(ACCESS_RULES_JDBC_USERNAME_PROPERTY); String password = getPersistenceProperty(ACCESS_RULES_JDBC_PASSWORD_PROPERTY); String table = getPersistenceProperty(ACCESS_RULES_JDBC_TABLE_PROPERTY); String column = getPersistenceProperty(ACCESS_RULES_JDBC_COLUMN_PROPERTY); Connection connection = null; Statement statement = null; ResultSet resultSet = null; Collection<String> accessRules = new HashSet<String>(); try { connection = DriverManager.getConnection(url, username, password); statement = connection.createStatement(); resultSet = statement.executeQuery("SELECT " + column + " FROM " + table); while (resultSet.next()) { accessRules.add(resultSet.getString(1)); } compileRules(accessRules); } catch (SQLException e) { throw new PersistenceException("Error reading access rules", e); } finally { close(resultSet); close(statement); close(connection); } } private String getPersistenceProperty(String propertyName) { String propertyValue = getPersistenceProperties().get(propertyName); if (propertyValue == null) { throw new PersistenceException("Error reading acces rules, property " + propertyName + " must be set"); } return propertyValue; } private void close(ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { //ignore } } } private void close(Statement statement) { if (statement != null) { try { statement.close(); } catch (SQLException e) { //ignore } } } private void close(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { //ignore } } } }
In your persistence.xml you can specify the needed parameters like following.
<persistence ...> <persistence-unit name="..." ...> ... <properties> <property name="org.jpasecurity.security.rules.jdbc.url" value="jdbc:your.db.url" /> <property name="org.jpasecurity.security.rules.jdbc.username" value="your_username" /> <property name="org.jpasecurity.security.rules.jdbc.password" value="your_password" /> <property name="org.jpasecurity.security.rules.jdbc.table" value="your_table_with_access_rules" /> <property name="org.jpasecurity.security.rules.jdbc.column" value="your_column_containing_the_access_rules" /> </properties> </persistence-unit> </persistence>
You can implement a custom security context in a similar way like the access rules provider. You only have to implement the interface org.jpasecurity.configuration.SecurityContext and specify the property org.jpasecurity.security.context in your persistence.xml with the classname of your implementation of the interface org.jpasecurity.configuration.SecurityContext. Take a look at its javadoc documentation for further reference.
As your access rules provider your custom security context may need additional configuration parameters, too. You also can define them via the persistence properties in your persistence.xml. Again you have to implement the interface org.jpasecurity.persistence.PersistenceInformationReceiver to have the persistence properties injected when your security context is initialized.
The following code shows how to implement a security context that reads its authentication information from the HttpSession.
public class SecurityContextFilter implements SecurityContext, Filter { private static final Alias PRINCIPAL_ALIAS = new Alias("principal"); private static final Alias ROLES_ALIAS = new Alias("roles"); private static final Alias TENANT_ALIAS = new Alias("tenant"); private static final Collection<Alias> ALIASES = Collections.unmodifiableList(Arrays.asList(PRINCIPAL_ALIAS, ROLES_ALIAS, TENANT_ALIAS)); private static ThreadLocal<HttpSession> session = new ThreadLocal<HttpSession>(); public Collection<Alias> getAliases() { return ALIASES; } public Object getAliasValue(Alias alias) { HttpSession session = SecurityContextFilter.session.get(); if (session == null) { return null; } return session.getAttribute(alias.getName()); } public Collection<?> getAliasValues(Alias alias) { Object aliasValue = getAliasValue(alias); if (aliasValue instanceof Collection) { return (Collection<?>)aliasValue; } else if (aliasValue == null) { return null; } else if (aliasValue.getClass().isArray()) { return Arrays.asList((Object[])aliasValue); } else { return Collections.singleton(aliasValue); } } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { if (request instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest)request; AuthenticationFilter.session.set(httpRequest.getSession()); } chain.doFilter(request, response); } finally { AuthenticationFilter.session.remove(); } } public void init(FilterConfig config) throws ServletException { } public void destroy() { } }
You now have to specify the class as web filter in your web.xml.
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> ... <filter> <filter-name>securityContextFilter</filter-name> <filter-class>your.package.SecurityContextFilter</filter-class> </filter> <filter-mapping> <filter-name>securityContextFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ... </web-app>
Now your login-process may store the authentication information (the principal, roles and tenant) in the HttpSession and you are done.
JPA Security intercepts your action with the EntityManager. Whenever you retrieve an entity from your EntityManager, it is subsidized by a proxy from JPA Security. Likewise whenever you perform a JPQL-query, it is modified with additional clauses and parameters to match your security rules.
JPA Security modifies the where-clause of your JPQL queries by adding restrictions according to your access rules. This behavior enforces security-rule-evaluation within the database. Only database rows resulting in entities that the user is allowed to read will be loaded. When using Hibernate as persistence provider, the Hibernate-WITH-clause is supported by JPA Security.
The proxies that are created around your entities are called SecureEntity (actually they implement an interface of the same name). This is how they behave:
Collection relationships (i.e. one-to-many- and many-to-many-relations) are handled via SecureCollections. Secure collections are filtered in memory and the backing collection will contain every entity of the original relationship. The main difference is that when you access any method of a secure collection it will behave, as if it only contained those entities you are allowed to read. In addition write-access will only be possible if write-access is allowed to the owning entity. Furthermore, for performance reasons every modification to a secure collection is queued and will not be executed until a commit operation.
Every entity that was loaded over a secured EntityManager can be casted to SecureEntity. This interface provides methods to programmatically check accessibility, force read- and write-check (via refresh() and flush()) and check the state of the entity.
A secure EntityManager can be casted to AccessManager, which allows programmatic security-checks, too.
On every operation that does not result into a query to the database JPA Security tries to check the configured access rules in memory. That means, for normal create-, update- and delete-operations, no database interaction is needed for the access check.
In-memory evaluation works perfectly, when no subselect is contained in the access rules. When the access rules contain subselects, some constraints are placed on the definition of the access rules. The first restriction is, that access rules that contain subselects may only contain subselects within EXISTS-clauses and not within IN-clauses. This restriction is likely to change in the future.
For example the following works:
GRANT ACCESS TO TestEntity entity WHERE EXISTS (SELECT e FROM TestEntity e WHERE e = entity AND ...)
Whereas the following will not work for the current release:
GRANT ACCESS TO TestEntity entity WHERE entity IN (SELECT e FROM TestEntity e WHERE ...)
Every subselect that contains only references to pathes to properties of the checked entity will work.
For example the following works, since acl is a direct reference to a property of the checked entity (indicated by acl = entity.acl):
GRANT ACCESS TO TestEntity entity WHERE EXISTS (SELECT acl FROM AccessControlList acl WHERE acl = entity.acl AND ...)
Whereas the following will not work since there is no direct path from a property of the checked entity to e (Reverse navigation would take place from e.acl to e, which is currently not supported).
GRANT ACCESS TO TestEntity entity WHERE EXISTS (SELECT e FROM AclEntry e WHERE e.acl = entity.acl)
The access rule could be rewritten to work with in-memory evaluation:
GRANT ACCESS TO TestEntity entity WHERE EXISTS (SELECT e FROM AccessControlList acl JOIN acl.entries e WHERE acl = entity.acl)
When in-memory evaluation cannot take place within the previously defined constraints, there is another chance to evaluate a query in memory: When the entities that are needed for the specified evaluation are already loaded within the specific EntityManager, evaluation will take place based on that entities. That means, if every AclEntry of the specific entity was loaded into memory by previous operations, the following access rule can be evaluated:
GRANT ACCESS TO TestEntity entity WHERE EXISTS (SELECT e FROM AclEntry e WHERE e.acl = entity.acl)
When an access rule cannot be evaluated the access-check will return false. This behavior will change in the future since it is not deterministic since the evaluation depends on previously loaded entities.


ScrollAreaGadget()
语法
Result = ScrollAreaGadget(#Gadget, x, y, Width, Height, ScrollAreaWidth, ScrollAreaHeight [, ScrollStep [, Flags]])概要
Creates a ScrollArea gadget in the current GadgetList. It is a container for other gadgets with a scrollable area.
参数
#Gadget A number to identify the new gadget. #PB_Any can be used to auto-generate this number. x, y, Width, Height The position and dimensions of the new gadget. ScrollAreaWidth, ScrollAreaHeight The dimensions of the scrollable area inside the gadget. These can also be smaller than the outer dimensions, in this case scrolling will be disabled. ScrollStep (optional) The amount of pixels to scroll when the user presses the scroll bar arrows. Flags (optional) Flags to modify the gadget behavior. It can be a combination of the following values: #PB_ScrollArea_Flat : Flat frame #PB_ScrollArea_Raised : Raised frame #PB_ScrollArea_Single : Single sunken frame #PB_ScrollArea_BorderLess : Without any border #PB_ScrollArea_Center : If the inner size is smaller than the outer, the inner area is automatically centered.
返回值
Returns nonzero on success and zero on failure. If #PB_Any was used as the #Gadget parameter then the return-value is the auto-generated gadget number on success.
备注
Once the gadget is created, all future created gadgets will be created inside the scroll area. When all the needed gadgets have been created, CloseGadgetList() must be called to return to the previous GadgetList. OpenGadgetList() can be used later to add others gadgets on the fly in the scroll area.
The following functions can be used to act on a ScrollAreaGadget:
GetGadgetAttribute(): With one of the following attribute:#PB_ScrollArea_InnerWidth : Returns the width (in pixels) of the contained scrollable area. #PB_ScrollArea_InnerHeight : Returns the height (in pixels) of the contained scrollable area. #PB_ScrollArea_X : Returns the current horizontal scrolling position (in pixels). #PB_ScrollArea_Y : Returns the current vertical scrolling position (in pixels). #PB_ScrollArea_ScrollStep : Returns the current scroll step value (in pixels).SetGadgetAttribute(): With one of the following attribute:#PB_ScrollArea_InnerWidth : Changes the width (in pixels) of the contained scrollable area. #PB_ScrollArea_InnerHeight : Changes the height (in pixels) of the contained scrollable area. #PB_ScrollArea_X : Changes the current horizontal scrolling position (in pixels). #PB_ScrollArea_Y : Changes the current vertical scrolling position (in pixels). #PB_ScrollArea_ScrollStep : Changes the current scroll step value (in pixels).This gadget supports the SetGadgetColor() and GetGadgetColor() functions with the #PB_Gadget_BackColor type to change the background color.
示例
If OpenWindow(0, 0, 0, 305, 140, "ScrollAreaGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) ScrollAreaGadget(0, 10, 10, 290,120, 375, 155, 30) ButtonGadget (1, 10, 10, 230, 30,"Button 1") ButtonGadget (2, 50, 50, 230, 30,"Button 2") ButtonGadget (3, 90, 90, 230, 30,"Button 3") TextGadget (4,130,130, 230, 20,"This is the content of a ScrollAreaGadget!",#PB_Text_Right) CloseGadgetList() Repeat Select WaitWindowEvent() Case #PB_Event_CloseWindow End Case #PB_Event_Gadget Select EventGadget() Case 1 MessageRequester("Info","Button 1 was pressed!",#PB_MessageRequester_Ok) Case 2 MessageRequester("Info","Button 2 was pressed!",#PB_MessageRequester_Ok) Case 3 MessageRequester("Info","Button 3 was pressed!",#PB_MessageRequester_Ok) EndSelect EndSelect ForEver EndIf
参阅
GetGadgetAttribute(), SetGadgetAttribute(), ScrollBarGadget()
已支持操作系统
所有


layout: index ---
Some understandings of how to make better use of the mcus.
Sharing some resued source code, such as drivers, libraries.
Tools to simplify the embedded development.


This tool lets you convert Connecticut census tracts, as defined by 2010 Census, into towns where these tracts are located. In the input area, type one or more tract numbers. They can be short (eg 303 for Darien) or long<PHONE_NUMBER> for Clinton or 1400000US09001220200 for New Fairfield). Keep it one per line. Press the arrow button to convert.
You can also download a spreadsheet powering this tool, or check out the interactive map to see how new 2020 tract boundaries are different from 2010 boundaries.