| PostgreSQL 9.5.19 Documentation | |||
|---|---|---|---|
| Prev | Up | Appendix E. Release Notes | Next |
Release date: 2018-08-09
This release contains a variety of fixes from 9.5.13. For information about new features in the 9.5 major release, see Section E.20.
A dump/restore is not required for those running 9.5.X.
However, if you are upgrading from a version earlier than 9.5.13, see Section E.7.
Fix failure to reset libpq's state fully between connection attempts (Tom Lane)
An unprivileged user of dblink or postgres_fdw could bypass the checks intended to prevent use of server-side credentials, such as a ~/.pgpass file owned by the operating-system user running the server. Servers allowing peer authentication on local connections are particularly vulnerable. Other attacks such as SQL injection into a postgres_fdw session are also possible. Attacking postgres_fdw in this way requires the ability to create a foreign server object with selected connection parameters, but any user with access to dblink could exploit the problem. In general, an attacker with the ability to select the connection parameters for a libpq-using application could cause mischief, though other plausible attack scenarios are harder to think of. Our thanks to Andrew Krasichkov for reporting this issue. (CVE-2018-10915)
Fix INSERT ... ON CONFLICT UPDATE through a view that isn't just SELECT * FROM ... (Dean Rasheed, Amit Langote)
Erroneous expansion of an updatable view could lead to crashes or "attribute ... has the wrong type" errors, if the view's SELECT list doesn't match one-to-one with the underlying table's columns. Furthermore, this bug could be leveraged to allow updates of columns that an attacking user lacks UPDATE privilege for, if that user has INSERT and UPDATE privileges for some other column(s) of the table. Any user could also use it for disclosure of server memory. (CVE-2018-10925)
Ensure that updates to the relfrozenxid and relminmxid values for "nailed" system catalogs are processed in a timely fashion (Andres Freund)
Overoptimistic caching rules could prevent these updates from being seen by other sessions, leading to spurious errors and/or data corruption. The problem was significantly worse for shared catalogs, such as pg_authid, because the stale cache data could persist into new sessions as well as existing ones.
Fix case where a freshly-promoted standby crashes before having completed its first post-recovery checkpoint (Michael Paquier, Kyotaro Horiguchi, Pavan Deolasee, Álvaro Herrera)
This led to a situation where the server did not think it had reached a consistent database state during subsequent WAL replay, preventing restart.
Avoid emitting a bogus WAL record when recycling an all-zero btree page (Amit Kapila)
This mistake has been seen to cause assertion failures, and potentially it could result in unnecessary query cancellations on hot standby servers.
During WAL replay, guard against corrupted record lengths exceeding 1GB (Michael Paquier)
Treat such a case as corrupt data. Previously, the code would try to allocate space and get a hard error, making recovery impossible.
When ending recovery, delay writing the timeline history file as long as possible (Heikki Linnakangas)
This avoids some situations where a failure during recovery cleanup (such as a problem with a two-phase state file) led to inconsistent timeline state on-disk.
Improve performance of WAL replay for transactions that drop many relations (Fujii Masao)
This change reduces the number of times that shared buffers are scanned, so that it is of most benefit when that setting is large.
Improve performance of lock releasing in standby server WAL replay (Thomas Munro)
Make logical WAL senders report streaming state correctly (Simon Riggs, Sawada Masahiko)
The code previously mis-detected whether or not it had caught up with the upstream server.
Fix bugs in snapshot handling during logical decoding, allowing wrong decoding results in rare cases (Arseny Sher, Álvaro Herrera)
Ensure a table's cached index list is correctly rebuilt after an index creation fails partway through (Peter Geoghegan)
Previously, the failed index's OID could remain in the list, causing problems later in the same session.
Fix mishandling of empty uncompressed posting list pages in GIN indexes (Sivasubramanian Ramasubramanian, Alexander Korotkov)
This could result in an assertion failure after pg_upgrade of a pre-9.4 GIN index (9.4 and later will not create such pages).
Ensure that VACUUM will respond to signals within btree page deletion loops (Andres Freund)
Corrupted btree indexes could result in an infinite loop here, and that previously wasn't interruptible without forcing a crash.
Fix misoptimization of equivalence classes involving composite-type columns (Tom Lane)
This resulted in failure to recognize that an index on a composite column could provide the sort order needed for a mergejoin on that column.
Fix SQL-standard FETCH FIRST syntax to allow parameters ($n), as the standard expects (Andrew Gierth)
Fix failure to schema-qualify some object names
in getObjectDescription
output
(Kyotaro Horiguchi, Tom Lane)
Names of collations, conversions, and text search objects were not schema-qualified when they should be.
Widen COPY FROM's current-line-number counter from 32 to 64 bits (David Rowley)
This avoids two problems with input exceeding 4G lines: COPY FROM WITH HEADER would drop a line every 4G lines, not only the first line, and error reports could show a wrong line number.
Add a string freeing function to ecpg's pgtypes library, so that cross-module memory management problems can be avoided on Windows (Takayuki Tsunakawa)
On Windows, crashes can ensue if the free
call
for a given chunk of memory is not made from the same DLL
that malloc
'ed the memory.
The pgtypes library sometimes returns strings
that it expects the caller to free, making it impossible to follow
this rule. Add a PGTYPESchar_free()
function
that just wraps free
, allowing applications
to follow this rule.
Fix ecpg's support for long
long variables on Windows, as well as other platforms that
declare strtoll
/strtoull
nonstandardly or not at all (Dang Minh Huong, Tom Lane)
Fix misidentification of SQL statement type in PL/pgSQL, when a rule change causes a change in the semantics of a statement intra-session (Tom Lane)
This error led to assertion failures, or in rare cases, failure to enforce the INTO STRICT option as expected.
Fix password prompting in client programs so that echo is properly disabled on Windows when stdin is not the terminal (Matthew Stickney)
Further fix mis-quoting of values for list-valued GUC variables in dumps (Tom Lane)
The previous fix for quoting of search_path and other list-valued variables in pg_dump output turned out to misbehave for empty-string list elements, and it risked truncation of long file paths.
Fix pg_dump's failure to dump REPLICA IDENTITY properties for constraint indexes (Tom Lane)
Manually created unique indexes were properly marked, but not those created by declaring UNIQUE or PRIMARY KEY constraints.
Make pg_upgrade check that the old server was shut down cleanly (Bruce Momjian)
The previous check could be fooled by an immediate-mode shutdown.
Fix contrib/hstore_plperl to look through Perl scalar references, and to not crash if it doesn't find a hash reference where it expects one (Tom Lane)
Fix crash in contrib/ltree's
lca()
function when the input array is empty
(Pierre Ducroquet)
Fix various error-handling code paths in which an incorrect error code might be reported (Michael Paquier, Tom Lane, Magnus Hagander)
Rearrange makefiles to ensure that programs link to freshly-built libraries (such as libpq.so) rather than ones that might exist in the system library directories (Tom Lane)
This avoids problems when building on platforms that supply old copies of PostgreSQL libraries.
Update time zone data files to tzdata release 2018e for DST law changes in North Korea, plus historical corrections for Czechoslovakia.
This update includes a redefinition of "daylight savings" in Ireland, as well as for some past years in Namibia and Czechoslovakia. In those jurisdictions, legally standard time is observed in summer, and daylight savings time in winter, so that the daylight savings offset is one hour behind standard time not one hour ahead. This does not affect either the actual UTC offset or the timezone abbreviations in use; the only known effect is that the is_dst column in the pg_timezone_names view will now be true in winter and false in summer in these cases.


Rules: At the Double, Forward to Victory, Inspiring Presence
Categories: SCENERY, SLAANESH
Unit Abilities: Locus of Savagery, Power of Slaanesh
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Locus of Savagery | At the start of your hero phase, you can pick 1 friendly CHAOS SLAANESH HERO within 6" of this terrain feature to make a sacrifice. If you do so, that Hero suffers 1 mortal wound, and you must roll a dice. On a 1, nothing happens. On a 2+ you can re-roll hit rolls for attacks made by that HERO until your next hero phase. If that HERO has an artefact of power, they can sacrifice that instead of suffering 1 mortal wound. If they do so, that artefact of power can no longer be used (if a weapon was picked when the artefact of power was selected, that weapon reverts to normal). However, on a roll of 2+, you can re-roll hit rolls for attacks made by that HERO for the rest of the battle instead of only until your next hero phase. |
|
| Power of Slaanesh | If you spend depravity points to summon a unit to the battlefield, and that unit is set up wholly within 12" of this terrain feature, you receive D3 depravity points after that unit has been set up. |
Selections: 1. Lash of Slaanesh
Categories: CHAOS, DAEMON, DAEMONETTE, EXALTED CHARIOTS, HERO, SLAANESH, BLADEBRINGER, WIZARD, Leader
Spell: Lash of Slaanesh, Unit: Bladebringer on Exalted Seeker Chariot, Unit Abilities: Excess of Blades, Pungent Soulscent, Weapon: Bladebringer's Flensing Whip, Daemonettes' Piercing Claws, Steed's Poisoned Tongue
| Spell | Casting Value | Description | Ref |
|---|---|---|---|
| Lash of Slaanesh | 5 | Pick 1 point on the battlefield within 12" of the caster that is visible to them, and draw an imaginary straight line 1mm wide between that point and the closest part of the caster's base. Roll a dice for each enemy model passed across by this line. On a 4+ that model's unit suffers 1 mortal wound. |
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Bladebringer on Exalted Seeker Chariot | 10" | 10 | 10 | 4+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Excess of Blades | Roll a dice for each enemy unit that is within 1" of this model after this model finishes a charge move. On a 1, nothing happens. On a 2-4, that unit suffers D3 mortal wounds. On a 5+, that unit suffers D6 mortal wounds. | |
| Pungent Soulscent | At the start of the combat phase, roll a dice for each enemy unit within 1" of this model. On a 2+, that enemy unit suffers D3 mortal wounds. In addition, for each 2+, add 1 to the Attacks characteristic of this model’s melee weapons until the end of that phase. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Bladebringer's Flensing Whip | Melee | 2" | 6 | 3+ | 4+ | -1 | 1 | |
| Daemonettes' Piercing Claws | Melee | 1" | 9 | 3+ | 4+ | -1 | 1 | |
| Steed's Poisoned Tongue | Melee | 1" | 8 | 3+ | 4+ | - | 1 |
Categories: CHAOS, DAEMON, DAEMONETTE, HERALD OF SLAANESH, HERO, INFERNAL ENRAPTURESS, SLAANESH, HEDONITE, Leader
Unit: Infernal Enrapturess, Unit Abilities: Discordant Disruption, Harmonic Alignment, Versatile Instrument, Weapon: Heartstring Lyre: Cacophonous Melody, Heartstring Lyre: Euphonic Blast, Ravaging Claw
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Infernal Enrapturess | 6" | 5 | 10 | 5+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Discordant Disruption | Re-roll successful casting rolls for enemy WIZARDS that are within 24" of one or more models with this ability. In addition, if the re-rolled casting roll is a double, that WIZARD suffers D3 mortal wound after the effects of the spell (if any) have been carried out. | |
| Harmonic Alignment | At the start of your hero phase, you receive 1 depravity point for each friendly INFERNAL ENRAPTURESS that is on the battlefield and part of a Slaanesh army. | |
| Versatile Instrument | Before attacking with a heartstring lyre, choose either the Cacophonous Melody or Euphonic Blast missile weapon characteristics for that shooting attack. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Heartstring Lyre: Cacophonous Melody | Missile | 18" | 6 | 3+ | 4+ | -1 | 1 | |
| Heartstring Lyre: Euphonic Blast | Missile | 24" | 1 | 2+ | 3+ | -3 | D3 | |
| Ravaging Claw | Melee | 1" | 3 | 3+ | 4+ | -1 | 1 |
Selections: 2. Progeny of Damnation, 2. Thrill-seeker, 5. Rageblade, General
Categories: CHAOS, DAEMON, HERO, KEEPER OF SECRETS, MONSTER, SLAANESH, WIZARD, GREATER DAEMON, Behemoth, Leader, General, Artefact
Artefact: Rageblade, Command Abilities: Excess of Violence, Thrill-seeker, Keeper of Secrets Wounds: 00-03, 04-06, 07-09, 10-12, 13+, Magic: Magic, Spell: Cacophonic Choir, Progeny of Damnation, Unit: Keeper of Secrets, Unit Abilities: Dark Temptations, Delicate Precision, Weapon: Elegant Greatblade, Impaling Claws
| Artefact | Artefact Details | Ref |
|---|---|---|
| Rageblade | Pick one of the bearer’s melee weapons to be a Rageblade. Add 1 to the attacks characteristic of that weapon. |
| Command Abilities | Command Ability Details | Ref |
|---|---|---|
| Excess of Violence | You can use this command ability in the combat phase, when it is your turn to pick a unit to fight with. If you do so, pick 1 friendly HEDONITE unit that has already fought once in that combat phase and is wholly within 12" of a model with this command ability. That unit can be selected to fight for a second time if it is within 3" of any enemy units. You cannot pick the same unit to benefit from this command ability more than once in the same combat phase. | |
| Thrill-seeker | This general can run and still charge later in the same turn. If this general already has an ability that allows them to run and still charge later in the same turn, add 3 to run rolls for this general instead. |
| Keeper of Secrets Wounds | Move | Elegant Greatblade | Impaling Claws | Ref |
|---|---|---|---|---|
| 00-03 | 14" | 5 | 5 | |
| 04-06 | 12" | 3 | 4 | |
| 07-09 | 10" | 3 | 3 | |
| 10-12 | 8" | 2 | 3 | |
| 13+ | 6" | 2 | 2 |
| Magic | Cast/Unbind | Spells Known | Ref |
|---|---|---|---|
| Magic | 2/2 | Arcane Bolt, Mystic Shield and Cacophonic Choir |
| Spell | Casting Value | Description | Ref |
|---|---|---|---|
| Cacophonic Choir | 6 | Roll 2D6. Each enemy unit within 6" of the caster that has a Bravery characteristic of less than the roll suffers D3 mortal wounds. | |
| Progeny of Damnation | 7 | Pick 1 friendly DAEMON HEDONITE HERO within 6" of the caster that is visible to them. You can heal D3 wounds allocated to that HERO. If the casting roll was 10+, you can heal D6 wounds allocated to that HERO instead of D3. |
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Keeper of Secrets | * | 14 | 10 | 4+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Dark Temptations | At the start of the combat phase, you can pick 1 enemy HERO within 3" of this model and ask your opponent if they wish that HERO to accept temptation. If they refuse, that HERO suffers D3 mortal wounds. If they accept, add 1 to hit rolls for attacks made by that HERO. Then, at the start of the next combat phase, roll a dice. On 1-3, that HERO no longer receives this modifier to their hit rolls. On 4-6, that HERO is slain. | |
| Delicate Precision | If the unmodified wound roll for an attack made with a melee weapon by this model is 6, that attack inflicts a number of mortal wounds equal to the Damage characteristic of the weapon used for the attack and the attack sequence ends (do not make a save roll). |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Elegant Greatblade | Melee | 2" | * | 3+ | 3+ | -1 | 2 | |
| Impaling Claws | Melee | 3" | 2 | 3+ | 3+ | -2 | * |
Selections: 6. Born of Damnation
Categories: CHAOS, DAEMON, DAEMONETTE, HERALD OF SLAANESH, HERO, SLAANESH, HEDONITE, WIZARD, Leader
Magic: Magic, Spell: Born of Damnation, Overwhelming Acquiescence, Unit: The Contorted Epitome, Unit Abilities: Gift of Power, Horrible Fascination, Swallow Energy, Weapon: Coiled Tentacles, Ravaging Claws
| Magic | Cast/Unbind | Spells Known | Ref |
|---|---|---|---|
| Magic | 2/2 | Arcane Bolt, Mystic Shield, and Overwhelming Acquiescence |
| Spell | Casting Value | Description | Ref |
|---|---|---|---|
| Born of Damnation | 5 | Pick 1 friendly HEDONITE HERO within 6" of the caster that is visible to them. You can heal 1 wound allocated to that HERO. If the casting roll was 10+ you can heal D3 wounds allocated to that HERO instead of 1. | |
| Overwhelming Acquiescence | 7 | You can pick up to D3 enemy units within 24" of the caster that are visible to them. You can re-roll hit rolls of 1 for attacks that target those units until your next hero phase. |
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| The Contorted Epitome | 12" | 7 | 10 | 5+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Gift of Power | You can re-roll casting, unbinding and dispelling rolls for this model. | |
| Horrible Fascination | At the start of the combat phase, roll a dice for each enemy unit that is within 6" of any friendly models with this ability. On a 4+, that unit fights at the end of that combat phase, after the players have picked any other units to fight with in that combat phase. If a unit that is affected by this ability is also affected by any rules that would allow it to fight at the start of the combat phase, that unit is not affected by this rule or those other rules (the effects cancel each other out). |
|
| Swallow Energy | Roll a dice each time you allocate a mortal wound to this model. On a 2+, that mortal wound is negated. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Coiled Tentacles | Melee | 3" | 2 | 3+ | 4+ | -2 | 2 | |
| Ravaging Claws | Melee | 1" | 9 | 3+ | 4+ | -1 | 1 |
Selections: 3x 10 Daemonettes, Hornblower, Icon Bearer, Standard Bearer
Categories: CHAOS, DAEMON, DAEMONETTE, SLAANESH, Battleline
Unit: Daemonettes of Slaanesh, Unit Abilities: Alluress, Hornblower, Icon and Standard Bearers, Icon Bearer, Lithe and Swift, Standard Bearers, Weapon: Piercing Claws
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Daemonettes of Slaanesh | 6" | 1 | 10 | 5+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Alluress | The leader of this unit is the Alluress. Add 1 to the Attacks characteristic of an Alluress' Piercing Claws. | |
| Hornblower | 1 in every 10 models in this unit can be a Hornblower. If the unmodified roll for a battleshock test for an enemy unit that is within 6" of any friendly Hornblowers is 1, that battleshock test must be re-rolled. | |
| Icon and Standard Bearers | 1 in every 10 models in this unit can be an Icon Bearer. In addition, 1 in every 10 models in this unit can be a Standard Bearer. | |
| Icon Bearer | If the unmodified roll for a battleshock test for a unit that includes any Icon Bearers is 1, you can add D6 models to that unit, and no models from that unit will flee in that battleshock phase. | |
| Lithe and Swift | This unit can run and still charge later in the same turn. | |
| Standard Bearers | You can re-roll hit rolls of 1 for attacks made by a unit that includes any Standard Bearers. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Piercing Claws | Melee | 1" | 2 | 4+ | 4+ | -1 | 1 |
Selections: 3x 5 Hellstriders [300pts], Hellreaver, Hellstrider Banner Bearer, Hornblower
Categories: CHAOS, HELLSTRIDERS OF SLAANESH, MORTAL, SLAANESH, Other, Battleline
Unit: Hellstriders, Unit Abilities: Hellreaver, Hellstrider Banner Bearer, Hornblower, Icon and Standard Bearers, Soul Hunters, Weapon: Hellscourge, Steed of Slaanesh's Poisoned Tongue
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Hellstriders | 14" | 2 | 6 | 4+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Hellreaver | 1 model in this unit can be a Hellreaver. Add 1 to the Attacks characteristic of a Hellreaver’s Claw-spear. | |
| Hellstrider Banner Bearer | You can re-roll charge rolls for this unit while it includes any Hellstrider Banner Bearers. | |
| Hornblower | 1 in every 5 models in this unit can be a Hellstrider Hornblower. If the unmodified roll for a battleshock test for an enemy unit that is within 6" of this unit while this unit includes any Hellstrider Hornblowers is 1, that battleshock test must be re-rolled. | |
| Icon and Standard Bearers | 1 in every 5 models in this unit can be a Seeker Banner Bearer, and 1 in every 5 models in this unit can be a Seeker Icon Bearer. | |
| Soul Hunters | If any enemy models were slain by wounds inflicted by this unit’s attacks in the combat phase, add 1 to the Attacks characteristic of this unit’s melee weapons in the next combat phase. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Hellscourge | Melee | 1" | 1 | 3+ | 4+ | -1 | 1 | |
| Steed of Slaanesh's Poisoned Tongue | Melee | 1" | 2 | 3+ | 4+ | - | 1 |
Selections: Seeker Chariot [120pts]
Categories: CHAOS, DAEMON, DAEMONETTE, SEEKER CHARIOT, SLAANESH, HEDONITE, Other, Battleline
Unit: Seeker Chariots, Unit Abilities: Impossibly Swift, Mutilating Blades, Weapon: Daemonettes' Piercing Claws, Flensing Whips, Steeds' Poisoned Tongues
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Seeker Chariots | 12" | 6 | 10 | 4+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Impossibly Swift | This unit can retreat and still charge later in the same turn. | |
| Mutilating Blades | Roll a dice for each enemy unit that is within 1" of a model from this unit after the model from this unit finishes a charge move. On a 2+ that enemy unit suffers D3 mortal wounds. If this unit has more than 1 model, roll to determine if mortal wounds are inflicted after each model completes its charge move, but do not allocate the mortal wounds until after all of the models in the unit have moved |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Daemonettes' Piercing Claws | Melee | 1" | 3 | 3+ | 4+ | -1 | 1 | |
| Flensing Whips | Melee | 2" | 4 | 3+ | 4+ | -1 | 1 | |
| Steeds' Poisoned Tongues | Melee | 1" | 4 | 3+ | 4+ | - | 1 |
Selections: Seeker Chariot [120pts]
Categories: CHAOS, DAEMON, DAEMONETTE, SEEKER CHARIOT, SLAANESH, HEDONITE, Other, Battleline
Unit: Seeker Chariots, Unit Abilities: Impossibly Swift, Mutilating Blades, Weapon: Daemonettes' Piercing Claws, Flensing Whips, Steeds' Poisoned Tongues
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Seeker Chariots | 12" | 6 | 10 | 4+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Impossibly Swift | This unit can retreat and still charge later in the same turn. | |
| Mutilating Blades | Roll a dice for each enemy unit that is within 1" of a model from this unit after the model from this unit finishes a charge move. On a 2+ that enemy unit suffers D3 mortal wounds. If this unit has more than 1 model, roll to determine if mortal wounds are inflicted after each model completes its charge move, but do not allocate the mortal wounds until after all of the models in the unit have moved |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Daemonettes' Piercing Claws | Melee | 1" | 3 | 3+ | 4+ | -1 | 1 | |
| Flensing Whips | Melee | 2" | 4 | 3+ | 4+ | -1 | 1 | |
| Steeds' Poisoned Tongues | Melee | 1" | 4 | 3+ | 4+ | - | 1 |
Selections: 2x 5 Seekers [240pts], Heartseeker, Hornblower, Seeker Icon Bearer, Standard Bearer
Categories: CHAOS, DAEMON, DAEMONETTE, SEEKERS, SLAANESH, Other
Unit: Seekers, Unit Abilities: Heartseeker, Hornblower, Icon and Standard Bearers, Quicksilver Speed, Seeker Banner Bearer, Seeker Icon Bearer, Soul Hunters, Weapon: Piercing Claws, Poisoned Tongue
| Unit | Move | Wounds | Bravery | Save | Ref |
|---|---|---|---|---|---|
| Seekers | 14" | 2 | 10 | 5+ |
| Unit Abilities | Ability Details | Ref |
|---|---|---|
| Heartseeker | 1 model in this unit can be a Heartseeker. Add 1 to the Attacks characteristic of a Heartseeker’s Piercing Claws. | |
| Hornblower | 1 in every 5 models in this unit can be a Seeker Hornblower. If the unmodified roll for a battleshock test for an enemy unit that is within 6" of this unit while this unit includes any Seeker Hornblowers is 1, that battleshock test must be re-rolled. | |
| Icon and Standard Bearers | 1 in every 5 models in this unit can be a Seeker Banner Bearer, and 1 in every 5 models in this unit can be a Seeker Icon Bearer. | |
| Quicksilver Speed | You can roll 2D6 instead of D6 when you make a run roll for this unit. In addition, this unit can run and still charge later in the same turn. | |
| Seeker Banner Bearer | You can re-roll charge rolls for this unit while it includes any Seeker Banner Bearers. | |
| Seeker Icon Bearer | If an unmodified battleshock roll of 1 is made for this unit while it includes any Seeker Icon Bearers, you can add D3 models to this unit, and no models from this unit will flee in that phase. | |
| Soul Hunters | If any enemy models were slain by wounds inflicted by this unit’s attacks in the combat phase, add 1 to the Attacks characteristic of this unit’s melee weapons in the next combat phase. |
| Weapon | Type | Range | Attacks | To Hit | To Wound | Rend | Damage | Ref |
|---|---|---|---|---|---|---|---|---|
| Piercing Claws | Melee | 1" | 2 | 4+ | 4+ | -1 | 1 | |
| Poisoned Tongue | Melee | 1" | 2 | 4+ | 4+ | - | 1 |
Categories: Allegiance
Selections: Godseekers Host
Battalion Organisation: Godseekers Hedonite Host, Battle Trait: Euphoric Killers, Feast of Depravities, Hosts of Slaanesh, Locus of Diversion, Maniacal Hunters, Thundering Cavalcade, Depravity Point Table: (01) 1 Keeper of Secrets, (02) 30 Daemonettes, (03) 3 Seeker Chariots, (04) 20 Daemonettes, (05) 1 Contorted Epitome, (06) 1 Bladebringer, Herald on Exalted Chariot, (07) 3 Feinds, (08) 1 Bladebringer, Herald on Hellflayer, (09) 1 Exalted Chariot, (10) 1 Infernal Enrapturess, Herald of Slaanesh, (11) 1 Bladebringer, Herald on Seeker Chariot, (12) 1 Hellflayer, (13) 1 Viceleader, Herald of Slaanesh, (14) 1 Seeker Chariot, (15) 5 Seekers, (16) 10 Daemonettes
| Battalion Organisation | Required | Ref |
|---|---|---|
| Godseekers Hedonite Host | A Hedonite Host in a GODSEEKERS HOST army must have0-2 Epicurean Revellers battalions and 2-4 Seeker Cavalcade battalions instead of 1-3. |
| Battle Trait | Battle Trait Details | Ref |
|---|---|---|
| Euphoric Killers | If the unmodified hit roll for an attack made with a melee weapon by a CHAOS SLAANESH model is 6, that attack inflicts 2 hits on the target instead of 1. Make a wound and save roll for each hit. If the attacking model’s unit has 20 or more models, its attacks inflict 3 hits on an unmodified hit roll of 6 instead. | |
| Feast of Depravities | You can summon units of SLAANESH DAEMONS to the battlefield if you collect enough depravity points (DPs). Each time a wound or mortal wound is inflicted on an enemy model by an attack made by a friendly SLAANESH HERO or a spell cast by a friendly SLAANESH HERO, and that enemy model is not slain by that wound or mortal wound, you receive 1 depravity point. In addition, every time a wound or mortal wound is allocated to a friendly SLAANESH HERO and not negated, and that friendly model is not slain by that wound or mortal wound, you receive 1 depravity point. If you have any depravity points at the end of your movement phase, you can summon one or more units from the list below to the battlefield, and add them to your army. Each unit you summon costs a number of depravity points, as shown on the list, and you can only summon a unit if you have enough depravity points to pay its cost. Summoned units must be set up wholly within 12" of a friendly SLAANESH HERO and more than 9" from any enemy units. Subtract the cost of the summoned unit from the number of depravity points you have immediately after it has been set up. |
|
| Hosts of Slaanesh | After you have chosen the Slaanesh allegiance for your army, you must also choose a Host of Slaanesh keyword for your army. You can choose for your army to be an INVADERS HOST, a PRETENDERS HOST, or a GODSEEKERS HOST. All units in your army gain the keyword of the host that you have chosen. All units with that keyword benefit from the host’s allegiance abilities, which are presented on the following pages, in addition to the allegiance abilities they have for being from a Slaanesh army. | |
| Locus of Diversion | At the end of the charge phase, each friendly HEDONITE HERO that is within 6" of an enemy unit can create a locus of diversion. If they do so, pick 1 enemy unit that is within 6" of that HEDONITE HERO and roll a dice, adding 2 if that HEDONITE HERO is a GREATER DAEMON. On a 5+, that enemy unit fights at the end of the following combat phase, after the players have picked any other units to fight in that combat phase. You cannot pick the same unit as the target for this ability more than once in the same charge phase (whether the roll is successful or not). If a unit that is affected by this battle trait is also affected by any rules that would allow it to fight at the start of the following combat phase, that unit is not affected by this rule or those other rules (the effects cancel each other out). |
|
| Maniacal Hunters | At the end of your charge phase, you receive D3 depravity points if any friendly GODSEEKERS HOST units made a charge move in that phase. If 3 or more friendly GODSEEKERS HOST units made a charge move in that phase, you receive D6 depravity points instead of D3. | |
| Thundering Cavalcade | Add 1 to charge rolls for units in a GODSEEKERS HOST army. |
| Depravity Point Table | Cost | Ref |
|---|---|---|
| (01) 1 Keeper of Secrets | 45 | |
| (02) 30 Daemonettes | 40 | |
| (03) 3 Seeker Chariots | 35 | |
| (04) 20 Daemonettes | 28 | |
| (05) 1 Contorted Epitome | 23 | |
| (06) 1 Bladebringer, Herald on Exalted Chariot | 23 | |
| (07) 3 Feinds | 23 | |
| (08) 1 Bladebringer, Herald on Hellflayer | 20 | |
| (09) 1 Exalted Chariot | 20 | |
| (10) 1 Infernal Enrapturess, Herald of Slaanesh | 17 | |
| (11) 1 Bladebringer, Herald on Seeker Chariot | 17 | |
| (12) 1 Hellflayer | 17 | |
| (13) 1 Viceleader, Herald of Slaanesh | 15 | |
| (14) 1 Seeker Chariot | 15 | |
| (15) 5 Seekers | 15 | |
| (16) 10 Daemonettes | 14 |
Selections: Allegiance: Chaos
Categories: Allegiance
Selections: 2000 Points - Battlehost
Categories: Game Options, Battlehost
Selections: Origin: Ghur
Categories: Realm of Origin
At the Double: You can use this command ability after you make a run roll for a friendly unit that is within 6" of a friendly HERO, or 12" of a friendly HERO that is a general.  (Core Rules p3)
Forward to Victory: You can use this command ability after you make a charge roll for a friendly unit that is within 6" of a friendly HERO, or 12" of a friendly HERO that is a general. If you do so, re-roll the charge roll. (Core Rules p3)
Inspiring Presence: You can use this command ability at the start of the battleshock phase. If you do so, pick a friendly unit that is within 6" of friendly HERO, or 12" of a friendly HERO that is a general. That unit does not have to take battleshock tests in that phase. (Core Rules p3)
Created with BattleScribe


pgAdmin 4¶
Welcome to pgAdmin 4. pgAdmin is the leading Open Source management tool for Postgres, the world’s most advanced Open Source database. pgAdmin 4 is designed to meet the needs of both novice and experienced Postgres users alike, providing a powerful graphical interface that simplifies the creation, maintenance and use of database objects.
- Getting Started
- Connecting To A Server
- Managing Cluster Objects
- Managing Database Objects
- Cast Dialog
- Collation Dialog
- Domain Dialog
- Domain Constraints Dialog
- Event Trigger Dialog
- Extension Dialog
- Foreign Data Wrapper Dialog
- Foreign Server Dialog
- Foreign Table Dialog
- FTS Configuration Dialog
- FTS Dictionary Dialog
- FTS Parser Dialog
- FTS Template Dialog
- Function Dialog
- Language Dialog
- Materialized View Dialog
- Package Dialog
- Procedure Dialog
- Schema Dialog
- Sequence Dialog
- Synonym Dialog
- Trigger Function Dialog
- Type Dialog
- User Mapping Dialog
- View Dialog
- Creating or Modifying a Table
- Management Basics
- Backup and Restore
- Developer Tools
- pgAgent
- pgAdmin Project Contributions
- Release Notes
- Version 4.29
- Version 4.28
- Version 4.27
- Version 4.26
- Version 4.25
- Version 4.24
- Version 4.23
- Version 4.22
- Version 4.21
- Version 4.20
- Version 4.19
- Version 4.18
- Version 4.17
- Version 4.16
- Version 4.15
- Version 4.14
- Version 4.13
- Version 4.12
- Version 4.11
- Version 4.10
- Version 4.9
- Version 4.8
- Version 4.7
- Version 4.6
- Version 4.5
- Version 4.4
- Version 4.3
- Version 4.2
- Version 4.1
- Version 4.0
- Version 3.6
- Version 3.5
- Version 3.4
- Version 3.3
- Version 3.2
- Version 3.1
- Version 3.0
- Version 2.1
- Version 2.0
- Version 1.6
- Version 1.5
- Version 1.4
- Version 1.3
- Version 1.2
- Version 1.1
- Version 1.0
- Licence


Hello, I'm Israt Jahan Sathi
Web Developer
Android Developer
My Story
I'm 24 years old creative web designer based in New York, specializing in User Interface Design and Development. I build clean, appealing, and functional interfaces which comply with the latest web standards. I’m happiest when I’m playing games, designing, or building something that didn’t exist before. I work primarily with logo design, custom & hand drawn lettering and expressive typography.
Age :
22 Years
Date of birth :
29-10-1998
Address :
Dhaka,Bangladesh
Email :
<EMAIL_ADDRESS>Phone :
01928*****
Freelance :
Available
Resume
My Skills
HTML
90%CSS3
82%jQuery
77%Languages
English
93%Spanish
86%Italian
72%Portfolio
- all
- logo
- coding
- Design
My Blog
March 19, 2018
100 Ways to be more happy
March 19, 2018
Tips to losing more weight
March 19, 2018
100 Ways to be more happy
March 19, 2018
Tips to losing more weight
March 19, 2018
100 Ways to be more happy
March 19, 2018
Tips to losing more weight
Contact
Get in Touch
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam


{%extends "nav_account.html"%} {%block title%}Proxy voting{%endblock%} {%block content%}
You are currently set up to allow {{key.proxyname}} to attend and vote on your behalf in {{meeting.name}}.
For them to retrieve the instructions for connecting, please ask them to visit the page at {{sitebase}}/membership/meetings/{{meeting.id}}/{{key.proxyaccesskey}}/ within 4 hours before the meeting.
{%else%}On this form you can assign a proxy voter. This person will be able to attend and vote on your behalf in {{meeting.name}}.
{%endif%}NOTE! Your submitted form contained errors and has not been saved!
{%endif%}


I would never trust
A person that always agrees with me
That always nods A
nd says I'm right
That I'm never wrong
And that I do no evil
That the future will be perfect
That the world is harmless
But they know Evil always exists
Not just in the world
But also in them
And as a matter of fact
These are the worst
They do not care
Anything but themselves
They are
The most dangerous with their
Wings of butterfly
Heads of crocodile.

And the one I trust the most
I may call it the God
It puts me everywhere
It make me feel what I don't want
It make me understand what I didn't know
But in tears and suffering
God gives me a future
God shows me the path
And although it's hard
Either on this life or another
There is always light


There are many ways to represent the same numeric value. Long ago, humans used
sticks to count, and later learned how to draw pictures of sticks in the ground
and eventually on paper. So, the number 5 was first represented as:
| |
| | | (for five sticks).
Later on, the Romans began using different symbols for multiple numbers
of sticks:| |
| still meant three sticks,
but a V
now meant five sticks,
and an X was used to represent ten of them.
Using sticks to count was a great idea for its time. And using
symbols instead of real sticks was much better.
Decimal System
Most people today use decimal representation to count.
In the decimal system there are 10 digits:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
These digits can represent any value, for example: 754.
The value is formed by the sum of each digit, multiplied by
the base (in this case it is 10 because there are
10 digits in decimal system) in power of digit position (counting from zero):
Position of each digit is very important!
for example if you place "7" to the end: 547
it will be another value:
Important note: any number in power of zero is 1, even
zero in power of zero is 1:
Binary System
Computers are not as smart as humans are (or not yet),
it's easy to make an electronic machine with two states: on and off,
or 1 and 0.
Computers use binary system, binary system uses 2 digits:
0, 1
And thus the base is 2.
Each digit in a binary number is called a BIT, 4 bits form a NIBBLE,
8 bits form a BYTE, two bytes form a WORD, two words form
a DOUBLE WORD (rarely used):
There is a convention to add "b" in the end of a binary number, this way we
can determine that 101b is a binary number with decimal value of 5.
The binary number 10100101b equals to decimal value of 165:
Hexadecimal System
Hexadecimal System uses 16 digits:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
And thus the base is 16.
Hexadecimal numbers are compact and easy to read.
It is very easy to convert numbers from binary system to hexadecimal system and vice-versa,
every nibble (4 bits) can be converted to a hexadecimal digit using this table:
Decimal (base 10)
Binary (base 2)
Hexadecimal (base 16)
0
0000
0
1
0001
1
2
0010
2
3
0011
3
4
0100
4
5
0101
5
6
0110
6
7
0111
7
8
1000
8
9
1001
9
10
1010
A
11
1011
B
12
1100
C
13
1101
D
14
1110
E
15
1111
F
There is a convention to add "h" in the end of a hexadecimal number, this way we
can determine that 5Fh is a hexadecimal number with decimal value of 95.
We also add "0" (zero) in the beginning of hexadecimal numbers that begin with a letter (A..F),
for example 0E120h.
The hexadecimal number 1234h is equal to decimal value of 4660:
Converting from Decimal System to Any Other
In order to convert from decimal system, to any other system, it is required
to divide the decimal value by the base of the desired system, each time
you should remember the result and keep the remainder, the
divide process continues until the result is zero.
The remainders are then used to represent a value in that system.
Let's convert the value of 39 (base 10) to
Hexadecimal System (base 16):
As you see we got this hexadecimal number: 27h.
All remainders were below 10 in the above example, so
we do not use any letters.
Here is another more complex example:
let's convert decimal number 43868 to hexadecimal form:
The result is 0AB5Ch, we are using the above table
to convert remainders over 9 to corresponding letters.
Using the same principle we can convert to binary form (using 2 as the divider),
or convert to hexadecimal number, and then convert it to binary number using
the above table:
As you see we got this binary number:<PHONE_NUMBER>011100b
Signed Numbers
There is no way to say for sure whether the hexadecimal byte 0FFh is
positive or negative, it can represent both decimal value "255" and "- 1".
8 bits can be used to create 256 combinations (including zero), so we simply
presume that first 128 combinations (0..127) will represent positive numbers
and next 128 combinations (128..256) will represent negative numbers.
In order to get "- 5", we should subtract 5 from the number of
combinations (256), so it we'll get: 256 - 5 = 251.
Using this complex way to represent negative numbers has some meaning, in math
when you add "- 5" to "5" you should get zero.
This is what happens when processor adds two bytes 5 and 251,
the result gets over 255, because of the overflow processor gets zero!
When combinations 128..256 are used the high bit is always 1, so
this maybe used to determine the sign of a number.
The same principle is used for words (16 bit values),
16 bits create 65536 combinations, first 32768 combinations (0..32767)
are used to represent positive numbers, and next 32768 combinations (32767..65535)
represent negative numbers.
There are some handy tools in emu8086 to convert numbers, and make
calculations of any numerical expressions, all you need is a
click on Math menu:
Base converter allows you to convert numbers from any system and
to any system. Just type a value in any text-box, and the value
will be automatically converted to all other systems. You can work both
with 8 bit and 16 bit values.
Multi base calculator can be used to make calculations between
numbers in different systems and convert numbers from one system to another.
Type an expression and press enter, result will appear in chosen numbering system.
You can work with values up to 32 bits. When Signed is checked
evaluator assumes that all values (except decimal and double words) should be treated as
signed. Double words are always treated as signed values, so
0FFFFFFFFh is converted to -1.
For example you want to calculate:
0FFFFh * 10h + 0FFFFh
(maximum memory location that can be accessed by 8086 CPU).
If you check Signed and Word you will get
-17 (because it is evaluated as
(-1) * 16 + (-1) . To make
calculation with unsigned values uncheck Signed
so that the evaluation will be 65535 * 16 + 65535
and you should get 1114095.
You can also use the base converter to convert
non-decimal digits to signed decimal values, and
do the calculation with decimal values (if it's easier for you).


{% extends "base-nosidebar.html" %}
{% block content %}
Blogger The Catami Blog
Catami has a blog! At the Catami blog you can read articles on project specifics and keep up to date with important milestones
Google+ Catami on plus.google.com
Catami is on Google+. We're using Google+ for day to day team communications and short notes on interesting topics.
Jira https://catami.atlassian.net
We're using Jira for our project management. You can see our current task set here, and track progress as we work
Github https://catami.github.com
Catami is open source! All Catami source code and the Catami Wiki can be found here
Email<EMAIL_ADDRESS>emails to<EMAIL_ADDRESS>get sent to the entire development team.


This application demonstrates how to develop an application that combines document centric application development techniques, JSON based data persistence, REST Services with an Oracle Database. The application is a simulation of a system for searching movies and theaters and then purchasing tickets to see a given showing of a movie. It is a single-page web application, built using a decoupled AngularJS front-end that communicates with a set of REST services provided by an application tier developed in Node.js. The application tier uses REST to invoke micro-services provided by Oracle's SODA for REST, a component of Oracle Rest Data Services (ORDS). Soda for rest provides data persistence services for JSON and other kinds of document. The application provides the following capabilities:
The architecture for this version of the application is as follows:
The front end application uses HTML5 and Angular to communicate with an application-tier developed using JavaScript and Node.js. The application tier makes use of a number of standard node modules, including express and http. The Application tier uses SODA for REST and Oracle REST Data Services (ORDS) to communicate with the back-end data store. The back-end data store is an Oracle 12c Database.
The data model for the application is shown in the following diagram:
The front end application consists of a single page HTML file named index.html. This file is served up by the Node.js server. The front end application logic, including the AngularJS modules, controllers and factories that invoke the REST services provided by Node.js server are contained in the file movieticketing.js file. The user interface uses the Twitter Bootstrap framework to provide a simple, clean and modern user interface.
The JavaScript code that makes up the application tier is organized into 3 layers.
All interaction between the application and the JSON document store managed by the Oracle Database goes through module soda_rest_api.js. This module soda_rest_api.js the NPM package request-promise-native to perform the HTTP requests required to invoke SODA for REST. The request package uses an options object to specify the details of the HTTP operation to be performed. All of the functions in soda_rest_api.js module follow a similar design pattern, they construct the appropriate options object for the operation in question and tpass the options object to a common function, send Request() which uses the request package to make the HTTP request. Function sendRequest() uses the JavaScript await operator, implemented as part of Node 8, to invoke the promise used to manages the HTTP operation. The await operator makes it easy to implement asynchronous HTTP opertions , ensuring optimal recourse usage on the Node.js server. Function sendRequest() is shown below:
async function sendRequest(options) {
try {
const response = await request(options).auth(getUsername(), gePassword(), true);
} catch (e) {
throw processError(moduleId,logContainer.logRequest,e);
}
}
In addition to the modules listed above the application includes the following additional modules:
There are 3 configuration files that are used by the application:
The MovieTicketing application exposes the following Rest services which are consumed by the browser-based front end.
Some of these services are nothing more that very thin veneers over the underlying collections. Other provide quite extensive processing, requiring multiple interactions between the Application Tier and the Document Management layer.
When the application is launched the user is presented with 3 tabs, "List Theaters", "List Movies" and "Load Test Data."
The following sections will examine the code behind some of these services and also look at how they are consumed in by the Browser-based component. Note that the code samples shown below are simplifciations of the actual application code.
The List Theaters tab is based on the output generated by the rest service associated with a GET operation on the end point /movieticket/theaters. The AngularJS controller used to invoke this service is shown below
app.controller('theatersCtrl',function($scope, $http, $cookies, theaterService) {
$cookies.put('movieTicketGUID', GUID)
$scope.theaterService = theaterService;
$http({
method: 'GET',
url: '/movieticket/theaters/',
}).success(function(data, status, headers) {
$scope.theaterService.theaters = data;
var path = '/movieticket/movieticketlog/operationId/'+ headers('X-SODA-LOG-TOKEN')
$http.get(path).success(function(data, status, headers) {
$scope.theaterService.logRecord = data
// console.log(JSON.stringify($scope.theaterService.logRecord));
});
});
});
A snippet of HTML and AngularJS code that is used to render the output of the service as HTML is shown below:
When a GET operation is performed on the URL /movieticket/theaters the Node.js application invokes the function theatersService provided by the module movie_ticketing.api. This function is declared as 'async', allowing it to use the 'await' operator to perform asynchronous execution of the promise returned by function 'getTheaters()' defined in the module 'movie_ticket_api.js'. The code for this module is shown below:
movie_ticketing.js
async function theatersService(sessionState, response, next) {
try {
const httpResponse = await movieAPI.getTheater(sessionState, key)
writeResponse(response,httpResponse.json,sessionState.operationId);
} catch (e) {
next(e);
}
}
This function uses the SODA for REST "Get Collection" micro-service to return the required list of Theater documents. It invokes function getTheaters() in module movie_ticket_api.js. The resulting JSON is retuned to the client as the response. Function theatersService() also adds an X-SODA-LOG-TOKEN header to the response that provides the client application with a unique identifier that can be used to retrieve the log records associated with the operation.
Function getTheaters() is a veneer over function getCollection() exported by module docStore_api.js which in turn calls function getCollection() exported by module soda_rest_api.js. The SODA for REST calls required to list the contents of the collection are implemented by function getCollection() in the module soda_rest_api.js. Function getCollection() relies on function processQuery() to execute the HTTP request and manage the automatic pagination of the results, since SODA for REST operations are limited to returning a maximum of 1000 documents per HTTP request. The code for these functions is shown below:
movie_ticket_api.js
function getTheaters(limit,fields) {
return docStoreAPI.getCollection('Theater',limit,fields)
}
docStore_api.js
async function getCollection(collectionName, limit, fields, includeTotal) {
return dbAPI.getCollection(collectionName, limit, fields, includeTotal)
}
soda_rest_api.js
async function processQuery(options, limit) {
const results = await sendRequest(options);
if ((limit !== 'unlimited') && (limit === 0)) {
results.body.items = []
results.body.count = 0
}
else {
if ((limit === 'unlimited') || (results.body.count < limit)) {
while (results.body.hasMore) {
if (limit !== 'unlimited') {
options.qs.limit = limit - results.body.count
}
options.qs.offset = results.body.count
const moreResults = await sendRequest(moduleId, sessionState, options, logContainer);
results.body.items = results.body.items.concat(moreResults.body.items);
results.body.count = results.body.items.length
results.body.hasMore = moreResults.body.hasMore
if (results.body.count === limit) {
break;
}
}
}
}
}
async function getCollection(collectionName, limit, fields, includeTotal) {
const options = { method : 'GET'
, baseUrl : documentStoreURL
, uri : getCollectionLink(collectionName)
, qs : getLimitAndFields({}, sodaLimit, fields, includeTotal)
, headers : setHeaders()
, time : true
, json : true
};
return processQuery(options,limit)
}
A "Get Collection" operation is executed by performing a GET operation on the URL associated with the collection
The "List Movies by Theater" tab is opened when the user clicks on the "Movies" button associated with one of the theaters on the "List Theaters" tab. It lists the show times for the movies playing at the selected theater on the specified date. The content of this tab is based on the output generated by the rest service associated with a GET operation on the end point /theaters/:id/movies/:date, where :id is the id of the theater and :date is the required date. When a GET operation is performed on the URL the Node.js application invokes the function moviesByTheaterService() exported by the module movie_ticketing.api passing the values for id and date. The code for this module is shown below:
movie_ticketing.js
async function moviesByTheaterService(sessionState, response, next, id, dateStr) {
try {
const httpResponse = await movieAPI.getTheater(sessionState, id)
const theater = httpResponse.json;
delete(theater.screens);
const moviesByTheater = await getMoviesByTheaterAndDate(sessionState,theater,dateStr)
writeResponse(response,moviesByTheater,sessionState.operationId);
} catch (e){
next(e);
};
}
This function invokes function getTheater() exported by the module movie_ticket_api.js to get the information for the specified theater using its internal key. It then calls function getMoviesByTheaterAndDate() to construct a JSON document that summarizes the movies and show times for the specified theater and date. The resulting JSON forms the response to the request. The code for function getMoviesByTheaterAndDate() is shown below:
movie_ticket_api.js
async function getMoviesByTheaterAndDate(sessionState,theater, date) {
var moviesByTheater = {
'theater' : theater,
'movies' : []
};
var startDate = new Date(Date.parse(date))
startDate.setHours(0);
startDate.setMinutes(0);
startDate.setSeconds(0);
startDate.setMilliseconds(0);
var endDate = new Date(Date.parse(date));
endDate.setHours(0)
endDate.setMinutes(0)
endDate.setSeconds(0)
endDate.setMilliseconds(0);
endDate.setDate(endDate.getDate() + 1);
var qbe = { theaterId : theater.id, startTime : { "$gte" : startDate, "$lt" : endDate }, "$orderby" : { screenId : 1, startTime : 1}};
const httpResponse = await movieAPI.queryScreenings(sessionState, qbe, 'unlimited')
let movies = await processScreeningsByTheaterAndDate(sessionState,httpResponse)
moviesByTheater.movies = movies;
return moviesByTheater;
}
This function uses the SODA for REST "Query By Example (QBE)" micro-service to to search for the required screening documents. First it constructs a QBE document that specifies the required theater and date range. Then it invokes function queryScreenings() in module movie_ticket_api.js to execute the QBE and fetch the required screening documents from the document store. These documents are then passed to function processScreeningsByTheaterAndDate() in order to generate the required summary. Function processScreeningsByTheaterAndDate() uses a second QBE to fetch the details of each movie being shown. The resulting JSON is retuned to the client as the response.
Function queryScreenings() is a veneer over function queryByExample() exported by module docStore_api.js which in turn calls function queryByExample() exported by module soda_rest_api.js. The SODA for REST calls required to perform the search of the collection are implemented by function queryByExample() in the module soda_rest_api.js. Function queryByExample() also relies on function processQuery() to execute the HTTP request and manage the automatic pagination of the results. The code for these functions is shown below:
movie_ticket_api.js
function queryScreenings(sessionState, qbe, limit, fields, includeTotal) {
return docStoreAPI.queryByExample(sessionState, 'Screening', qbe, limit, fields, includeTotal);
}
docStore_api.js
async function queryByExample(sessionState, collectionName, qbe, limit, fields, includeTotal) {
return dbAPI.queryByExample(sessionState, collectionName, qbe, limit, fields, includeTotal)
}
soda_rest_api.js
async function queryByExample(sessionState, collectionName, qbe, limit, fields, includeTotal) {
const options = { method : 'POST'
, baseUrl : documentStoreURL
, uri : getCollectionLink(collectionName)
, qs : getLimitAndFields({action : "query"}, limit, fields, includeTotal)
, json : qbe
, time : true
};
return processQuery(sessionState,options,limit)
}
A "Query By Example" operation is executed by performing a POST operation on the URL associted with collection, specifying the query string 'action=query'. The QBE specification is supplied as the body of the POST.
Both the List Movies By Theater and List Theaters by Movie tab allow the user to purchase tickets to see a movie by clicking on the showing they would like to attend. Once they have entered the number of tickets they require they can complete the purchase by clicking on the '$' icon. The purchase is made by performing a POST operation on the URL /movieticket/bookTickets. When a POST operation is performed on this URL the Node.js application invokes the function bookTicketService() provided by the module movie_ticketing.api. The information about the number of tickets required is provided as the body of the POST operation. The code for this module is shown below:
Function bookTicketService() invokes function bookTickets() exported by the module movie_ticketing.api to record the ticket sale. This functions returns a simple JSON document that indicates whether or not the booking was successful. This document is returned to the front end.
Function bookTickets() uses the SODA for REST "Update Document" and "Insert Document" micro-services to record the transaction. First it invokes function updateScreening() exported by module movie_ticket_api.js to update the screening document with a new version of the document containing the new value for the number of seats remaining for the screening. Then it invokes function insertTicketSale() expotred by module movie_ticket_api.js to store the document that records the ticket sale.
SODA for REST uses an optimistic locking strategy to prevent conflicting updates from taking place. This follows REST conventions and is based on the value of the documents ETag. Any time an application might need to update a document it must fetch the document metadata as well as document content in order to get the current value of the ETag. Conflicting updates are prevented by adding an "If Match" header to the HTTP request. The value of this header is the ETag that was obtained last time the document was read. If there has been a conflicting update the current ETag for the document will not match the ETag supplied by the application and the PUT operation will return HTTP Status code of 412 [Precondition Failed] indicating that the PUT operation was not successful. If there are no conflicting updates then the PUT operation will return HTTP Status code 200 [Successful].
The application logic for completing the booking is as follows:
The code for these functions is shown below:
movie_ticket_api.js
async function bookTicketService(sessionState, response, next, bookingRequest) {
try {
let bookingStatus = await bookTickets(sessionState, bookingRequest)
writeResponse(response,bookingStatus,sessionState.operationId);
} catch (err) {
next(err);
};
}
async function bookTickets(sessionState, bookingRequest) {
var key = bookingRequest.key;
var etag = null;
var screening = {}
var seatsRequired = bookingRequest.adult + bookingRequest.senior + bookingRequest.child;
try {
let httpResponse = await movieAPI.getScreening(sessionState, key)
etag = httpResponse.etag;
screening = httpResponse.json;
if (screening.seatsRemaining < seatsRequired) {
return {
status : "SoldOut",
message : `Only ${screening.seatsRemaining} seats are available for this performance.`
};
}
else {
screening.seatsRemaining = screening.seatsRemaining - seatsRequired;
try {
httpResponse = await movieAPI.updateScreening(sessionState, key, screening, etag)
switch (httpResponse.status) {
case constants.SUCCESS: // Seat Reserved : Record Ticket Sale
var ticketSale = makeTicketSale(bookingRequest, screening);
try {
httpResponse = await movieAPI.insertTicketSale(sessionState, ticketSale)
switch (httpResponse.status) {
case constants.CREATED: // Booking Completed
return {
status : "Booked",
message : "Please enjoy your movie."
 Function putDocument() in-turn calls function putDocument() exported by module soda_rest_api.js. The SODA for REST calls required to update the document are implemented by function putDocument() in the module soda_rest_api.js. The code for these functions is shown below:
movie_ticket_api.js
function updateScreening(sessionState, key,screening,etag) {
return docStoreAPI.putJSON(sessionState, 'Screening',key,screening,etag);
}
docStore_api.js
function putJSON(sessionState, collectionName, key, json, etag) {
return putDocument(sessionState, collectionName, key, json, 'application/json', etag);
}
async function putDocument(sessionState, collectionName, key, document, contentType, etag) {
return dbAPI.putDocument(sessionState, collectionName, key, document, contentType, etag)
}
soda_rest_api.js
async function putDocument(sessionState, collectionName, key, document, contentType, etag) {
const options = { method : 'PUT'
, baseUrl : documentStoreURL
, uri : getDocumentLink(collectionName,key)
, headers : setHeaders(contentType , etag)
, time : true
};
if (contentType === 'application/json') {
options.json = document
}
else {
options.body = document
}
const results = await sendRequest(options);
return results
}
An "Update Document" operation is executed by performing a PUT on a particular document within the target collection. The document is identified using the ID that was assigned or provided when the document was inserted. The updated content is supplied as the body of the PUT. When using package request-promise-native, a JSON payload is passed using the key 'json', a non-JSON payload is passed using the key 'body'.
Function insertTicketSale() is a veneer over function postJSON() exported by module docStore_api.js. Function postJSON() calls function postDocument(), specifying that the content-type for the document is "application/json". Function postDocument() in-turn calls function postDocument() exported by module soda_rest_api.js. The SODA for REST calls required to insert the document are implemented by function postDocument() in the module soda_rest_api.js. The code for these functions is shown below:
movie_ticket_api.js
function insertTicketSale(sessionState, ticketSale) {
return docStoreAPI.ensurePostJSON(sessionState, 'TicketSale', ticketSale);
}
docStore_api.js
function postJSON(sessionState, collectionName, json) {
return postDocument(sessionState, collectionName, json, 'application/json');
}
async function postDocument(sessionState, collectionName, document, contentType) {
return dbAPI.postDocument(sessionState, collectionName, document, contentType)
}
soda_rest_api.js
async function postDocument(sessionState, collectionName, document, contentType) {
const options = { method : 'POST'
, baseUrl : documentStoreURL
, uri : getCollectionLink(collectionName)
, headers : setHeaders(contentType , undefined)
, time : true
};
if (contentType === 'application/json') {
options.json = document
}
else {
options.body = document
}
const results = await sendRequest(moduleId, sessionState, options, logContainer);
}
An "Insert Document" operation is executed by performing a POST on the target collection. The content of the new document is supplied as the body of the POST. When using package request-promise-native, a JSON payload is passed using the key 'json', a non-JSON payload is passed using the key 'body'.
These instructions assume you already have access to an Oracle Database <IP_ADDRESS>.0 instance with Bundle Patch 13 installed. If you do not have this available you can start by downloading the latest version of the Oracle Developer Days VM from the Oracle Technology Network. Although this VM comes with a version of Oracle Rest Data Services installed, you will need to update it from 3.0.4 to 3.0.5 by following step 1 of the instructions below
The MovieTicketing demonstration works with sample data downloaded from publically available websites. The THEATER collection is populated with data obtained from an RSS feed published by Fandango.com. Optionally, this data can be enriched with location information obtained from a geocoding service, such as the one provided by Google. The Movie and Poster collections are populated using data obtained from the website themoviedatabase.org (TMDb). In order to obtain data from TMDb and Google you must register with those sites and obtain an API key.
The following commands will work on Enterprise Linux, assuming your are running as root, for other environments please refer to the platform specific platform specific installation instructions at https://docs.npmjs.com/getting-started/installing-node.
[root@localhost oracle]# curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
## Installing the NodeSource Node.js 8.x repo...
## Inspecting system...
+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release || rpm -q --whatprovides sl-release
+ uname -m
## Confirming "el7-x86_64" is supported...
+ curl -sLf -o /dev/null 'https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Downloading release setup RPM...
+ mktemp
+ curl -sL -o '/tmp/tmp.XATaz89OU3' 'https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Installing release setup RPM...
+ rpm -i --nosignature --force '/tmp/tmp.XATaz89OU3'
## Cleaning up...
+ rm -f '/tmp/tmp.XATaz89OU3'
## Checking for existing installations...
+ rpm -qa 'node|npm' | grep -v nodesource
## Run `yum install -y nodejs` (as root) to install Node.js 8.x and npm.
## You may also need development tools to build native addons:
## `yum install -y gcc-c++ make`
[root@localhost oracle]# yum install -y nodejs
Loaded plugins: langpacks, ulninfo
nodesource | 2.5 kB 00:00
nodesource/x86_64/primary_db | 30 kB 00:00
Resolving Dependencies
--> Running transaction check
---> Package nodejs.x86_64 2:8.9.4-1nodesource will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=======================================================================================================================================
Package Arch Version Repository Size
=======================================================================================================================================
Installing:
nodejs x86_64 2:8.9.4-1nodesource nodesource 17 M
Transaction Summary
=======================================================================================================================================
Install 1 Package
Total download size: 17 M
Installed size: 51 M
Downloading packages:
warning: /var/cache/yum/x86_64/7Server/nodesource/packages/nodejs-8.9.4-1nodesource.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 34fa74dd: NOKEY
Public key for nodejs-8.9.4-1nodesource.x86_64.rpm is not installed
nodejs-8.9.4-1nodesource.x86_64.rpm | 17 MB 00:00:01
Retrieving key from file:///etc/pki/rpm-gpg/NODESOURCE-GPG-SIGNING-KEY-EL
Importing GPG key 0x34FA74DD:
Userid : "NodeSource "
Fingerprint: 2e55 207a 95d9 944b 0cc9 3261 5ddb e8d4 34fa 74dd
Package : nodesource-release-el7-1.noarch (installed)
From : /etc/pki/rpm-gpg/NODESOURCE-GPG-SIGNING-KEY-EL
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Warning: RPMDB altered outside of yum.
Installing : 2:nodejs-8.9.4-1nodesource.x86_64 1/1
Verifying : 2:nodejs-8.9.4-1nodesource.x86_64 1/1
Installed:
nodejs.x86_64 2:8.9.4-1nodesource
Complete!
[root@localhost oracle]#
$ mkdir NodeExample
$ cd NodeExample
$ npm install oracle-movie-ticket-demo
This should result in output similar to this (note your version numbers may be later that the ones shown below):
[oracle@localhost ~]$ mkdir NodeExample
[oracle@localhost ~]$ cd NodeExample/
[oracle@localhost NodeExample]$ npm install oracle-movie-ticket-demo
npm WARN saveError ENOENT: no such file or directory, open '/home/oracle/NodeExample/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/oracle/NodeExample/package.json'
npm WARN NodeExample No description
npm WARN NodeExample No repository field.
npm WARN NodeExample No README data
npm WARN NodeExample No license field.
+<EMAIL_ADDRESS>added 134 packages in 4.845s
[oracle@localhost NodeExample]$
At this point the Node.js server has been installed and the application has been downloaded and is ready to run
The following commands will work on Enterprise Linux, assuming the node installation zip file is in the users Downloads folder, for other environments please refer to the platform specific installation instructions at https://docs.oracle.com/cd/E37099_01/doc.20/e25066/toc.htm.
$ cd
$ mkdir ORDS
$ cd ORDS
$ unzip ../Downloads/ords.<IP_ADDRESS>.10.54.zip
Make sure that the database and listener are started and you know a TNS Alias that can connect to the database where ORDS will be installed. Then start the ORDS configuration process as shown below
$ java -jar ords.war
This Oracle REST Data Services instance has not yet been configured.
Please complete the following prompts
Enter the location to store configuration data:/home/oracle/ORDS/config
Enter the name of the database server [localhost]:
Enter the database listen port [1521]:
Enter 1 to specify the database service name, or 2 to specify the database SID [1]:1
Enter the database service name:ORCL
Enter the database password for ORDS_PUBLIC_USER:
Confirm password:
Please login with SYSDBA privileges to verify Oracle REST Data Services schema.
Enter the username with SYSDBA privileges to verify the installation [SYS]:sys
Enter the database password for sys:
Confirm password:
Oracle REST Data Services will be installed in ORCL
Enter 1 if you want to use PL/SQL Gateway or 2 to skip this step.
If using Oracle Application Express or migrating from mod_plsql then you must enter 1 [1]:2
At this point ORDS will be installed into the target database. The output will be as follows:
Jun 17, 2016 6:18:24 PM oracle.dbtools.common.config.file.ConfigurationFilesBase update
INFO: Updated configurations: defaults, apex_pu
Installing Oracle REST Data Services version <IP_ADDRESS>.10.54
... Log file written to /home/oracle/ORDS/logs/ords_install_core_2016-06-17_181824_00306.log
... Verified database prerequisites
... Created Oracle REST Data Services schema
... Created Oracle REST Data Services proxy user
... Granted privileges to Oracle REST Data Services
... Created Oracle REST Data Services database objects
Completed installation for Oracle REST Data Services version <IP_ADDRESS>.10.54. Elapsed time: 00:00:14.299
Enter 1 if you wish to start in standalone mode or 2 to exit [1]:2
ORDS is now installed
java -jar ords.war user MovieTicketing "SODA Developer"
Enter a password for user MovieTicketing:
Confirm password for user MovieTicketing:
Jun 17, 2016 6:29:33 PM oracle.dbtools.standalone.ModifyUser execute
INFO: Created user: MovieTicketing in file: /home/oracle/ORDS/config/ords/credentials
Edit the file defaults.xml. Assuming you specified /home/oracle/ORDS/config when responding to the prompt "Enter the location to store configuration data:" in step 2.1 the file is located in the folder config/ords. Locate the entry with the key "jdbc.MaxLimit" and change the value to 500. Locate the entry with the key "jdbc.InitialLimit" and change the value to 50. Save the file
The first time you start the ORDS server you are asked whether you want to use HTTP or HTTPS and to select the port the server is to listen on. This information is only required the first time ORDS is started.
[oracle@localhost ORDS]$ java -jar ords.war standalone
Enter 1 if using HTTP or 2 if using HTTPS [1]:1
Enter the HTTP port [8080]:
2016-06-17 18:22:54.846:INFO::main: Logging initialized @5506ms
Jun 17, 2016 6:22:55 PM oracle.dbtools.standalone.StandaloneJetty setupDocRoot
INFO: Disabling document root because the specified folder does not exist: /home/oracle/ORDS/config/ords/standalone/doc_root
2016-06-17 18:22:55.994:INFO:oejs.Server:main: jetty-9.2.z-SNAPSHOT
Jun 17, 2016 6:22:56 PM oracle.dbtools.auth.crypto.CryptoKeysGenerator startup
INFO: No encryption key found in configuration, generating key
Jun 17, 2016 6:22:56 PM oracle.dbtools.auth.crypto.CryptoKeysGenerator startup
INFO: No mac key found in configuration, generating key
Jun 17, 2016 6:22:56 PM oracle.dbtools.common.config.file.ConfigurationFilesBase update
INFO: Updated configurations: defaults
Jun 17, 2016 6:22:56 PM oracle.dbtools.auth.crypto.CryptoKeysGenerator startup
INFO: Updated configuration with generated keys
2016-06-17 18:22:56.539:INFO:/ords:main: INFO: Using configuration folder: /home/oracle/ORDS/config/ords
2016-06-17 18:22:56.539:INFO:/ords:main: FINEST: |ApplicationContext [configurationFolder=/home/oracle/ORDS/config/ords, services=Application Scope]|
Jun 17, 2016 6:22:56 PM oracle.dbtools.common.config.db.DatabasePools validatePool
INFO: Validating pool: |apex|pu|
Jun 17, 2016 6:22:57 PM oracle.dbtools.common.config.db.DatabasePools validatePool
INFO: Pool: |apex|pu| is correctly configured
config.dir
2016-06-17 18:22:57.381:INFO:/ords:main: INFO: Oracle REST Data Services initialized|Oracle REST Data Services version : <IP_ADDRESS>.10.54|Oracle REST Data Services server info: jetty/9.2.z-SNAPSHOT|
2016-06-17 18:22:57.384:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@2d209079{/ords,null,AVAILABLE}
2016-06-17 18:22:57.410:INFO:oejs.ServerConnector:main: Started ServerConnector@2c8d66b2{HTTP/1.1}{<IP_ADDRESS>:8080}
2016-06-17 18:22:57.414:INFO:oejs.Server:main: Started @8085ms
^C2016-06-17 18:28:39.476:INFO:oejs.ServerConnector:Thread-1: Stopped ServerConnector@2c8d66b2{HTTP/1.1}{<IP_ADDRESS>:8080}
2016-06-17 18:28:39.482:INFO:oejsh.ContextHandler:Thread-1: Stopped o.e.j.s.ServletContextHandler@2d209079{/ords,null,UNAVAILABLE}
At this point the ORDS server is running and ready to service SODA for REST operations
$ sqlplus system@ORCL
SQL*Plus: Release <IP_ADDRESS>.0 Production on Fri Jun 17 19:01:37 2016
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Enter password:
Last Successful login time: Fri Jun 17 2016 18:14:03 -07:00
Connected to:
Oracle Database 12c Enterprise Edition Release <IP_ADDRESS>.0 - 64bit Production
SQL> grant connect, resource, unlimited tablespace, SODA_APP to MOVIES identified by MOVIES;
Grant succeeded.
SQL> connect MOVIES/MOVIES@ORCL
Connected.
SQL> begin
2 ORDS.enable_schema();
3 commit;
4 end;
5 /
PL/SQL procedure successfully completed.
SQL> quit
Disconnected from Oracle Database 12c Enterprise Edition Release <IP_ADDRESS>.0 - 64bit Production
The SODA_APP role is required to use Oracle Document Collections. The call to ORDS.enable_schema() is required to allow the schema to be accessed via ORDS. Both steps are required to use SODA for REST.
The config.json file supplies the Node.js server with the information required to connect to the ORDS server. This file must be updated with the username and password and path to endpoint for the Movie Ticketing document store. Click the right arrow below to see a sample config.json document:
The file is located in the folder NodeExample/node_modules/oracle-movie-ticket-sample The keys in this file are self explanatory
If the application needs use a proxy server to connect to these sites information about the proxy server must be added to the dataSources.json file.
Click the right arrow below to see a sample dataSources.json document:
The file is located in the folder NodeExample/node_modules/oracle-movie-ticket-sample. The following keys may need to be edited before running the application.
The following commands will work on Enterprise Linux, assuming you followed the steps outlined above.
$ cd
$ cd NodeExample/oracle-movie-ticket-demo
$ node index.js
And the system should respond with something similar to this
2016-10-12T13:34:52.819Z: MovieTicket Webserver listening on localhost:3000
2016-10-12T13:34:53.235Z: $contains operator supported: true
2016-10-12T13:34:53.235Z: $near operatator supported: true
The first time you run the application you should see a page like this:
This page is used configure the application and obtain the data required to run the application.
Movie Information is loaded using services provided by the website themoviedb.org. Theater information is obtained using an RSS feed published by Fandango.com.
If the target document store supports Oracle Location services and the version of Query-By-Example included with SODA supports the $near operator you are given option of geocoding the Theater information. Currently, only the US Government Census Bureau's Geocoding service and Google's Geocoding service are supported. If Geocoding is enabled you are given the option viewing theater locality graphically using a Mapping service. Currently only Google's Mapping service is supported.
If you want to make use of Geocoding and Mapping please select the required services using the provided menus. In order to load Movie Information a valid key for the TMDb API must be provided using the box marked TMDb API Key. In order to use Google services a valid key for relevant Google APIs must be provided using the box marked Google API. If you have not yet obtained the necessary API keys you can use the 'Get Key' buttons associated with each box to open the appropriate website used to request the necessary keys. Once your selections are made and the required keys have been entered click 'SAVE' to update dataSources.json.
Successfully saving the configuration will enable the loading of Theaters and Movies.
Click the "Load" button associated with the Theaters collection to download theater information from Fandango. Click the "Load" button associated with the Movies collection to download movie information from TMDb. This operation may take a while to complete due to throughput restrictions imposed by the TMDb website. While the load operations are in progress the 'refresh' icon will rotate and the status box associated with target will display 'Working'. Once the load operations are completed the status box will be updated with the number of documents loaded.
Successfully completing the "Load Movies" operation will enable the loading of Posters. Successfully completing the "Load Movies" and "Load Theaters" operations will enabled the generation of screenings.
Click the "Load" button associated with the Posters collection to download movie posters from TMDb. This operation is also subject to the throughput restrictions imposed by the TMDb website. Click the "Load" button associated with the Screenings collection to generate 2 weeks' worth of screenings from the current set of theaters and movies. While the load and generate operations are is in progress the 'refresh' icon will rotate and the status box associated with target will display 'Working'. Once the load and gemerate operations are completed the status box will be updated with the number of documents loaded.
The data loading process only needs to be completed once, since once data loading is completed all of the information needed to run the application is stored as JSON documents in the Oracle document store. If any of the steps fail, simply click the associated button to try the step again. Note you must successfully complete "Load Movies" before attempting to run "Load Posters", and you must successfully complete "Load Theaters" and "Load Movies" before attempting to run "Generate Screenings". If you re-run either "Load Theaters" or "Load Movies" you must re-run "Generate Screenings before attempting to use the movie ticketing application. If you re-run "Load Movies" you must also re-run "Load Posters" to repopulate the Posters collection.
Once the Posters have been loaded and the Screenings generated the application will automatically reload itself and the "List Theaters" and "List Movies" tabs will be displayed. The applicaiton is now ready for use.


{% seo %}
Email: theshirleyzhang [at] gmail.com
GitHub | Linkedin |
CV | transcript
News [More Updates]
2023.06 I started my Digital Engineering internship at Arup Los Angeles!
Theme by orderedlist


Trapped protesters weigh options as Hong Kong aims for normality
About 100 people said to be holed up in Polytechnic University, as primary and secondary schools reopen after closure.
The last band of anti-government protesters trapped inside a besieged Hong Kong university were weighing a narrowing range of options early on Wednesday as city officials allowed primary and secondary schools to reopen in an attempt to restore some kind of normalcy to the city.
Reuters witnesses said fewer than 100 protesters remained on the Hong Kong Polytechnic University (PolyU) campus and police outside appeared ready to simply wait them out. More than 1,000 people have been arrested since late on Monday.
More:
-
China says will act on 'uncontrollable unrest'
-
Pictures: Hong Kong's night of mayhem
-
China plays the long game in Hong Kong protests
As the siege continued, children began returning to school after a six-day shutdown triggered by protesters' attempts to shut down the city by choking off rail and road links.
At PolyU, some protesters were nabbed in escape attempts that included trying to clamber down ropes onto waiting motorbikes.
Police officers stand guard outside Hong Kong Polytechnic University in Hong Kong where about 100 people remain holed up. [Thomas Peter/Reuters]
Others resurfaced inside the campus after unsuccessfully trying to find a way out through the sewers during the night. It was unclear if any had managed to escape that way.
New police chief
Police searched for potential escapees with spotlights rather than using the tear gas and rubber-coated bullets that had marked clashes in recent days, heeding calls from Hong Kong leader Carrie Lam for a humane end to a siege that saw the most intense violence since protests escalated more than five months ago.
They also tightened barricades in the streets surrounding the university, making them secure enough to be visited late on Tuesday night by the force's new commissioner, Chris Tang, at the end of his first day on the job.
Tang earlier urged the support of all citizens to end the unrest triggered by fears that China's central government is stifling the former British colony's freedoms and encroaching into the autonomy guaranteed on its return to Chinese rule in 1997.
Tang is under pressure to restore public confidence in a force that has come in for widespread criticism for its increasingly violent tactics to suppress the protests.
An independent inquiry into alleged police brutality has become a key demand for the protesters.
The police quietly rolled out a new, harder-edged motto on Tang's first day, replacing "We Serve with Pride and Care" with "Serving Hong Kong with Honour, Duty and Loyalty".


Documentation
jquery.dynatree.js
Examples
Default options
Init from JS object
Init from external data
URL navigation and <iframe>
Programming API
Checkbox & select
Theming
Persistence
Event handling
Effects
Drag'n'drop
Drag'n'drop
Drag'n'drop 2
Drag'n'drop 3
Context menu, Copy/paste
Context menu, Copy/paste (2)
Fixed expand level
Lazy loading
Embed in forms
Large nodes
Tweaks
Column layout
Edit nodes
RTL
Test
Benchmark large trees
Latest jQuery
Local server
DTD
No DTD
HTML4 transitional
HTML4 strict
HTML5
XHTML transitional
XHTML strict


Graffiti Artist TEACH Joins maharishi for 'Each One Teach One' Print
Available in a limited edition of 30.
by Gabrielle LeungLast year, maharishi partnered with legendary graffiti writer TEACH for a “Yeah of the Pig” capsule collection that launched alongside the British artist’s “They Taste Yeah Yeah” exhibition.
The hand-screen printed artwork features TEACH’s signature script in contrasting blue, red and white colors. The words, emboldened by a thick black outline and surrounded by paint-like drips, give the 420 x 594 mm print a sense of depth. maharishi explains the importance of its ongoing collaborations with the graffiti artist: “TEACH, who has been active since the ’90s and a member of London’s infamous DDS crew, the Kings of the London Underground, has influenced a whole generation of younger writers from his ethos on the culture to his hand style, throw-up’s, trains and consistency.”
Available in an edition of 30, TEACH’s ‘Each One Teach One’ print is available to purchase now for £75 (approx. $95 USD) on maharishi’s website and at its store location in London. Each print is signed and numbered by the artist.
For more art drops, Devin Troy Strother released his ‘Heavy Is The Head That Wears The Afro’ lithograph in collaboration with Print Them All.


1 package of energii mushrooms
1 tsp butter
1/2 tsp sake
1 scallion, chopped
1 tsp sake
Salt and sugar to taste
1 tsp tobiko (optional)
Lemon zest, to taste (optional)
GARNISH
Thinly sliced scallions (optional)
Wash the rice as per the basic rice recipe. With a vegetable peeler, peel any hard portions of skin towards the bottom of the asparagus stalks. Cut into ½ inch pieces and add to the rice. Add dashi or chicken stock, light soy sauce, sake, and salt. Continue to prepare as per the basic rice recipeh, whether using a rice cooker or donabe./p>
When the rice is finished, add the butter and stir gently with a rice paddle. The bottom will inevitably be brown and scorched because of the addition of the other ingredients. This is called okoge, and is delicious, as the flavor is concentrated and the texture, slightly chewy. You can either mix it in with the rest of the rice, or if you don’t like the look of it, separate the okoge portion to eat separately.
PNOTE: This is a recipe that stands up to the flavor of powdered dashi, and one whole packet should be used.
Serves 6


net config workstation
Allows modifications to the workstation service. Entered with no parameters give details of the current configuration
Options:
/charcount:<bytes> Number of bytes to be collected before data is sent. The default is 16, valid range is between 0 and 65535.
/chartime:<msec> Number of milliseconds NT waits before sending data. If charcount is also set whichever is satisfied first is used. Default is 250, valid range is between 0 and 65535000.
/charwait:<seconds> Number of seconds NT waits for a communications device to become available. Default is 3600, valid is between 0 and 65535.


Get a Chance to drive ONE!!!
Victory VEGAS 8-BALL
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Sterling ACTERRA 5500
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Indian CHIEF VINTAGE
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
American Ironhorse CLASSIC CHOP
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Sea-Doo RXP X 260
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Arctic Cat MOUNTAIN CAT
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Husqvarna TE450
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
International 3800
Features
- Make: Lorem
- Year: 199X
- Engine: Lorem Ipsum
- Country of Origin: X Y Z
- Capacity: X Persons
- Wheels Size: X
- Body Type: X Door Sedan
Coming Sooon


Basic Dynamic Page
Dynamic Page that snaps on scrolling
Other than the expand/collapse/pin buttons and Snap on Click feature, scrolling the content also snaps the header.
Scrolling down will hide the header, and scrolling back up to the top will bring back the header into view.
Tabbed Dynamic Page
Specify the [tabLabel]
option to internally set up tabbed content for the page.
The left and right paddings of the Dynamic Page can be adjusted according to the width of the container with the
[size]
property. Available values are: small
, medium
, large
and
extra-large


| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../../math/SafeMath.sol"; import "../../utils/Arrays.sol"; import "../../utils/Counters.sol"; import "./ERC20.sol"; /** * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and * total supply at the time are recorded for later access. * * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be * used to create an efficient ERC20 forking mechanism. * * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id * and the account address. * * ==== Gas Costs * * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much * smaller since identical balances in subsequent snapshots are stored as a single entry. * * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent * transfers will have normal cost until the next snapshot, and so on. */ abstract contract ERC20Snapshot is ERC20 { // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol using SafeMath for uint256; using Arrays for uint256[]; using Counters for Counters.Counter; // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a // Snapshot struct, but that would impede usage of functions that work on an array. struct Snapshots { uint256[] ids; uint256[] values; } mapping (address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. Counters.Counter private _currentSnapshotId; /** * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. */ event Snapshot(uint256 id); /** * @dev Creates a new snapshot and returns its snapshot id. * * Emits a {Snapshot} event that contains the same id. * * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a * set of accounts, for example using {AccessControl}, or it may be open to the public. * * [WARNING] * ==== * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, * you must consider that it can potentially be used by attackers in two ways. * * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs * section above. * * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. * ==== */ function _snapshot() internal virtual returns (uint256) { _currentSnapshotId.increment(); uint256 currentId = _currentSnapshotId.current(); emit Snapshot(currentId); return currentId; } /** * @dev Retrieves the balance of `account` at the time `snapshotId` was created. */ function balanceOfAt(address account, uint256 snapshotId) public view returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); return snapshotted ? value : balanceOf(account); } /** * @dev Retrieves the total supply at the time `snapshotId` was created. */ function totalSupplyAt(uint256 snapshotId) public view returns(uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); return snapshotted ? value : totalSupply(); } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } else if (to == address(0)) { // burn _updateAccountSnapshot(from); _updateTotalSupplySnapshot(); } else { // transfer _updateAccountSnapshot(from); _updateAccountSnapshot(to); } } function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { require(snapshotId > 0, "ERC20Snapshot: id is 0"); // solhint-disable-next-line max-line-length require(snapshotId <= _currentSnapshotId.current(), "ERC20Snapshot: nonexistent id"); // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(snapshotId); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply()); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 currentId = _currentSnapshotId.current(); if (_lastSnapshotId(snapshots.ids) < currentId) { snapshots.ids.push(currentId); snapshots.values.push(currentValue); } } function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { if (ids.length == 0) { return 0; } else { return ids[ids.length - 1]; } } } |


{% extends "base.html" %} {% import "macro/mera_options.html" as options %} {% block title %}CWR File Crossroads{% endblock %} {% block page_title %}CWR File Crossroads{% endblock %} {% block content %}
Choose what to do with the uploaded file.
{% endblock %}