text:
package com.google.gerrit.server.notedb;

import static com.google.gerrit.server.notedb.ReviewerState.CC;
import static com.google.gerrit.server.notedb.ReviewerState.REVIEWER;
import static com.google.gerrit.testutil.TestChanges.incrementPatchSet;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.server.git.VersionedMetaData.BatchMetaDataUpdate;
import com.google.gwtorm.server.OrmException;

import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.notes.Note;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.junit.Test;

import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

public class ChangeNotesTest extends AbstractChangeNotesTest {
  @Test
  public void approvalsOnePatchSet() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putApproval("Verified", (short) 1);
    update.putApproval("Code-Review", (short) -1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(1, notes.getApprovals().keySet().size());
    List<PatchSetApproval> psas =
      notes.getApprovals().get(c.currentPatchSetId());
    assertEquals(2, psas.size());

    assertEquals(c.currentPatchSetId(), psas.get(0).getPatchSetId());
    assertEquals(1, psas.get(0).getAccountId().get());
    assertEquals("Code-Review", psas.get(0).getLabel());
    assertEquals((short) -1, psas.get(0).getValue());
    assertEquals(truncate(after(c, 1000)), psas.get(0).getGranted());

    assertEquals(c.currentPatchSetId(), psas.get(1).getPatchSetId());
    assertEquals(1, psas.get(1).getAccountId().get());
    assertEquals("Verified", psas.get(1).getLabel());
    assertEquals((short) 1, psas.get(1).getValue());
    assertEquals(psas.get(0).getGranted(), psas.get(1).getGranted());
  }

  @Test
  public void approvalsMultiplePatchSets() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) -1);
    update.commit();
    PatchSet.Id ps1 = c.currentPatchSetId();

    incrementPatchSet(c);
    update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) 1);
    update.commit();
    PatchSet.Id ps2 = c.currentPatchSetId();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, PatchSetApproval> psas = notes.getApprovals();
    assertEquals(2, notes.getApprovals().keySet().size());

    PatchSetApproval psa1 = Iterables.getOnlyElement(psas.get(ps1));
    assertEquals(ps1, psa1.getPatchSetId());
    assertEquals(1, psa1.getAccountId().get());
    assertEquals("Code-Review", psa1.getLabel());
    assertEquals((short) -1, psa1.getValue());
    assertEquals(truncate(after(c, 1000)), psa1.getGranted());

    PatchSetApproval psa2 = Iterables.getOnlyElement(psas.get(ps2));
    assertEquals(ps2, psa2.getPatchSetId());
    assertEquals(1, psa2.getAccountId().get());
    assertEquals("Code-Review", psa2.getLabel());
    assertEquals((short) +1, psa2.getValue());
    assertEquals(truncate(after(c, 2000)), psa2.getGranted());
  }

  @Test
  public void approvalsMultipleApprovals() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) -1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    PatchSetApproval psa = Iterables.getOnlyElement(
        notes.getApprovals().get(c.currentPatchSetId()));
    assertEquals("Code-Review", psa.getLabel());
    assertEquals((short) -1, psa.getValue());

    update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) 1);
    update.commit();

    notes = newNotes(c);
    psa = Iterables.getOnlyElement(
        notes.getApprovals().get(c.currentPatchSetId()));
    assertEquals("Code-Review", psa.getLabel());
    assertEquals((short) 1, psa.getValue());
  }

  @Test
  public void approvalsMultipleUsers() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) -1);
    update.commit();

    update = newUpdate(c, otherUser);
    update.putApproval("Code-Review", (short) 1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(1, notes.getApprovals().keySet().size());
    List<PatchSetApproval> psas =
      notes.getApprovals().get(c.currentPatchSetId());
    assertEquals(2, psas.size());

    assertEquals(c.currentPatchSetId(), psas.get(0).getPatchSetId());
    assertEquals(1, psas.get(0).getAccountId().get());
    assertEquals("Code-Review", psas.get(0).getLabel());
    assertEquals((short) -1, psas.get(0).getValue());
    assertEquals(truncate(after(c, 1000)), psas.get(0).getGranted());

    assertEquals(c.currentPatchSetId(), psas.get(1).getPatchSetId());
    assertEquals(2, psas.get(1).getAccountId().get());
    assertEquals("Code-Review", psas.get(1).getLabel());
    assertEquals((short) 1, psas.get(1).getValue());
    assertEquals(truncate(after(c, 2000)), psas.get(1).getGranted());
  }

  @Test
  public void approvalsTombstone() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putApproval("Not-For-Long", (short) 1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    PatchSetApproval psa = Iterables.getOnlyElement(
        notes.getApprovals().get(c.currentPatchSetId()));
    assertEquals(1, psa.getAccountId().get());
    assertEquals("Not-For-Long", psa.getLabel());
    assertEquals((short) 1, psa.getValue());

    update = newUpdate(c, changeOwner);
    update.removeApproval("Not-For-Long");
    update.commit();

    notes = newNotes(c);
    assertTrue(notes.getApprovals().isEmpty());
  }

  @Test
  public void multipleReviewers() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.putReviewer(otherUser.getAccount().getId(), REVIEWER);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(ImmutableSetMultimap.of(
          REVIEWER, new Account.Id(1),
          REVIEWER, new Account.Id(2)),
        notes.getReviewers());
  }

  @Test
  public void reviewerTypes() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.putReviewer(otherUser.getAccount().getId(), CC);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(ImmutableSetMultimap.of(
          REVIEWER, new Account.Id(1),
          CC, new Account.Id(2)),
        notes.getReviewers());
  }

  @Test
  public void oneReviewerMultipleTypes() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(otherUser.getAccount().getId(), REVIEWER);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(ImmutableSetMultimap.of(
          REVIEWER, new Account.Id(2)),
        notes.getReviewers());

    update = newUpdate(c, otherUser);
    update.putReviewer(otherUser.getAccount().getId(), CC);
    update.commit();

    notes = newNotes(c);
    assertEquals(ImmutableSetMultimap.of(
          CC, new Account.Id(2)),
        notes.getReviewers());
  }

  @Test
  public void removeReviewer() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(otherUser.getAccount().getId(), REVIEWER);
    update.commit();

    update = newUpdate(c, changeOwner);
    update.putApproval("Code-Review", (short) 1);
    update.commit();

    update = newUpdate(c, otherUser);
    update.putApproval("Code-Review", (short) 1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    List<PatchSetApproval> psas =
        notes.getApprovals().get(c.currentPatchSetId());
    assertEquals(2, psas.size());
    assertEquals(changeOwner.getAccount().getId(), psas.get(0).getAccountId());
    assertEquals(otherUser.getAccount().getId(), psas.get(1).getAccountId());

    update = newUpdate(c, changeOwner);
    update.removeReviewer(otherUser.getAccount().getId());
    update.commit();

    notes = newNotes(c);
    psas = notes.getApprovals().get(c.currentPatchSetId());
    assertEquals(1, psas.size());
    assertEquals(changeOwner.getAccount().getId(), psas.get(0).getAccountId());
  }

  @Test
  public void submitRecords() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.setSubject("Submit patch set 1");

    update.submit(ImmutableList.of(
        submitRecord("NOT_READY", null,
          submitLabel("Verified", "OK", changeOwner.getAccountId()),
          submitLabel("Code-Review", "NEED", null)),
        submitRecord("NOT_READY", null,
          submitLabel("Verified", "OK", changeOwner.getAccountId()),
          submitLabel("Alternative-Code-Review", "NEED", null))));
    update.commit();

    ChangeNotes notes = newNotes(c);
    List<SubmitRecord> recs = notes.getSubmitRecords();
    assertEquals(2, recs.size());
    assertEquals(submitRecord("NOT_READY", null,
        submitLabel("Verified", "OK", changeOwner.getAccountId()),
        submitLabel("Code-Review", "NEED", null)), recs.get(0));
    assertEquals(submitRecord("NOT_READY", null,
        submitLabel("Verified", "OK", changeOwner.getAccountId()),
        submitLabel("Alternative-Code-Review", "NEED", null)), recs.get(1));
  }

  @Test
  public void latestSubmitRecordsOnly() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.setSubject("Submit patch set 1");
    update.submit(ImmutableList.of(
        submitRecord("OK", null,
          submitLabel("Code-Review", "OK", otherUser.getAccountId()))));
    update.commit();

    incrementPatchSet(c);
    update = newUpdate(c, changeOwner);
    update.setSubject("Submit patch set 2");
    update.submit(ImmutableList.of(
        submitRecord("OK", null,
          submitLabel("Code-Review", "OK", changeOwner.getAccountId()))));
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(submitRecord("OK", null,
          submitLabel("Code-Review", "OK", changeOwner.getAccountId())),
        Iterables.getOnlyElement(notes.getSubmitRecords()));
  }

  @Test
  public void emptyChangeUpdate() throws Exception {
    ChangeUpdate update = newUpdate(newChange(), changeOwner);
    update.commit();
    assertNull(update.getRevision());
  }

  @Test
  public void hashtagCommit() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    LinkedHashSet<String> hashtags = new LinkedHashSet<>();
    hashtags.add("tag1");
    hashtags.add("tag2");
    update.setHashtags(hashtags);
    update.commit();
    RevWalk walk = new RevWalk(repo);
    try {
      RevCommit commit = walk.parseCommit(update.getRevision());
      walk.parseBody(commit);
      assertTrue(commit.getFullMessage().endsWith("Hashtags: tag1,tag2\n"));
    } finally {
      walk.release();
    }
  }

  @Test
  public void hashtagChangeNotes() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    LinkedHashSet<String> hashtags = new LinkedHashSet<>();
    hashtags.add("tag1");
    hashtags.add("tag2");
    update.setHashtags(hashtags);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(hashtags, notes.getHashtags());
  }

  @Test
  public void emptyExceptSubject() throws Exception {
    ChangeUpdate update = newUpdate(newChange(), changeOwner);
    update.setSubject("Create change");
    update.commit();
    assertNotNull(update.getRevision());
  }

  @Test
  public void multipleUpdatesInBatch() throws Exception {
    Change c = newChange();
    ChangeUpdate update1 = newUpdate(c, changeOwner);
    update1.putApproval("Verified", (short) 1);

    ChangeUpdate update2 = newUpdate(c, otherUser);
    update2.putApproval("Code-Review", (short) 2);

    BatchMetaDataUpdate batch = update1.openUpdate();
    try {
      batch.write(update1, new CommitBuilder());
      batch.write(update2, new CommitBuilder());
      batch.commit();
    } finally {
      batch.close();
    }

    ChangeNotes notes = newNotes(c);
    List<PatchSetApproval> psas =
        notes.getApprovals().get(c.currentPatchSetId());
    assertEquals(2, psas.size());

    assertEquals(changeOwner.getAccount().getId(), psas.get(0).getAccountId());
    assertEquals("Verified", psas.get(0).getLabel());
    assertEquals((short) 1, psas.get(0).getValue());

    assertEquals(otherUser.getAccount().getId(), psas.get(1).getAccountId());
    assertEquals("Code-Review", psas.get(1).getLabel());
    assertEquals((short) 2, psas.get(1).getValue());
  }

  @Test
  public void multipleUpdatesIncludingComments() throws Exception {
    Change c = newChange();
    ChangeUpdate update1 = newUpdate(c, otherUser);
    String uuid1 = "uuid1";
    String message1 = "comment 1";
    CommentRange range1 = new CommentRange(1, 1, 2, 1);
    Timestamp time1 = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();
    BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate();
    BatchMetaDataUpdate batch = update1.openUpdateInBatch(bru);
    PatchLineComment comment1 = newPublishedPatchLineComment(psId, "file1",
        uuid1, range1, range1.getEndLine(), otherUser, null, time1, message1,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update1.setPatchSetId(psId);
    update1.upsertComment(comment1);
    update1.writeCommit(batch);
    ChangeUpdate update2 = newUpdate(c, otherUser);
    update2.putApproval("Code-Review", (short) 2);
    update2.writeCommit(batch);

    RevWalk rw = new RevWalk(repo);
    try {
      batch.commit();
      bru.execute(rw, NullProgressMonitor.INSTANCE);

      ChangeNotes notes = newNotes(c);
      ObjectId tip = notes.getRevision();
      RevCommit commitWithApprovals = rw.parseCommit(tip);
      assertNotNull(commitWithApprovals);
      RevCommit commitWithComments = commitWithApprovals.getParent(0);
      assertNotNull(commitWithComments);

      ChangeNotesParser notesWithComments =
          new ChangeNotesParser(c, commitWithComments.copy(), rw, repoManager);
      notesWithComments.parseAll();
      ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals1 =
          notesWithComments.buildApprovals();
      assertEquals(0, approvals1.size());
      assertEquals(1, notesWithComments.commentsForBase.size());
      notesWithComments.close();

      ChangeNotesParser notesWithApprovals =
          new ChangeNotesParser(c, commitWithApprovals.copy(), rw, repoManager);
      notesWithApprovals.parseAll();
      ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals2 =
          notesWithApprovals.buildApprovals();
      assertEquals(1, approvals2.size());
      assertEquals(1, notesWithApprovals.commentsForBase.size());
      notesWithApprovals.close();
    } finally {
      batch.close();
      rw.release();
    }
  }

  @Test
  public void multipleUpdatesAcrossRefs() throws Exception {
    Change c1 = newChange();
    ChangeUpdate update1 = newUpdate(c1, changeOwner);
    update1.putApproval("Verified", (short) 1);

    Change c2 = newChange();
    ChangeUpdate update2 = newUpdate(c2, otherUser);
    update2.putApproval("Code-Review", (short) 2);

    BatchMetaDataUpdate batch1 = null;
    BatchMetaDataUpdate batch2 = null;

    BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate();
    try {
      batch1 = update1.openUpdateInBatch(bru);
      batch1.write(update1, new CommitBuilder());
      batch1.commit();
      assertNull(repo.getRef(update1.getRefName()));

      batch2 = update2.openUpdateInBatch(bru);
      batch2.write(update2, new CommitBuilder());
      batch2.commit();
      assertNull(repo.getRef(update2.getRefName()));
    } finally {
      if (batch1 != null) {
        batch1.close();
      }
      if (batch2 != null) {
        batch2.close();
      }
    }

    List<ReceiveCommand> cmds = bru.getCommands();
    assertEquals(2, cmds.size());
    assertEquals(update1.getRefName(), cmds.get(0).getRefName());
    assertEquals(update2.getRefName(), cmds.get(1).getRefName());

    RevWalk rw = new RevWalk(repo);
    try {
      bru.execute(rw, NullProgressMonitor.INSTANCE);
    } finally {
      rw.release();
    }

    assertEquals(ReceiveCommand.Result.OK, cmds.get(0).getResult());
    assertEquals(ReceiveCommand.Result.OK, cmds.get(1).getResult());

    assertNotNull(repo.getRef(update1.getRefName()));
    assertNotNull(repo.getRef(update2.getRefName()));
  }

  @Test
  public void changeMessageOnePatchSet() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.setChangeMessage("Just a little code change.\n");
    update.commit();
    PatchSet.Id ps1 = c.currentPatchSetId();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(1, changeMessages.keySet().size());

    ChangeMessage cm = Iterables.getOnlyElement(changeMessages.get(ps1));
    assertEquals("Just a little code change.\n",
        cm.getMessage());
    assertEquals(changeOwner.getAccount().getId(),
        cm.getAuthor());
    assertEquals(ps1, cm.getPatchSetId());
  }

  @Test
  public void noChangeMessage() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.commit();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(0, changeMessages.keySet().size());
  }

  @Test
  public void changeMessageWithTrailingDoubleNewline() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.setChangeMessage("Testing trailing double newline\n"
        + "\n");
    update.commit();
    PatchSet.Id ps1 = c.currentPatchSetId();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(1, changeMessages.keySet().size());

    ChangeMessage cm1 = Iterables.getOnlyElement(changeMessages.get(ps1));
    assertEquals("Testing trailing double newline\n" + "\n", cm1.getMessage());
    assertEquals(changeOwner.getAccount().getId(), cm1.getAuthor());
  }

  @Test
  public void changeMessageWithMultipleParagraphs() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.setChangeMessage("Testing paragraph 1\n"
        + "\n"
        + "Testing paragraph 2\n"
        + "\n"
        + "Testing paragraph 3");
    update.commit();
    PatchSet.Id ps1 = c.currentPatchSetId();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(1, changeMessages.keySet().size());

    ChangeMessage cm1 = Iterables.getOnlyElement(changeMessages.get(ps1));
    assertEquals("Testing paragraph 1\n"
        + "\n"
        + "Testing paragraph 2\n"
        + "\n"
        + "Testing paragraph 3", cm1.getMessage());
    assertEquals(changeOwner.getAccount().getId(), cm1.getAuthor());
  }

  @Test
  public void changeMessagesMultiplePatchSets() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.setChangeMessage("This is the change message for the first PS.");
    update.commit();
    PatchSet.Id ps1 = c.currentPatchSetId();

    incrementPatchSet(c);
    update = newUpdate(c, changeOwner);

    update.setChangeMessage("This is the change message for the second PS.");
    update.commit();
    PatchSet.Id ps2 = c.currentPatchSetId();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(2, changeMessages.keySet().size());

    ChangeMessage cm1 = Iterables.getOnlyElement(changeMessages.get(ps1));
    assertEquals("This is the change message for the first PS.",
        cm1.getMessage());
    assertEquals(changeOwner.getAccount().getId(),
        cm1.getAuthor());

    ChangeMessage cm2 = Iterables.getOnlyElement(changeMessages.get(ps2));
    assertEquals(ps1, cm1.getPatchSetId());
    assertEquals("This is the change message for the second PS.",
        cm2.getMessage());
    assertEquals(changeOwner.getAccount().getId(), cm2.getAuthor());
    assertEquals(ps2, cm2.getPatchSetId());
  }

  @Test
  public void changeMessageMultipleInOnePatchSet() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.setChangeMessage("First change message.\n");
    update.commit();

    PatchSet.Id ps1 = c.currentPatchSetId();

    update = newUpdate(c, changeOwner);
    update.putReviewer(changeOwner.getAccount().getId(), REVIEWER);
    update.setChangeMessage("Second change message.\n");
    update.commit();

    ChangeNotes notes = newNotes(c);
    ListMultimap<PatchSet.Id, ChangeMessage> changeMessages =
        notes.getChangeMessages();
    assertEquals(1, changeMessages.keySet().size());

    List<ChangeMessage> cm = changeMessages.get(ps1);
    assertEquals(2, cm.size());
    assertEquals("First change message.\n",
        cm.get(0).getMessage());
    assertEquals(changeOwner.getAccount().getId(),
        cm.get(0).getAuthor());
    assertEquals(ps1, cm.get(0).getPatchSetId());
    assertEquals("Second change message.\n",
        cm.get(1).getMessage());
    assertEquals(changeOwner.getAccount().getId(),
        cm.get(1).getAuthor());
    assertEquals(ps1, cm.get(1).getPatchSetId());
  }

  @Test
  public void patchLineCommentNotesFormatSide1() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, otherUser);
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    String uuid3 = "uuid3";
    String message1 = "comment 1";
    String message2 = "comment 2";
    String message3 = "comment 3";
    CommentRange range1 = new CommentRange(1, 1, 2, 1);
    Timestamp time1 = TimeUtil.nowTs();
    Timestamp time2 = TimeUtil.nowTs();
    Timestamp time3 = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();

    PatchLineComment comment1 = newPublishedPatchLineComment(psId, "file1",
        uuid1, range1, range1.getEndLine(), otherUser, null, time1, message1,
        (short) 1, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment1);
    update.commit();

    update = newUpdate(c, otherUser);
    CommentRange range2 = new CommentRange(2, 1, 3, 1);
    PatchLineComment comment2 = newPublishedPatchLineComment(psId, "file1",
        uuid2, range2, range2.getEndLine(), otherUser, null, time2, message2,
        (short) 1, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment2);
    update.commit();

    update = newUpdate(c, otherUser);
    CommentRange range3 = new CommentRange(3, 1, 4, 1);
    PatchLineComment comment3 = newPublishedPatchLineComment(psId, "file2",
        uuid3, range3, range3.getEndLine(), otherUser, null, time3, message3,
        (short) 1, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment3);
    update.commit();

    ChangeNotes notes = newNotes(c);

    RevWalk walk = new RevWalk(repo);
    ArrayList<Note> notesInTree =
        Lists.newArrayList(notes.getNoteMap().iterator());
    Note note = Iterables.getOnlyElement(notesInTree);

    byte[] bytes =
        walk.getObjectReader().open(
            note.getData(), Constants.OBJ_BLOB).getBytes();
    String noteString = new String(bytes, UTF_8);
    assertEquals("Patch-set: 1\n"
        + "Revision: abcd1234abcd1234abcd1234abcd1234abcd1234\n"
        + "File: file1\n"
        + "\n"
        + "1:1-2:1\n"
        + CommentsInNotesUtil.formatTime(serverIdent, time1) + "\n"
        + "Author: Other Account <2@gerrit>\n"
        + "UUID: uuid1\n"
        + "Bytes: 9\n"
        + "comment 1\n"
        + "\n"
        + "2:1-3:1\n"
        + CommentsInNotesUtil.formatTime(serverIdent, time2) + "\n"
        + "Author: Other Account <2@gerrit>\n"
        + "UUID: uuid2\n"
        + "Bytes: 9\n"
        + "comment 2\n"
        + "\n"
        + "File: file2\n"
        + "\n"
        + "3:1-4:1\n"
        + CommentsInNotesUtil.formatTime(serverIdent, time3) + "\n"
        + "Author: Other Account <2@gerrit>\n"
        + "UUID: uuid3\n"
        + "Bytes: 9\n"
        + "comment 3\n"
        + "\n",
        noteString);
  }

  @Test
  public void patchLineCommentNotesFormatSide0() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, otherUser);
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    String message1 = "comment 1";
    String message2 = "comment 2";
    CommentRange range1 = new CommentRange(1, 1, 2, 1);
    Timestamp time1 = TimeUtil.nowTs();
    Timestamp time2 = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();

    PatchLineComment comment1 = newPublishedPatchLineComment(psId, "file1",
        uuid1, range1, range1.getEndLine(), otherUser, null, time1, message1,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment1);
    update.commit();

    update = newUpdate(c, otherUser);
    CommentRange range2 = new CommentRange(2, 1, 3, 1);
    PatchLineComment comment2 = newPublishedPatchLineComment(psId, "file1",
        uuid2, range2, range2.getEndLine(), otherUser, null, time2, message2,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);

    RevWalk walk = new RevWalk(repo);
    ArrayList<Note> notesInTree =
        Lists.newArrayList(notes.getNoteMap().iterator());
    Note note = Iterables.getOnlyElement(notesInTree);

    byte[] bytes =
        walk.getObjectReader().open(
            note.getData(), Constants.OBJ_BLOB).getBytes();
    String noteString = new String(bytes, UTF_8);
    assertEquals("Base-for-patch-set: 1\n"
        + "Revision: abcd1234abcd1234abcd1234abcd1234abcd1234\n"
        + "File: file1\n"
        + "\n"
        + "1:1-2:1\n"
        + CommentsInNotesUtil.formatTime(serverIdent, time1) + "\n"
        + "Author: Other Account <2@gerrit>\n"
        + "UUID: uuid1\n"
        + "Bytes: 9\n"
        + "comment 1\n"
        + "\n"
        + "2:1-3:1\n"
        + CommentsInNotesUtil.formatTime(serverIdent, time2) + "\n"
        + "Author: Other Account <2@gerrit>\n"
        + "UUID: uuid2\n"
        + "Bytes: 9\n"
        + "comment 2\n"
        + "\n",
        noteString);
  }

  @Test
  public void patchLineCommentMultipleOnePatchsetOneFileBothSides()
      throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, otherUser);
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    String messageForBase = "comment for base";
    String messageForPS = "comment for ps";
    CommentRange range = new CommentRange(1, 1, 2, 1);
    Timestamp now = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();

    PatchLineComment commentForBase =
        newPublishedPatchLineComment(psId, "filename", uuid1,
        range, range.getEndLine(), otherUser, null, now, messageForBase,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(commentForBase);
    update.commit();

    update = newUpdate(c, otherUser);
    PatchLineComment commentForPS =
        newPublishedPatchLineComment(psId, "filename", uuid2,
        range, range.getEndLine(), otherUser, null, now, messageForPS,
        (short) 1, "abcd4567abcd4567abcd4567abcd4567abcd4567");
    update.setPatchSetId(psId);
    update.upsertComment(commentForPS);
    update.commit();

    ChangeNotes notes = newNotes(c);
    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
        notes.getBaseComments();
    Multimap<PatchSet.Id, PatchLineComment> commentsForPS =
        notes.getPatchSetComments();
    assertEquals(commentsForBase.size(), 1);
    assertEquals(commentsForPS.size(), 1);

    assertEquals(commentForBase,
        Iterables.getOnlyElement(commentsForBase.get(psId)));
    assertEquals(commentForPS,
        Iterables.getOnlyElement(commentsForPS.get(psId)));
  }

  @Test
  public void patchLineCommentMultipleOnePatchsetOneFile() throws Exception {
    Change c = newChange();
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id psId = c.currentPatchSetId();
    String filename = "filename";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp timeForComment1 = TimeUtil.nowTs();
    Timestamp timeForComment2 = TimeUtil.nowTs();
    PatchLineComment comment1 = newPublishedPatchLineComment(psId, filename,
        uuid1, range, range.getEndLine(), otherUser, null, timeForComment1,
        "comment 1", side, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment1);
    update.commit();

    update = newUpdate(c, otherUser);
    PatchLineComment comment2 = newPublishedPatchLineComment(psId, filename,
        uuid2, range, range.getEndLine(), otherUser, null, timeForComment2,
        "comment 2", side, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);
    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
        notes.getBaseComments();
    Multimap<PatchSet.Id, PatchLineComment> commentsForPS =
        notes.getPatchSetComments();
    assertEquals(commentsForBase.size(), 0);
    assertEquals(commentsForPS.size(), 2);

    ImmutableList<PatchLineComment> commentsForThisPS =
        (ImmutableList<PatchLineComment>) commentsForPS.get(psId);
    assertEquals(commentsForThisPS.size(), 2);
    PatchLineComment commentFromNotes1 = commentsForThisPS.get(0);
    PatchLineComment commentFromNotes2 = commentsForThisPS.get(1);

    assertEquals(comment1, commentFromNotes1);
    assertEquals(comment2, commentFromNotes2);
  }

  @Test
  public void patchLineCommentMultipleOnePatchsetMultipleFiles()
      throws Exception {
    Change c = newChange();
    String uuid = "uuid";
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id psId = c.currentPatchSetId();
    String filename1 = "filename1";
    String filename2 = "filename2";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp now = TimeUtil.nowTs();
    PatchLineComment comment1 = newPublishedPatchLineComment(psId, filename1,
        uuid, range, range.getEndLine(), otherUser, null, now, "comment 1",
        side, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment1);
    update.commit();

    update = newUpdate(c, otherUser);
    PatchLineComment comment2 = newPublishedPatchLineComment(psId, filename2,
        uuid, range, range.getEndLine(), otherUser, null, now, "comment 2",
        side, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);
    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
        notes.getBaseComments();
    Multimap<PatchSet.Id, PatchLineComment> commentsForPS =
        notes.getPatchSetComments();
    assertEquals(commentsForBase.size(), 0);
    assertEquals(commentsForPS.size(), 2);

    ImmutableList<PatchLineComment> commentsForThisPS =
        (ImmutableList<PatchLineComment>) commentsForPS.get(psId);
    assertEquals(commentsForThisPS.size(), 2);
    PatchLineComment commentFromNotes1 = commentsForThisPS.get(0);
    PatchLineComment commentFromNotes2 = commentsForThisPS.get(1);

    assertEquals(comment1, commentFromNotes1);
    assertEquals(comment2, commentFromNotes2);
  }

  @Test
  public void patchLineCommentMultiplePatchsets() throws Exception {
    Change c = newChange();
    String uuid = "uuid";
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id ps1 = c.currentPatchSetId();
    String filename = "filename1";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp now = TimeUtil.nowTs();
    PatchLineComment comment1 = newPublishedPatchLineComment(ps1, filename,
        uuid, range, range.getEndLine(), otherUser, null, now, "comment on ps1",
        side, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(ps1);
    update.upsertComment(comment1);
    update.commit();

    incrementPatchSet(c);
    PatchSet.Id ps2 = c.currentPatchSetId();

    update = newUpdate(c, otherUser);
    now = TimeUtil.nowTs();
    PatchLineComment comment2 = newPublishedPatchLineComment(ps2, filename,
        uuid, range, range.getEndLine(), otherUser, null, now, "comment on ps2",
        side, "abcd4567abcd4567abcd4567abcd4567abcd4567");
    update.setPatchSetId(ps2);
    update.upsertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);
    LinkedListMultimap<PatchSet.Id, PatchLineComment> commentsForBase =
        LinkedListMultimap.create(notes.getBaseComments());
    LinkedListMultimap<PatchSet.Id, PatchLineComment> commentsForPS =
        LinkedListMultimap.create(notes.getPatchSetComments());
    assertEquals(commentsForBase.keys().size(), 0);
    assertEquals(commentsForPS.values().size(), 2);

    List<PatchLineComment> commentsForPS1 = commentsForPS.get(ps1);
    assertEquals(commentsForPS1.size(), 1);
    PatchLineComment commentFromPs1 = commentsForPS1.get(0);

    List<PatchLineComment> commentsForPS2 = commentsForPS.get(ps2);
    assertEquals(commentsForPS2.size(), 1);
    PatchLineComment commentFromPs2 = commentsForPS2.get(0);

    assertEquals(comment1, commentFromPs1);
    assertEquals(comment2, commentFromPs2);
  }

  @Test
  public void patchLineCommentSingleDraftToPublished() throws Exception {
    Change c = newChange();
    String uuid = "uuid";
    CommentRange range = new CommentRange(1, 1, 2, 1);
    PatchSet.Id ps1 = c.currentPatchSetId();
    String filename = "filename1";
    short side = (short) 1;

    ChangeUpdate update = newUpdate(c, otherUser);
    Timestamp now = TimeUtil.nowTs();
    PatchLineComment comment1 = newPatchLineComment(ps1, filename, uuid,
        range, range.getEndLine(), otherUser, null, now, "comment on ps1", side,
        "abcd4567abcd4567abcd4567abcd4567abcd4567", Status.DRAFT);
    update.setPatchSetId(ps1);
    update.insertComment(comment1);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertEquals(1, notes.getDraftPsComments(otherUserId).values().size());
    assertEquals(0, notes.getDraftBaseComments(otherUserId).values().size());

    comment1.setStatus(Status.PUBLISHED);
    update = newUpdate(c, otherUser);
    update.setPatchSetId(ps1);
    update.updateComment(comment1);
    update.commit();

    notes = newNotes(c);

    assertTrue(notes.getDraftPsComments(otherUserId).values().isEmpty());
    assertTrue(notes.getDraftBaseComments(otherUserId).values().isEmpty());

    assertTrue(notes.getBaseComments().values().isEmpty());
    PatchLineComment commentFromNotes =
        Iterables.getOnlyElement(notes.getPatchSetComments().values());
    assertEquals(comment1, commentFromNotes);
  }

  @Test
  public void patchLineCommentMultipleDraftsSameSidePublishOne()
      throws OrmException, IOException {
    Change c = newChange();
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    CommentRange range1 = new CommentRange(1, 1, 2, 2);
    CommentRange range2 = new CommentRange(2, 2, 3, 3);
    String filename = "filename1";
    short side = (short) 1;
    Timestamp now = TimeUtil.nowTs();
    String commitSHA1 = "abcd4567abcd4567abcd4567abcd4567abcd4567";
    PatchSet.Id psId = c.currentPatchSetId();

    // Write two drafts on the same side of one patch set.
    ChangeUpdate update = newUpdate(c, otherUser);
    update.setPatchSetId(psId);
    PatchLineComment comment1 = newPatchLineComment(psId, filename, uuid1,
        range1, range1.getEndLine(), otherUser, null, now, "comment on ps1",
        side, commitSHA1, Status.DRAFT);
    PatchLineComment comment2 = newPatchLineComment(psId, filename, uuid2,
        range2, range2.getEndLine(), otherUser, null, now, "other on ps1",
        side, commitSHA1, Status.DRAFT);
    update.insertComment(comment1);
    update.insertComment(comment2);
    update.commit();

    ChangeNotes notes = newNotes(c);
    assertTrue(notes.getDraftBaseComments(otherUserId).values().isEmpty());
    assertEquals(2, notes.getDraftPsComments(otherUserId).values().size());

    assertTrue(notes.getDraftPsComments(otherUserId).containsValue(comment1));
    assertTrue(notes.getDraftPsComments(otherUserId).containsValue(comment2));

    // Publish first draft.
    update = newUpdate(c, otherUser);
    update.setPatchSetId(psId);
    comment1.setStatus(Status.PUBLISHED);
    update.updateComment(comment1);
    update.commit();

    notes = newNotes(c);
    assertEquals(comment1,
        Iterables.getOnlyElement(notes.getPatchSetComments().get(psId)));
    assertEquals(comment2,
        Iterables.getOnlyElement(
            notes.getDraftPsComments(otherUserId).values()));

    assertTrue(notes.getBaseComments().values().isEmpty());
    assertTrue(notes.getDraftBaseComments(otherUserId).values().isEmpty());
  }

  @Test
  public void patchLineCommentsMultipleDraftsBothSidesPublishAll()
      throws OrmException, IOException {
    Change c = newChange();
    String uuid1 = "uuid1";
    String uuid2 = "uuid2";
    CommentRange range1 = new CommentRange(1, 1, 2, 2);
    CommentRange range2 = new CommentRange(2, 2, 3, 3);
    String filename = "filename1";
    Timestamp now = TimeUtil.nowTs();
    String commitSHA1 = "abcd4567abcd4567abcd4567abcd4567abcd4567";
    String baseSHA1 = "abcd1234abcd1234abcd1234abcd1234abcd1234";
    PatchSet.Id psId = c.currentPatchSetId();

    // Write two drafts, one on each side of the patchset.
    ChangeUpdate update = newUpdate(c, otherUser);
    update.setPatchSetId(psId);
    PatchLineComment baseComment = newPatchLineComment(psId, filename, uuid1,
        range1, range1.getEndLine(), otherUser, null, now, "comment on base",
        (short) 0, baseSHA1, Status.DRAFT);
    PatchLineComment psComment = newPatchLineComment(psId, filename, uuid2,
        range2, range2.getEndLine(), otherUser, null, now, "comment on ps",
        (short) 1, commitSHA1, Status.DRAFT);

    update.insertComment(baseComment);
    update.insertComment(psComment);
    update.commit();

    ChangeNotes notes = newNotes(c);
    PatchLineComment baseDraftCommentFromNotes =
        Iterables.getOnlyElement(
            notes.getDraftBaseComments(otherUserId).values());
    PatchLineComment psDraftCommentFromNotes =
        Iterables.getOnlyElement(
            notes.getDraftPsComments(otherUserId).values());

    assertEquals(baseComment, baseDraftCommentFromNotes);
    assertEquals(psComment, psDraftCommentFromNotes);

    // Publish both comments.
    update = newUpdate(c, otherUser);
    update.setPatchSetId(psId);

    baseComment.setStatus(Status.PUBLISHED);
    psComment.setStatus(Status.PUBLISHED);
    update.updateComment(baseComment);
    update.updateComment(psComment);
    update.commit();

    notes = newNotes(c);

    PatchLineComment baseCommentFromNotes =
        Iterables.getOnlyElement(notes.getBaseComments().values());
    PatchLineComment psCommentFromNotes =
        Iterables.getOnlyElement(notes.getPatchSetComments().values());

    assertEquals(baseComment, baseCommentFromNotes);
    assertEquals(psComment, psCommentFromNotes);

    assertTrue(notes.getDraftBaseComments(otherUserId).values().isEmpty());
    assertTrue(notes.getDraftPsComments(otherUserId).values().isEmpty());
  }

  @Test
  public void fileComment() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, otherUser);
    String uuid = "uuid";
    String messageForBase = "comment for base";
    Timestamp now = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();

    PatchLineComment commentForBase =
        newPublishedPatchLineComment(psId, "filename", uuid,
        null, 0, otherUser, null, now, messageForBase,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(commentForBase);
    update.commit();

    ChangeNotes notes = newNotes(c);
    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
        notes.getBaseComments();
    Multimap<PatchSet.Id, PatchLineComment> commentsForPs =
        notes.getPatchSetComments();

    assertTrue(commentsForPs.isEmpty());
    assertEquals(commentForBase,
        Iterables.getOnlyElement(commentsForBase.get(psId)));
  }

  @Test
  public void patchLineCommentNoRange() throws Exception {
    Change c = newChange();
    ChangeUpdate update = newUpdate(c, otherUser);
    String uuid = "uuid";
    String messageForBase = "comment for base";
    Timestamp now = TimeUtil.nowTs();
    PatchSet.Id psId = c.currentPatchSetId();

    PatchLineComment commentForBase =
        newPublishedPatchLineComment(psId, "filename", uuid,
        null, 1, otherUser, null, now, messageForBase,
        (short) 0, "abcd1234abcd1234abcd1234abcd1234abcd1234");
    update.setPatchSetId(psId);
    update.upsertComment(commentForBase);
    update.commit();

    ChangeNotes notes = newNotes(c);
    Multimap<PatchSet.Id, PatchLineComment> commentsForBase =
        notes.getBaseComments();
    Multimap<PatchSet.Id, PatchLineComment> commentsForPs =
        notes.getPatchSetComments();

    assertTrue(commentsForPs.isEmpty());
    assertEquals(commentForBase,
        Iterables.getOnlyElement(commentsForBase.get(psId)));
  }
}


text:
module Swaggable
  module Errors
    autoload :ValidationsCollection, 'swaggable/errors/validations_collection'

    Validation = Class.new StandardError
    EndpointNotFound = Class.new StandardError
    UnsupportedContentType = Class.new Validation
  end
end

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>Welcome to Pwb's documentation! — Pwb 2013-01 documentation</title>

    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />

    <link rel="top" title="Pwb 2013-01 documentation" href="#" />
    <link rel="next" title="Introduction" href="introduction.html" />

Navigation

          index

          next |

Pwb 2013-01 documentation »

Welcome to Pwb’s documentation!¶

Welcome to yet to be Psi-Calculi Workbench documentation!

Warning

under developement!

Contents:

Introduction

Installation

Symbolic Semantics

Requirements on psi-calculus parameters

Broadcast requirements

Sorted Substitution Requirements

Extra requirements of bisimulation algorithm on substitution

References

Coding Conventions

Uses: The Pwb Guerilla Module System

Todo

Fill in the missing pieces.

Next topic

Introduction

This Page

Show Source

Quick search

    <form class="search" action="search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>

    Enter search terms or a module, class or function name.

Navigation

          index

          next |

Pwb 2013-01 documentation »

        © Copyright 2013, Ramunas Gutkovas.
      Created using Sphinx 1.1.3.


text:
package org.stellar.base.xdr;

import java.io.IOException;

// === xdr source ============================================================

//  struct OperationMeta
//  {
//      LedgerEntryChanges changes;
//  };

//  ===========================================================================
public class OperationMeta  {
  public OperationMeta () {}
  private LedgerEntryChanges changes;
  public LedgerEntryChanges getChanges() {
    return this.changes;
  }
  public void setChanges(LedgerEntryChanges value) {
    this.changes = value;
  }
  public static void encode(XdrDataOutputStream stream, OperationMeta encodedOperationMeta) throws IOException{
    LedgerEntryChanges.encode(stream, encodedOperationMeta.changes);
  }
  public static OperationMeta decode(XdrDataInputStream stream) throws IOException {
    OperationMeta decodedOperationMeta = new OperationMeta();
    decodedOperationMeta.changes = LedgerEntryChanges.decode(stream);
    return decodedOperationMeta;
  }
}


text:
import os
import zipfile
import json
import datetime

from werkzeug._compat import to_unicode

from ..common import consts

metadata_items = [
    'sys_items',
    'sys_fields',
    'sys_indices',
    'sys_filters',
    'sys_report_params',
    'sys_roles',
    'sys_params',
    'sys_privileges',
    'sys_lookup_lists',
]

def export_task(task, url):
    result = {}
    result['db_type'] = task.task_db_type
    for item_name in metadata_items:
        item = task.item_by_name(item_name)
        copy = item.copy(handlers=False)
        copy.open()
        fields = []
        for field in copy.fields:
            fields.append(field.field_name)
        result[item.item_name] = {'fields': fields, 'records': copy.dataset}
    task_file = 'task.dat'
    file_name = 'task.zip'
    zip_file_name = os.path.join(task.work_dir, file_name)
    try:
        with open(task_file, 'w') as f:
            json.dump(result, f)
        with zipfile.ZipFile(zip_file_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
            zip_file.write(task_file)
            zip_dir('', zip_file, include_ext=['.html', '.js'], recursive=False)
            zip_dir('js', zip_file)
            zip_dir('css', zip_file)
            zip_dir(os.path.join('static', 'img'), zip_file)
            zip_dir(os.path.join('static', 'js'), zip_file)
            zip_dir(os.path.join('static', 'css'), zip_file)
            zip_dir(os.path.join('static', 'fonts'), zip_file)
            zip_dir(os.path.join('static', 'builder'), zip_file)
            zip_dir('utils', zip_file, exclude_ext=['.pyc'])
            zip_dir('reports', zip_file, exclude_ext=['.xml', '.ods#'], recursive=True)

        items = task.sys_items.copy()
        items.set_where(type_id=consts.TASK_TYPE)
        items.open()
        result_path = os.path.join(task.work_dir, 'static', 'internal')
        if not os.path.exists(result_path):
            os.makedirs(result_path)
        result_file = '%s_%s_%s_%s.zip' % (items.f_item_name.value, consts.VERSION,
            task.app.jam_version, datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
        os.rename(to_unicode(zip_file_name, 'utf-8'), os.path.join(to_unicode(result_path, 'utf-8'), to_unicode(result_file, 'utf-8')))
        if url:
            result = '%s/static/internal/%s' % (url, result_file)
        else:
            result = result_file
    finally:
        if os.path.exists(task_file):
            os.remove(task_file)
        if os.path.exists(file_name):
            os.remove(file_name)
    return result

def zip_dir(directory, zip_file, exclude_dirs=[], include_ext=None, exclude_ext=[], recursive=True):
    folder = os.path.join(os.getcwd())
    if directory:
        folder = os.path.join(os.getcwd(), directory)
    if os.path.exists(folder):
        if recursive:
            for dirpath, dirnames, filenames in os.walk(folder):
                head, tail = os.path.split(dirpath)
                if not tail in exclude_dirs:
                    for file_name in filenames:
                        name, ext = os.path.splitext(file_name)
                        if (not include_ext or ext in include_ext) and not ext in exclude_ext:
                            file_path = os.path.join(dirpath, file_name)
                            arcname = os.path.relpath(os.path.join(directory, file_path))
                            zip_file.write(file_path, arcname)
        else:
            for file_name in os.listdir(folder):
                name, ext = os.path.splitext(file_name)
                if (not include_ext or ext in include_ext) and not ext in exclude_ext:
                    file_path = os.path.join(folder, file_name)
                    arcname = os.path.relpath(os.path.join(directory, file_path))
                    zip_file.write(file_path, arcname)


text:
module AsposeCellsCloud
  #
  class ChartsChartArea < BaseObject
    attr_accessor :area, :auto_scale_font, :background_mode, :border, :font, :is_automatic_size, :is_inner_mode, :shadow, :shape_properties, :width, :height, :x, :y, :link
    # attribute mapping from ruby-style variable name to JSON key
    def self.attribute_map
      {

        #
        :'area' => :'Area',

        #
        :'auto_scale_font' => :'AutoScaleFont',

        #
        :'background_mode' => :'BackgroundMode',

        #
        :'border' => :'Border',

        #
        :'font' => :'Font',

        #
        :'is_automatic_size' => :'IsAutomaticSize',

        #
        :'is_inner_mode' => :'IsInnerMode',

        #
        :'shadow' => :'Shadow',

        #
        :'shape_properties' => :'ShapeProperties',

        #
        :'width' => :'Width',

        #
        :'height' => :'Height',

        #
        :'x' => :'X',

        #
        :'y' => :'Y',

        #
        :'link' => :'link'

      }
    end

    # attribute type
    def self.swagger_types
      {
        :'area' => :'DrawingArea',
        :'auto_scale_font' => :'BOOLEAN',
        :'background_mode' => :'String',
        :'border' => :'DrawingLine',
        :'font' => :'Font',
        :'is_automatic_size' => :'BOOLEAN',
        :'is_inner_mode' => :'BOOLEAN',
        :'shadow' => :'BOOLEAN',
        :'shape_properties' => :'Array<LinkElement>',
        :'width' => :'Integer',
        :'height' => :'Integer',
        :'x' => :'Integer',
        :'y' => :'Integer',
        :'link' => :'Link'

      }
    end

    def initialize(attributes = {})
      return if !attributes.is_a?(Hash) || attributes.empty?

      # convert string to symbol for hash key
      attributes = attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}

      if attributes[:'Area']
        self.area = attributes[:'Area']
      end

      if attributes[:'AutoScaleFont']
        self.auto_scale_font = attributes[:'AutoScaleFont']
      end

      if attributes[:'BackgroundMode']
        self.background_mode = attributes[:'BackgroundMode']
      end

      if attributes[:'Border']
        self.border = attributes[:'Border']
      end

      if attributes[:'Font']
        self.font = attributes[:'Font']
      end

      if attributes[:'IsAutomaticSize']
        self.is_automatic_size = attributes[:'IsAutomaticSize']
      end

      if attributes[:'IsInnerMode']
        self.is_inner_mode = attributes[:'IsInnerMode']
      end

      if attributes[:'Shadow']
        self.shadow = attributes[:'Shadow']
      end

      if attributes[:'ShapeProperties']
        if (value = attributes[:'ShapeProperties']).is_a?(Array)
          self.shape_properties = value
        end
      end

      if attributes[:'Width']
        self.width = attributes[:'Width']
      end

      if attributes[:'Height']
        self.height = attributes[:'Height']
      end

      if attributes[:'X']
        self.x = attributes[:'X']
      end

      if attributes[:'Y']
        self.y = attributes[:'Y']
      end

      if attributes[:'link']
        self.link = attributes[:'link']
      end

    end

  end
end


text:
#ifndef SELECTTHREADIMPL_H
#define SELECTTHREADIMPL_H

#include "dtoolbase.h"

/*
 * This file decides which of the core implementations of the various
 * threading and locking implementations we should use, based on platform
 * andor available libraries.  This file, along with mutexImpl.h and the
 * various Mutex implementation classes, are defined in dtool so that some
 * form of critical-section protection will be available to view low-level
 * classes like TypeRegistry.  Most of the rest of the threading and
 * synchronization classes are defined in pandasrcexpress.
 */

// This keyword should be used to mark any variable which is possibly volatile
// because multiple threads might contend on it, unprotected by a mutex.  It
// will be defined out in the non-threaded case.  Other uses for volatile (dma
// buffers, for instance) should use the regular volatile keyword.
#define TVOLATILE volatile

#if !defined(HAVE_THREADS) || defined(CPPPARSER)

// With threading disabled, use the do-nothing implementation.
#define THREAD_DUMMY_IMPL 1

// And the TVOLATILE keyword means nothing in the absence of threads.
#undef TVOLATILE
#define TVOLATILE

#elif defined(SIMPLE_THREADS)
// Use the simulated threading library.
#define THREAD_SIMPLE_IMPL 1
#undef TVOLATILE
#define TVOLATILE

#elif defined(WIN32_VC)

// In Windows, use the native threading library.
#define THREAD_WIN32_IMPL 1

#elif defined(HAVE_POSIX_THREADS)

// Posix threads are nice.
#define THREAD_POSIX_IMPL 1

#else

// This is a configuration error.  For some reason, HAVE_THREADS is defined
// but we don't have any way to implement it.
#error No thread implementation defined for platform.

#endif

// Let's also factor out some of the other configuration variables.
#if defined(DO_PIPELINING) && defined(HAVE_THREADS)
#define THREADED_PIPELINE 1
#else
#undef THREADED_PIPELINE
#endif

#endif


text:
FOUNDATION_EXPORT double Pods_PlayingCardsTestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_PlayingCardsTestsVersionString[];


text:
package kieker.tools.slastic.simulation.software.controller;

import kieker.common.record.controlflow.OperationExecutionRecord;
import kieker.tools.slastic.simulation.config.Constants;
import kieker.tools.slastic.simulation.model.ModelManager;

/**
 *
 * @author Robert von Massow
 *
 */
public class StackFrame {
	// private static final Log LOG = LogFactory.getLog(StackFrame.class);

	private final String calledServiceName;
	private final String asmContextTo;
	private final String serverId;
	private final double timeEnter;
	private final String traceId;

	private volatile int eoi = 0;

	public StackFrame(final String traceId, final String calledServiceName, final String asmContextTo, final String serverId, final double time) {
		this.traceId = traceId;
		this.calledServiceName = calledServiceName;
		this.asmContextTo = asmContextTo;
		this.serverId = serverId;
		this.timeEnter = time;
	}

	public final String getCalledServiceName() {
		return this.calledServiceName;
	}

	public final String getAsmContextTo() {
		return this.asmContextTo;
	}

	public final String getServerId() {
		return this.serverId;
	}

	public final double getTimeEnter() {
		return this.timeEnter;
	}

	public final OperationExecutionRecord createRecord(final double timeExit, final int depth) {

		final String componentName = ModelManager.getInstance().getAssemblyController().getASMInstanceAndComponentNameById(this.asmContextTo);
		final String operationSignature = componentName + "." + this.calledServiceName;
		final long tin = (long) (Constants.SIM_TIME_TO_MON_TIME * this.timeEnter);
		final long tout = (long) (Constants.SIM_TIME_TO_MON_TIME * timeExit);
		final long traceId = Long.parseLong(this.traceId);
		final String hostname = this.serverId;
		final int eoi = this.eoi;
		final int ess = depth;

		final OperationExecutionRecord rec =
				new OperationExecutionRecord(operationSignature, OperationExecutionRecord.NO_SESSION_ID, traceId, tin, tout, hostname, eoi, ess);
		return rec;
	}

	public final String getTraceId() {
		return this.traceId;
	}

	public final int getEoi() {
		return this.eoi;
	}

	public final void setEoi(final int eoi) {
		this.eoi = eoi;
	}

}


text:
BEGIN_INANITY_GUI

using namespace Graphics;

HbFontShape::HbFontShape(ptr<FontFace> face, hb_font_t* font)
: face(face), font(font), buffer(hb_buffer_create()) {}

HbFontShape::~HbFontShape()
{
	hb_font_destroy(font);
	hb_buffer_destroy(buffer);
}

FontShape::Language HbFontShape::GetLanguage(const String& tag)
{
	return (Language)hb_language_from_string(tag.c_str(), (int)tag.length());
}

void HbFontShape::Shape(const String& text, Script script, Language language, vec2* outAdvance, std::vector<OutGlyph>* outGlyphs)
{
	if(text.empty())
	{
		if(outAdvance)
			*outAdvance = vec2(0.0f, 0.0f);
		return;
	}

	// shape text, and get glyph numbers and offsets
	hb_buffer_set_script(buffer, (hb_script_t)script);
	hb_buffer_set_language(buffer, (hb_language_t)language);
	hb_buffer_set_direction(buffer, hb_script_get_horizontal_direction((hb_script_t)script));
	hb_buffer_add_utf8(buffer, text.c_str(), (int)text.length(), 0, (int)text.length());
	hb_shape(font, buffer, nullptr, 0);
	hb_buffer_normalize_glyphs(buffer);

	unsigned int glyphCount;
	hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(buffer, &glyphCount);
	hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(buffer, &glyphCount);

	// process numbers
	vec2 position(0, 0);
	for(unsigned int i = 0; i < glyphCount; ++i)
	{
		// unpack glyph offset and get position
		vec2 glyphPosition = position + vec2(
			float(glyphPositions[i].x_offset) / 64,
			float(glyphPositions[i].y_offset) / 64
		);

		vec2 glyphAdvance(float(glyphPositions[i].x_advance) / 64, float(glyphPositions[i].y_advance) / 64);

		// add out glyph
		if(outGlyphs)
		{
			OutGlyph outGlyph;
			outGlyph.position = glyphPosition;
			outGlyph.advance = glyphAdvance;
			outGlyph.glyphIndex = glyphInfos[i].codepoint;
			outGlyph.characterIndex = glyphInfos[i].cluster;
			outGlyphs->push_back(outGlyph);
		}

		// advance to next glyph
		position += glyphAdvance;
	}

	if(outAdvance)
		*outAdvance = position;

	// cleanup
	hb_buffer_reset(buffer);
}

void HbFontShape::ShapeParagraph(const String& text, Script script, Language language, const icu::Locale& locale, float maxLineWidth, float lineHeight, std::vector<OutGlyph>* outGlyphs)
{
	UErrorCode e = U_ZERO_ERROR;
	icu::UnicodeString s = icu::UnicodeString::fromUTF8(text);
	UBiDi* ubidi = ubidi_openSized(s.length(), 0, &e);
	if(!ubidi) return;

	UBiDiLevel paragraphDirection = hb_script_get_horizontal_direction((hb_script_t)script) == HB_DIRECTION_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR;
	ubidi_setPara(ubidi, s.getBuffer(), s.length(), paragraphDirection, nullptr, &e);

	float currentLineWidth = 0;
	Graphics::vec2 linePosition(0, 0);

	// break iterator for breaking logical runs into pieces
	icu::BreakIterator* breakIter = icu::BreakIterator::createLineInstance(locale, e);

	// loop for logical runs
	int32_t runLimit;
	UBiDiLevel runLevel;
	for(int32_t runStart = 0; ubidi_getLogicalRun(ubidi, runStart, &runLimit, &runLevel), runStart < s.length(); runStart = runLimit)
	{
		// break logical run into pieces
		icu::UnicodeString runStr = s.tempSubStringBetween(runStart, runLimit);
		breakIter->setText(runStr);

		// shape logical run
		hb_buffer_set_script(buffer, (hb_script_t)script);
		hb_buffer_set_language(buffer, (hb_language_t)language);
		hb_buffer_set_direction(buffer, runLevel == UBIDI_RTL ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);
		hb_buffer_add_utf16(buffer, (const uint16_t*)runStr.getBuffer(), runStr.length(), 0, runStr.length());
		hb_shape(font, buffer, nullptr, 0);
		hb_buffer_normalize_glyphs(buffer);

		unsigned int glyphCount;
		hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(buffer, &glyphCount);
		hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(buffer, &glyphCount);

		auto addCombinedPiece = [&](int32_t pieceStart, int32_t pieceLimit, float pieceWidth)
		{
			if(pieceStart >= pieceLimit) return;

			// if it doesn't fit into current line (and not the first piece in a line)
			float newCurrentLineWidth = currentLineWidth + pieceWidth;
			if(currentLineWidth > 0 && newCurrentLineWidth > maxLineWidth)
			{
				// start new line
				currentLineWidth = 0;
				linePosition.x = 0;
				linePosition.y += lineHeight;
			}

			// add piece to current line
			currentLineWidth += pieceWidth;

			if(paragraphDirection == UBIDI_DEFAULT_RTL) linePosition.x -= pieceWidth;
			Graphics::vec2 position = linePosition;
			if(paragraphDirection != UBIDI_DEFAULT_RTL) linePosition.x += pieceWidth;

			for(unsigned int i = 0; i < glyphCount; ++i)
			{
				if((int32_t)glyphInfos[i].cluster >= pieceStart && (int32_t)glyphInfos[i].cluster < pieceLimit)
				{
					// unpack glyph offset and get position
					vec2 glyphPosition = position + vec2(
						float(glyphPositions[i].x_offset) / 64,
						float(glyphPositions[i].y_offset) / 64
					);

					vec2 glyphAdvance(float(glyphPositions[i].x_advance) / 64, float(glyphPositions[i].y_advance) / 64);

					// add out glyph
					if(outGlyphs)
					{
						OutGlyph outGlyph;
						outGlyph.position = glyphPosition;
						outGlyph.advance = glyphAdvance;
						outGlyph.glyphIndex = glyphInfos[i].codepoint;
						outGlyph.characterIndex = glyphInfos[i].cluster;
						outGlyphs->push_back(outGlyph);
					}

					// advance to next glyph
					position += glyphAdvance;
				}
			}
		};

		int32_t pieceLimit;
		int32_t combinedPieceStart = 0;
		float combinedPieceWidth = 0;
		for(int32_t pieceStart = 0; pieceStart < runStr.length(); pieceStart = pieceLimit)
		{
			pieceLimit = breakIter->next();
			if(pieceLimit == icu::BreakIterator::DONE)
			{
				pieceLimit = runStr.length();
			}

			// calculate width of a piece
			float pieceWidth = 0;
			for(unsigned int i = 0; i < glyphCount; ++i)
			{
				if((int32_t)glyphInfos[i].cluster >= pieceStart && (int32_t)glyphInfos[i].cluster < pieceLimit)
				{
					pieceWidth += float(glyphPositions[i].x_advance) / 64;
				}
			}

			// try to combine it
			float newCombinedPieceWidth = combinedPieceWidth + pieceWidth;
			// if there's no overflow
			if(currentLineWidth + newCombinedPieceWidth <= maxLineWidth)
			{
				combinedPieceWidth = newCombinedPieceWidth;
			}
			// else it overflows
			else
			{
				// flush combined piece
				addCombinedPiece(combinedPieceStart, pieceStart, combinedPieceWidth);
				combinedPieceStart = pieceStart;
				combinedPieceWidth = pieceWidth;
				// ensure we start new line
				if(currentLineWidth > 0)
				{
					currentLineWidth = 0;
					linePosition.x = 0;
					linePosition.y += lineHeight;
				}
			}
		}
		// flush last combined piece
		addCombinedPiece(combinedPieceStart, runStr.length(), combinedPieceWidth);

		// cleanup
		hb_buffer_reset(buffer);
	};

	delete breakIter;

	ubidi_close(ubidi);
}

END_INANITY_GUI


text:
using mono::geo::Point;
using mono::geo::Rect;

Computer::Computer ()
:
  View(Rect(100, margin, paddleLength, paddleWidth)),
  x(100)
{
}

void Computer::tick (SharedState & state)
{
  if (state.game == SharedState::GameEnd)
    return;
  if (state.game == SharedState::Init)
    return repaint();
  if (state.game == SharedState::Intermission)
    return;
  if (state.msNow % computerSlowdown != 0)
    return;
  followBall(state.ballX);
  state.computerX = x;

  if (Position().X() < 0)
    state.crash = "computer x negative";
  if (Position().X() + paddleLength > screenHeight)
    state.crash = "computer x too high";
}

void Computer::repaint ()
{
  painter.setBackgroundColor(black);
  // Only erase minimal area to avoid flicker.
  uint16_t oldX = Position().X();
  if (oldX < x)
  {
    painter.drawFillRect(Rect(oldX, margin, x - oldX, paddleWidth), true);
  }
  else if (oldX > x)
  {
    painter.drawFillRect(Rect(x + paddleLength, margin, oldX - x, paddleWidth), true);
  }
  setPosition(Point(x, margin));
  painter.setBackgroundColor(green);
  painter.drawFillRect(ViewRect(), true);
}

void Computer::followBall (uint16_t ballX)
{
  if (rng.random31b() % 3 == 0)
    return;
  int direction = (ballX - 4 + rng.random31b() % 8) - (x + paddleLength/2);
  if (direction < 0)
    x -= 1;
  else if (direction > 0)
    x += 1;
  if (x < 0)
    x = 0;
  else if (x > screenHeight - paddleLength)
    x = screenHeight - paddleLength;
  if (x != Position().X())
    scheduleRepaint();
}


text:
package models

import api.ApiRequestHeader
import play.api.mvc.RequestHeader
import play.api.libs.json._
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

/*
* Stores all the information of a request. Specially used for store the errors in the DB.
*/
case class ApiLog(
    id: Long,
    date: DateTime,
    ip: String,
    apiKey: Option[String],
    token: Option[String],
    method: String,
    uri: String,
    requestBody: Option[String],
    responseStatus: Int,
    responseBody: Option[String]) {
  def dateStr: String = ApiLog.dtf.print(date)
}
object ApiLog {
  import FakeDB.logs

  private val dtf = DateTimeFormat.forPattern("MM/dd/yyyy HH:ss:mm")

  def findById(id: Long): Future[Option[ApiLog]] = Future.successful {
    logs.get(id)
  }

  def insert[R <: RequestHeader](request: ApiRequestHeader[R], status: Int, json: JsValue): Future[(Long, ApiLog)] = Future.successful {
    logs.insert(ApiLog(
      _,
      date = request.dateOrNow,
      ip = request.remoteAddress,
      apiKey = request.apiKeyOpt,
      token = request.tokenOpt,
      method = request.method,
      uri = request.uri,
      requestBody = request.maybeBody,
      responseStatus = status,
      responseBody = if (json == JsNull) None else Some(Json.prettyPrint(json))
    ))
  }

  def delete(id: Long): Future[Unit] = Future.successful {
    logs.delete(id)
  }

}


text:
const ExcelJS = verquire('exceljs');

const TEST_XLSX_FILE_NAME = './spec/out/wb.test.xlsx';

describe('github issues', () => {
  it('pull request 1204 - Read and write data validation should be successful', async () => {
    const wb = new ExcelJS.Workbook();
    await wb.xlsx.readFile('./spec/integration/data/test-pr-1204.xlsx');
    const expected = {
      E1: {
        type: 'textLength',
        formulae: [2],
        showInputMessage: true,
        showErrorMessage: true,
        operator: 'greaterThan',
      },
      E4: {
        type: 'textLength',
        formulae: [2],
        showInputMessage: true,
        showErrorMessage: true,
        operator: 'greaterThan',
      },
    };
    const ws = wb.getWorksheet(1);
    expect(ws.dataValidations.model).to.deep.equal(expected);
    await wb.xlsx.writeFile(TEST_XLSX_FILE_NAME);
  });
});


text:
package aQute.maven.api;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import aQute.bnd.version.MavenVersion;

public class Archive implements Comparable<Archive> {
	public static final Pattern	ARCHIVE_P	= Pattern.compile(																																					//
			"\\s*"																																																// skip
																																																				// whitespace
					+ "(?<program>[^:]+:[^:]+)         # program\n"																																				//
					+ "(:(?<extension>[^:]+)         # optional extension\n"																																	//
					+ "    (:(?<classifier>[^:]+))?  # optional classifer (must be preceded by extension)\n"																									//
					+ ")?                            # end of extension\n"																																		//
					+ ":(?<version>[^:]+)           # version is last\n"																																						//
					+ "\\s*",																																													// skip
																																																				// whitespace
			Pattern.COMMENTS);
	public final Revision		revision;
	public final String			classifier;
	public final String			extension;
	public final String			localPath;
	public final String			remotePath;
	public final MavenVersion	snapshot;

	public Archive(String s) {
		Archive v = valueOf(s);
		this.revision = v.revision;
		this.extension = v.extension;
		this.classifier = v.classifier;
		this.snapshot = v.snapshot;
		this.localPath = v.localPath;
		this.remotePath = v.remotePath;
	}

	Archive(Revision revision, MavenVersion snapshot, String extension, String classifier) {
		this.revision = revision;
		this.extension = extension == null || extension.isEmpty() ? "jar" : extension;
		this.classifier = classifier == null || classifier.isEmpty() ? "" : classifier;
		this.snapshot = snapshot;
		this.localPath = revision.path + "/" + getName();
		this.remotePath = revision.path + "/" + getName(snapshot);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + classifier.hashCode();
		result = prime * result + extension.hashCode();
		result = prime * result + revision.hashCode();
		result = prime * result + (snapshot == null ? 0 : snapshot.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;

		Archive other = (Archive) obj;
		if (!classifier.equals(other.classifier))
			return false;

		if (!extension.equals(other.extension))
			return false;

		if (!revision.equals(other.revision))
			return false;

		if (snapshot == null) {
			if (other.snapshot != null)
				return false;
		} else if (!snapshot.equals(other.snapshot))
			return false;

		return true;
	}

	public Revision getRevision() {
		return revision;
	}

	public String getName() {
		return getName(revision.version);
	}

	public boolean isSnapshot() {
		return revision.isSnapshot();
	}

	public String getName(MavenVersion version) {
		return revision.program.artifact + "-" + (version == null ? revision.version : version)
				+ (this.classifier.isEmpty() ? "" : "-" + this.classifier) + "." + this.extension;
	}

	public String toString() {
		StringBuilder sb = prefix();
		sb.append(":").append(revision.version);
		return sb.toString();
	}

	public String getWithoutVersion() {
		return prefix().toString();
	}

	private StringBuilder prefix() {
		StringBuilder sb = new StringBuilder();
		sb.append(revision.program.group);
		sb.append(":");
		sb.append(revision.program.artifact);

		if (!extension.isEmpty() && !extension.equals("jar")) {
			sb.append(":").append(extension);
			if (!classifier.isEmpty())
				sb.append(":").append(classifier);
		} else {
			if (!classifier.isEmpty()) {
				sb.append(":jar:").append(classifier);
			}
		}
		return sb;
	}

	public boolean isResolved() {
		return !isSnapshot() || snapshot != null;
	}

	public Archive resolveSnapshot(MavenVersion version) {
		if (version.equals(this.snapshot))
			return this;

		return new Archive(revision, version, extension, classifier);
	}

	public boolean isPom() {
		return "pom".equals(extension);
	}

	public Archive getPomArchive() {
		return revision.getPomArchive();
	}

	public static boolean isValid(String archive) {
		return ARCHIVE_P.matcher(archive).matches();
	}

	public static Archive valueOf(String archive) {
		Matcher m = ARCHIVE_P.matcher(archive);
		if (!m.matches())
			return null;

		Program p = Program.valueOf(m.group("program"));
		return p.version(m.group("version")).archive(m.group("extension"), m.group("classifier"));
	}

	@Override
	public int compareTo(Archive o) {
		int n = revision.compareTo(o.revision);
		if (n != 0)
			return n;

		n = extension.compareTo(o.extension);
		if (n != 0)
			return n;

		return classifier.compareTo(o.classifier);
	}

	final static Pattern FILEPATH_P = Pattern
			.compile("(?<group>([^/]+)(/[^/]+)+)/(?<artifact>[^/]+)/(?<version>[^/]+)/(?<name>[^/]+)");
	public static Archive fromFilepath(String filePath) {
		Matcher matcher = FILEPATH_P.matcher(filePath);
		if (!matcher.matches())
			return null;

		String group = matcher.group("group").replace('/', '.');
		String artifact = matcher.group("artifact");
		Program program = Program.valueOf(group, artifact);

		String version = matcher.group("version");
		Revision revision = program.version(version);

		String name = matcher.group("name");

		String prefix = artifact + "-" + version;
		if (!name.startsWith(prefix))
			return null;

		int n = name.lastIndexOf(".");
		if (n < prefix.length())
			return null;

		String extension = name.substring(n + 1);

		String classifier = null;
		if (prefix.length() < n)
			classifier = name.substring(prefix.length() + 1, n);

		return revision.archive(extension, classifier);
	}

	public static Archive valueOf(String group, String artifact, String version, String extension, String classifier) {
		return Program.valueOf(group, artifact).version(version).archive(extension, classifier);
	}

	public boolean hasClassifier() {
		return classifier != null && !classifier.isEmpty();
	}

	public boolean hasExtension() {
		return extension != null && !extension.isEmpty() && !extension.equals("jar");
	}

}


text:
namespace PaintsNow {
	class pure_interface INetwork : public ITunnel {
	public:
		~INetwork() override;
		class HttpRequest {};

		Dispatcher* OpenDispatcher() override = 0;
		void SetDispatcherOption(Dispatcher* dispatcher, const String& option, size_t value) override = 0;
		bool ActivateDispatcher(Dispatcher* dispatcher) override = 0;
		void DeactivateDispatcher(Dispatcher* dispatcher) override = 0;
		Dispatcher* GetListenerDispatcher(Listener* listener) override = 0;
		Dispatcher* GetConnectionDispatcher(Connection* connection) override = 0;
		void CloseDispatcher(Dispatcher* dispatcher) override = 0;
		std::vector<String> Resolve(const String& name) override = 0;

		// derived from ITunnel
		Listener* OpenListener(Dispatcher* dispatcher, const TWrapper<void, ITunnel::Listener*, EVENT>& eventHandler, const TWrapper<const TWrapper<void, ITunnel::Connection*, EVENT>, Connection*>& callback, const String& address) override = 0;
		virtual void SetListenerForHttpd(Listener* listener, const TWrapper<void, Connection*, HttpRequest*>& httpRequestHandler) = 0;
		bool ActivateListener(Listener* listener) override = 0;
		String GetAddress(Listener* listener) override = 0;
		void DeactivateListener(Listener* listener) override = 0;
		void CloseListener(Listener* listener) override = 0;

		Connection* OpenConnection(Dispatcher* dispatcher, const TWrapper<void, ITunnel::Connection*, EVENT>& callback, const String& address) override = 0;
		bool ActivateConnection(Connection* connection) override = 0;
		void GetConnectionAddresses(Connection* connection, String& from, String& to) override = 0;
		void Flush(Connection* connection) override = 0;
		bool ReadConnection(Connection* connection, void* data, size_t& length, size_t& mode) override = 0;
		bool WriteConnection(Connection* connection, const void* data, size_t length, size_t mode) override = 0;
		void DeactivateConnection(Connection* connection) override = 0;
		void CloseConnection(Connection* connection) override = 0;

		// URI, METHOD, CONTENT
		virtual void PrepareHttpRequest(HttpRequest* request) = 0;
		virtual String GetHttpRequestUri(HttpRequest* request) = 0;
		virtual void SetHttpRequestUri(HttpRequest* request, const String& uri) = 0;
		virtual String GetHttpRequestMethod(HttpRequest* request) = 0;
		virtual void SetHttpRequestMethod(HttpRequest* request, const String& method) = 0;
		virtual void GetHttpRequestHeader(HttpRequest* request, std::list<std::pair<String, String> >& header) = 0;
		virtual String GetHttpRequestData(HttpRequest* request) = 0;
		virtual void SetHttpRequestData(HttpRequest* request, const String& uri) = 0;
		virtual void SetHttpRequestHeader(HttpRequest* request, const std::list<std::pair<String, String> >& header) = 0;
		virtual void ParseUri(const String& uri, String& user, String& host, int& port, String& path, std::list<std::pair<String, String> >& query, String& fragment) = 0;
		virtual String MakeUri(const String& user, const String& host, const String& path, const std::list<std::pair<String, String> >& query, const String& fragment) = 0;

		virtual void MakeHttpRequest(HttpRequest* request) = 0;
		virtual void MakeHttpResponse(HttpRequest* request, int code, const String& reason, const String& data) = 0;

		virtual HttpRequest* OpenHttpRequest(Connection* connection, const TWrapper<void, int>& callback) = 0;
		virtual void CloseHttpRequest(HttpRequest* request) = 0;
	};
}


text:
USE master
GO

-- Create a db
CREATE DATABASE PeopleDB
GO

USE PeopleDB
GO

-- Create a new table named 'Persons'
CREATE TABLE Persons
(
	PersonsId int IDENTITY NOT NULL PRIMARY KEY,
	FirstName nvarchar(50) NOT NULL,
	LastName nvarchar(50) NOT NULL,
	SSN varchar(9) NOT NULL
)
GO

-- Create a new table named 'Accounts'
CREATE TABLE Accounts
(
	Id int IDENTITY NOT NULL PRIMARY KEY,
	PersonId int NOT NULL FOREIGN KEY REFERENCES Persons(PersonsId),
	Balance money NOT NULL
)
GO

--INSERT some values into both tables and repeat this action a few times
INSERT INTO Persons(FirstName, LastName, SSN)
VALUES('Natalie', 'Klein', '9212315698')

INSERT INTO Accounts(PersonID, Balance)
VALUES (3, 789058.67)

--1.
CREATE PROC dbo.usp_SelectFullNamesOfAllPersons
AS
	SELECT DISTINCT CONCAT(FirstName, LastName) AS [Full Name]
	FROM Persons
GO

--2.
CREATE PROC dbo.usp_ReturnsAllPersonsWithMoreMoneyInAccountsThanGivenParameter
(@givenParameter money)
AS
SELECT CONCAT(p.FirstName, p.LastName) AS [Full Name], a.Balance
FROM Persons p
	JOIN Accounts a
		ON a.PersonID = p.PersonID
WHERE a.Balance > @givenParameter
ORDER BY a.Balance DESC

--3.
CREATE FUNCTION unf_CalculateAndReturnSum(@sum money, @interestRate float, @numberOfMonths int)
RETURNS money
AS

BEGIN
	RETURN @sum * (1 + @interestRate / 12) * @numberOfMonths
END
GO

--Test it
USE PeopleDB
SELECT Balance, ROUND(dbo.unf_CalculateAndReturnSum(Balance, 3.50, 11), 2) AS [Bonus]
FROM Accounts

--4.
USE PeopleDB
GO

CREATE PROC dbo.usp_CalculateInterestRateToAccountPerMonth(@accountId int, @interestRate float)
AS
	DECLARE @balance money
	SELECT @balance = Balance FROM Accounts WHERE PersonID = AccountID

	DECLARE @newBalance money
	SELECT @newBalance = dbo.unf_CalculateAndReturnSum(@balance,  @interestRate, 3)

	SELECT CONCAT(p.FirstName, p.LastName) AS [Full Name], a.Balance, @newBalance AS [New balance]
	FROM Persons p
		JOIN Accounts a
			ON p.PersonID = a.AccountID
	WHERE a.AccountID = @accountId
GO

--Test
EXEC dbo.usp_CalculateInterestRateToAccountPerMonth 1, 0.5
EXEC dbo.usp_CalculateInterestRateToAccountPerMonth 2, 2.5
EXEC dbo.usp_CalculateInterestRateToAccountPerMonth 3, 1.5

--5.
CREATE PROC dbo.usp_WithdrawMoney(@AccountId int, @money money)
AS
	BEGIN TRANSACTION
		UPDATE Accounts
		SET Balance -= @money
		WHERE AccountID = @AccountId
	COMMIT TRANSACTION
GO

CREATE PROC dbo.usp_DepositMoney(@AccountId int, @money money)
AS
	BEGIN TRANSACTION
		UPDATE Accounts
		SET Balance += @money
		WHERE AccountID = @AccountId
	COMMIT TRANSACTION
GO

EXEC dbo.usp_WithdrawMoney 5, 678

EXEC dbo.usp_DepositMoney 3, 500

--6.
CREATE TABLE Logs
(
    LogId int IDENTITY PRIMARY KEY,
    AccountId int NOT NULL FOREIGN KEY REFERENCES Accounts(AccountId),
    OldSum money NOT NULL,
    NewSum money NOT NULL
)

CREATE TRIGGER tr_UpdateAccountBalance ON Accounts FOR UPDATE
AS
    DECLARE @oldSum money;
    SELECT @oldSum = Balance FROM deleted;

    INSERT INTO Logs(AccountId, OldSum, NewSum)
        SELECT AccountId, @oldSum, Balance
        FROM inserted
GO

EXEC usp_WithdrawMoney 1, 500

EXEC usp_DepositMoney 3, 2000

--7.
USE TelerikAcademy
GO

CREATE FUNCTION ufn_SearchForWordsInGivenPattern(@pattern nvarchar(255))
	RETURNS @MatchedNames TABLE (Name varchar(50))
AS
BEGIN
	INSERT @MatchedNames
	SELECT *
	FROM
		(SELECT e.FirstName FROM Employees e
        UNION
        SELECT e.LastName FROM Employees e
        UNION
        SELECT t.Name FROM Towns t) as temp(name)
    WHERE PATINDEX('%[' + @pattern + ']', Name) > 0
	RETURN
END
GO

-- Test
-- SELECT * FROM dbo.ufn_SearchForWordsInGivenPattern('oistmiahf')

--8.
DECLARE empCursor CURSOR READ_ONLY FOR
    SELECT emp1.FirstName, emp1.LastName, t1.Name, emp2.FirstName, emp2.LastName
    FROM Employees emp1
    JOIN Addresses a1
        ON emp1.AddressID = a1.AddressID
    JOIN Towns t1
        ON a1.TownID = t1.TownID,
        Employees emp2
    JOIN Addresses a2
        ON emp2.AddressID = a2.AddressID
    JOIN Towns t2
        ON a2.TownID = t2.TownID
    WHERE t1.TownID = t2.TownID AND emp1.EmployeeID != emp2.EmployeeID
    ORDER BY emp1.FirstName, emp2.FirstName

OPEN empCursor

DECLARE @firstName1 nvarchar(50),
        @lastName1 nvarchar(50),
        @townName nvarchar(50),
        @firstName2 nvarchar(50),
        @lastName2 nvarchar(50)
FETCH NEXT FROM empCursor INTO @firstName1, @lastName1, @townName, @firstName2, @lastName2

DECLARE @counter int;
SET @counter = 0;

WHILE @@FETCH_STATUS = 0
	BEGIN
		SET @counter = @counter + 1;

		PRINT @firstName1 + ' ' + @lastName1 +
			  '     ' + @townName + '       ' +
			  @firstName2 + ' ' + @lastName2;

		FETCH NEXT FROM empCursor
		INTO @firstName1, @lastName1, @townName, @firstName2, @lastName2
	END

print 'Total records: ' + CAST(@counter AS nvarchar(10));

CLOSE empCursor
DEALLOCATE empCursor

--9.
IF NOT EXISTS (
    SELECT value
    FROM sys.configurations
    WHERE name = 'clr enabled' AND value = 1
)
BEGIN
    EXEC sp_configure @configname = clr_enabled, @configvalue = 1
    RECONFIGURE
END
GO

-- Remove the aggregate and assembly if they're there
IF (OBJECT_ID('dbo.concat') IS NOT NULL)
    DROP Aggregate concat;
GO

IF EXISTS (SELECT * FROM sys.assemblies WHERE name = 'concat_assembly')
    DROP assembly concat_assembly;
GO

CREATE Assembly concat_assembly
   AUTHORIZATION dbo
   FROM 'C:\SqlStringConcatenation.dll' --- CHANGE THE LOCATION
   WITH PERMISSION_SET = SAFE;
GO

CREATE AGGREGATE dbo.concat (
    @Value NVARCHAR(MAX),
    @Delimiter NVARCHAR(4000)
)
    RETURNS NVARCHAR(MAX)
    EXTERNAL Name concat_assembly.concat;
GO

--- CURSOR
DECLARE empCursor CURSOR READ_ONLY FOR
    SELECT t.Name, dbo.concat(e.FirstName + ' ' + e.LastName, ', ')
    FROM Towns t
    JOIN Addresses a
        ON t.TownID = a.TownID
    JOIN Employees e
        ON a.AddressID = e.AddressID
    GROUP BY t.Name
    ORDER BY t.Name

OPEN empCursor

DECLARE @townName nvarchar(50),
        @employeesNames nvarchar(max)
FETCH NEXT FROM empCursor INTO @townName, @employeesNames

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @townName + ' -> ' + @employeesNames;

    FETCH NEXT FROM empCursor
    INTO @townName, @employeesNames
END

CLOSE empCursor
DEALLOCATE empCursor
GO

DROP Aggregate concat;
DROP assembly concat_assembly;
GO

--10.
IF NOT EXISTS (
    SELECT value
    FROM sys.configurations
    WHERE name = 'clr enabled' AND value = 1
)
BEGIN
    EXEC sp_configure @configname = clr_enabled, @configvalue = 1
    RECONFIGURE
END
GO

-- Remove the aggregate and assembly if they're there
IF (OBJECT_ID('dbo.concat') IS NOT NULL)
    DROP Aggregate concat;
GO

IF EXISTS (SELECT * FROM sys.assemblies WHERE name = 'concat_assembly')
    DROP assembly concat_assembly;
GO

CREATE Assembly concat_assembly
   AUTHORIZATION dbo
   FROM 'C:\SqlStringConcatenation.dll' --- CHANGE THE LOCATION
   WITH PERMISSION_SET = SAFE;
GO

CREATE AGGREGATE dbo.concat (
    @Value NVARCHAR(MAX),
    @Delimiter NVARCHAR(4000)
)
    RETURNS NVARCHAR(MAX)
    EXTERNAL Name concat_assembly.concat;
GO

SELECT dbo.concat(FirstName + ' ' + LastName, ', ')
FROM Employees
GO

DROP Aggregate concat;
DROP assembly concat_assembly;
GO


text:
0.4.0 (unreleased)
------------------

New Features
^^^^^^^^^^^^

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Bug Fixes
^^^^^^^^^

0.3.2 (unreleased)
------------------

New Features
^^^^^^^^^^^^

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Opt in to new container-based builds on travis. [#227]

- Update astropy_helpers to 1.0.5. [#245]

Bug Fixes
^^^^^^^^^

- Ensure that creating a WCS from a header that contains list-like keywords
  (e.g. ``BLANK`` or ``HISTORY``) succeeds. [#229, #231]

0.3.1 (2015-05-12)
------------------

New Features
^^^^^^^^^^^^

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Add extensive tests to ensure ``ccdproc`` functions do not modify the input
  data. [#208]

- Remove red-box warning about API stability from docs. [#210]

- Support astropy 1.0.5, which made changes to ``NDData``. [#242]

Bug Fixes
^^^^^^^^^

- Make ``subtract_overscan`` act on a copy of the input data. [#206]

- Overscan subtraction failed on non-square images if the overscan axis was the
  first index, ``0``. [#240, #244]

0.3.0 (2015-03-17)
------------------

New Features
^^^^^^^^^^^^

- When reading in a FITS file, the extension to be used can be specified.  If
  it is not and there is no data in the primary extension, the first extension
  with data will be used.

- Set wcs attribute when reading from a FITS file that contains WCS keywords
  and write WCS keywords to header when converting to an HDU. [#195]

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Updated CCDData to use the new version of NDDATA in astropy v1.0.   This
  breaks backward compatibility with earlier versions of astropy.

Bug Fixes
^^^^^^^^^

- Ensure ``dtype`` of combined images matches the ``dtype`` of the
  ``Combiner`` object. [#189]

0.2.2 (2014-11-05)
------------------

New Features
^^^^^^^^^^^^

- Add dtype argument to `ccdproc.Combiner` to help control memory use [#178]

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Added Changes to the docs [#183]

Bug Fixes
^^^^^^^^^

- Allow the unit string "adu" to be upper or lower case in a FIS header [#182]

0.2.1 (2014-09-09)
------------------

New Features
^^^^^^^^^^^^

- Add a unit directly from BUNIT if it is available in the FITS header [#169]

Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Relaxed the requirements on what the metadata must be. It can be anything dict-like, e.g. an astropy.io.fits.Header, a python dict, an OrderedDict or some custom object created by the user. [#167]

Bug Fixes
^^^^^^^^^

- Fixed a new-style formating issue in the logging [#170]

0.2 (2014-07-28)
----------------

- Initial release.


text:
drop table users if exists;

create table users (
  id int,
  name varchar(20)
);

insert into users (id, name) values(1, 'User1');
insert into users (id, name) values(2, 'User2');
insert into users (id, name) values(3, 'User3');