text:
test_description='test smart pushing over http via http-backend'
. ./test-lib.sh

ROOT_PATH="$PWD"
. "$TEST_DIRECTORY"/lib-gpg.sh
. "$TEST_DIRECTORY"/lib-httpd.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
start_httpd

test_expect_success 'setup remote repository' '
	cd "$ROOT_PATH" &&
	mkdir test_repo &&
	cd test_repo &&
	git init &&
	: >path1 &&
	git add path1 &&
	test_tick &&
	git commit -m initial &&
	cd - &&
	git clone --bare test_repo test_repo.git &&
	cd test_repo.git &&
	git config http.receivepack true &&
	git config core.logallrefupdates true &&
	ORIG_HEAD=$(git rev-parse --verify HEAD) &&
	cd - &&
	mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
'

setup_askpass_helper

cat >exp <<EOF
GET  /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200
EOF
test_expect_success 'no empty path components' '
	# Clear the log, so that it does not affect the "used receive-pack
	# service" test which reads the log too.
	test_when_finished ">\"\$HTTPD_ROOT_PATH\"/access.log" &&

	# In the URL, add a trailing slash, and see if git appends yet another
	# slash.
	cd "$ROOT_PATH" &&
	git clone $HTTPD_URL/smart/test_repo.git/ test_repo_clone &&

	# NEEDSWORK: If the overspecification of the expected result is reduced, we
	# might be able to run this test in all protocol versions.
	if test -z "$GIT_TEST_PROTOCOL_VERSION"
	then
		check_access_log exp
	fi
'

test_expect_success 'clone remote repository' '
	rm -rf test_repo_clone &&
	git clone $HTTPD_URL/smart/test_repo.git test_repo_clone &&
	(
		cd test_repo_clone && git config push.default matching
	)
'

test_expect_success 'push to remote repository (standard)' '
	cd "$ROOT_PATH"/test_repo_clone &&
	: >path2 &&
	git add path2 &&
	test_tick &&
	git commit -m path2 &&
	HEAD=$(git rev-parse --verify HEAD) &&
	GIT_TRACE_CURL=true git push -v -v 2>err &&
	! grep "Expect: 100-continue" err &&
	grep "POST git-receive-pack ([0-9]* bytes)" err &&
	(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
	 test $HEAD = $(git rev-parse --verify HEAD))
'

test_expect_success 'push already up-to-date' '
	git push
'

test_expect_success 'create and delete remote branch' '
	cd "$ROOT_PATH"/test_repo_clone &&
	git checkout -b dev &&
	: >path3 &&
	git add path3 &&
	test_tick &&
	git commit -m dev &&
	git push origin dev &&
	git push origin :dev &&
	test_must_fail git show-ref --verify refs/remotes/origin/dev
'

cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
#!/bin/sh
exit 1
EOF
chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"

cat >exp <<EOF
remote: error: hook declined to update refs/heads/dev2
To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
 ! [remote rejected] dev2 -> dev2 (hook declined)
error: failed to push some refs to 'http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git'
EOF

test_expect_success 'rejected update prints status' '
	cd "$ROOT_PATH"/test_repo_clone &&
	git checkout -b dev2 &&
	: >path4 &&
	git add path4 &&
	test_tick &&
	git commit -m dev2 &&
	test_must_fail git push origin dev2 2>act &&
	sed -e "/^remote: /s/ *$//" <act >cmp &&
	test_i18ncmp exp cmp
'
rm -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"

cat >exp <<EOF
GET  /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200
GET  /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET  /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
GET  /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET  /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET  /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
EOF
test_expect_success 'used receive-pack service' '
	# NEEDSWORK: If the overspecification of the expected result is reduced, we
	# might be able to run this test in all protocol versions.
	if test -z "$GIT_TEST_PROTOCOL_VERSION"
	then
		check_access_log exp
	fi
'

test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \
	"$ROOT_PATH"/test_repo_clone master 		success

test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper' '
	# create a dissimilarly-named remote ref so that git is unable to match the
	# two refs (viz. local, remote) unless an explicit refspec is provided.
	git push origin master:retsam &&

	echo "change changed" > path2 &&
	git commit -a -m path2 --amend &&

	# push master too; this ensures there is at least one '"'push'"' command to
	# the remote helper and triggers interaction with the helper.
	test_must_fail git push -v origin +master master:retsam >output 2>&1'

test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper: remote output' '
	grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *master -> master (forced update)$" output &&
	grep "^ ! \[rejected\] *master -> retsam (non-fast-forward)$" output
'

test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper: our output' '
	test_i18ngrep "Updates were rejected because" \
		output
'

test_expect_success 'push (chunked)' '
	git checkout master &&
	test_commit commit path3 &&
	HEAD=$(git rev-parse --verify HEAD) &&
	test_config http.postbuffer 4 &&
	git push -v -v origin $BRANCH 2>err &&
	grep "POST git-receive-pack (chunked)" err &&
	(cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
	 test $HEAD = $(git rev-parse --verify HEAD))
'

test_expect_success 'push --atomic also prevents branch creation, reports collateral' '
	# Setup upstream repo - empty for now
	d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
	git init --bare "$d" &&
	test_config -C "$d" http.receivepack true &&
	up="$HTTPD_URL"/smart/atomic-branches.git &&

	# Tell "$up" about three branches for now
	test_commit atomic1 &&
	test_commit atomic2 &&
	git branch collateral &&
	git branch other &&
	git push "$up" master collateral other &&

	# collateral is a valid push, but should be failed by atomic push
	git checkout collateral &&
	test_commit collateral1 &&

	# Make master incompatible with upstream to provoke atomic
	git checkout master &&
	git reset --hard HEAD^ &&

	# Add a new branch which should be failed by atomic push. This is a
	# regression case.
	git branch atomic &&

	# --atomic should cause entire push to be rejected
	test_must_fail git push --atomic "$up" master atomic collateral 2>output &&

	# the new branch should not have been created upstream
	test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&

	# upstream should still reflect atomic2, the last thing we pushed
	# successfully
	git rev-parse atomic2 >expected &&
	# on master...
	git -C "$d" rev-parse refs/heads/master >actual &&
	test_cmp expected actual &&
	# ...and collateral.
	git -C "$d" rev-parse refs/heads/collateral >actual &&
	test_cmp expected actual &&

	# the failed refs should be indicated to the user
	grep "^ ! .*rejected.* master -> master" output &&

	# the collateral failure refs should be indicated to the user
	grep "^ ! .*rejected.* atomic -> atomic .*atomic push failed" output &&
	grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
'

test_expect_success 'push --atomic fails on server-side errors' '
	# Use previously set up repository
	d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
	test_config -C "$d" http.receivepack true &&
	up="$HTTPD_URL"/smart/atomic-branches.git &&

	# break ref updates for other on the remote site
	mkdir "$d/refs/heads/other.lock" &&

	# add the new commit to other
	git branch -f other collateral &&

	# --atomic should cause entire push to be rejected
	test_must_fail git push --atomic "$up" atomic other 2>output  &&

	# the new branch should not have been created upstream
	test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&

	# upstream should still reflect atomic2, the last thing we pushed
	# successfully
	git rev-parse atomic2 >expected &&
	# ...to other.
	git -C "$d" rev-parse refs/heads/other >actual &&
	test_cmp expected actual &&

	# the new branch should not have been created upstream
	test_must_fail git -C "$d" show-ref --verify refs/heads/atomic &&

	# the failed refs should be indicated to the user
	grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output &&

	# the collateral failure refs should be indicated to the user
	grep "^ ! .*rejected.* atomic -> atomic .*atomic transaction failed" output
'

test_expect_success 'push --all can push to empty repo' '
	d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
	git init --bare "$d" &&
	git --git-dir="$d" config http.receivepack true &&
	git push --all "$HTTPD_URL"/smart/empty-all.git
'

test_expect_success 'push --mirror can push to empty repo' '
	d=$HTTPD_DOCUMENT_ROOT_PATH/empty-mirror.git &&
	git init --bare "$d" &&
	git --git-dir="$d" config http.receivepack true &&
	git push --mirror "$HTTPD_URL"/smart/empty-mirror.git
'

test_expect_success 'push --all to repo with alternates' '
	s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
	d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-all.git &&
	git clone --bare --shared "$s" "$d" &&
	git --git-dir="$d" config http.receivepack true &&
	git --git-dir="$d" repack -adl &&
	git push --all "$HTTPD_URL"/smart/alternates-all.git
'

test_expect_success 'push --mirror to repo with alternates' '
	s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
	d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-mirror.git &&
	git clone --bare --shared "$s" "$d" &&
	git --git-dir="$d" config http.receivepack true &&
	git --git-dir="$d" repack -adl &&
	git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
'

test_expect_success TTY 'push shows progress when stderr is a tty' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit noisy &&
	test_terminal git push >output 2>&1 &&
	test_i18ngrep "^Writing objects" output
'

test_expect_success TTY 'push --quiet silences status and progress' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit quiet &&
	test_terminal git push --quiet >output 2>&1 &&
	test_must_be_empty output
'

test_expect_success TTY 'push --no-progress silences progress but not status' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit no-progress &&
	test_terminal git push --no-progress >output 2>&1 &&
	test_i18ngrep "^To http" output &&
	test_i18ngrep ! "^Writing objects" output
'

test_expect_success 'push --progress shows progress to non-tty' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit progress &&
	git push --progress >output 2>&1 &&
	test_i18ngrep "^To http" output &&
	test_i18ngrep "^Writing objects" output
'

test_expect_success 'http push gives sane defaults to reflog' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit reflog-test &&
	git push "$HTTPD_URL"/smart/test_repo.git &&
	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
		log -g -1 --format="%gn <%ge>" >actual &&
	echo "anonymous <anonymous@http.127.0.0.1>" >expect &&
	test_cmp expect actual
'

test_expect_success 'http push respects GIT_COMMITTER_* in reflog' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_commit custom-reflog-test &&
	git push "$HTTPD_URL"/smart_custom_env/test_repo.git &&
	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
		log -g -1 --format="%gn <%ge>" >actual &&
	echo "Custom User <custom@example.com>" >expect &&
	test_cmp expect actual
'

test_expect_success 'push over smart http with auth' '
	cd "$ROOT_PATH/test_repo_clone" &&
	echo push-auth-test >expect &&
	test_commit push-auth-test &&
	set_askpass user@host pass@host &&
	git push "$HTTPD_URL"/auth/smart/test_repo.git &&
	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
		log -1 --format=%s >actual &&
	expect_askpass both user@host &&
	test_cmp expect actual
'

test_expect_success 'push to auth-only-for-push repo' '
	cd "$ROOT_PATH/test_repo_clone" &&
	echo push-half-auth >expect &&
	test_commit push-half-auth &&
	set_askpass user@host pass@host &&
	git push "$HTTPD_URL"/auth-push/smart/test_repo.git &&
	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
		log -1 --format=%s >actual &&
	expect_askpass both user@host &&
	test_cmp expect actual
'

test_expect_success 'create repo without http.receivepack set' '
	cd "$ROOT_PATH" &&
	git init half-auth &&
	(
		cd half-auth &&
		test_commit one
	) &&
	git clone --bare half-auth "$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git"
'

test_expect_success 'clone via half-auth-complete does not need password' '
	cd "$ROOT_PATH" &&
	set_askpass wrong &&
	git clone "$HTTPD_URL"/half-auth-complete/smart/half-auth.git \
		half-auth-clone &&
	expect_askpass none
'

test_expect_success 'push into half-auth-complete requires password' '
	cd "$ROOT_PATH/half-auth-clone" &&
	echo two >expect &&
	test_commit two &&
	set_askpass user@host pass@host &&
	git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
		log -1 --format=%s >actual &&
	expect_askpass both user@host &&
	test_cmp expect actual
'

test_expect_success CMDLINE_LIMIT 'push 2000 tags over http' '
	sha1=$(git rev-parse HEAD) &&
	test_seq 2000 |
	  sort |
	  sed "s|.*|$sha1 refs/tags/really-long-tag-name-&|" \
	  >.git/packed-refs &&
	run_with_limited_cmdline git push --mirror
'

test_expect_success GPG 'push with post-receive to inspect certificate' '
	(
		cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git &&
		mkdir -p hooks &&
		write_script hooks/post-receive <<-\EOF &&
		# discard the update list
		cat >/dev/null
		# record the push certificate
		if test -n "${GIT_PUSH_CERT-}"
		then
			git cat-file blob $GIT_PUSH_CERT >../push-cert
		fi &&
		cat >../push-cert-status <<E_O_F
		SIGNER=${GIT_PUSH_CERT_SIGNER-nobody}
		KEY=${GIT_PUSH_CERT_KEY-nokey}
		STATUS=${GIT_PUSH_CERT_STATUS-nostatus}
		NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}
		NONCE=${GIT_PUSH_CERT_NONCE-nononce}
		E_O_F
		EOF

		git config receive.certnonceseed sekrit &&
		git config receive.certnonceslop 30
	) &&
	cd "$ROOT_PATH/test_repo_clone" &&
	test_commit cert-test &&
	git push --signed "$HTTPD_URL/smart/test_repo.git" &&
	(
		cd "$HTTPD_DOCUMENT_ROOT_PATH" &&
		cat <<-\EOF &&
		SIGNER=C O Mitter <committer@example.com>
		KEY=13B6F51ECDDE430D
		STATUS=G
		NONCE_STATUS=OK
		EOF
		sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" push-cert
	) >expect &&
	test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH/push-cert-status"
'

test_expect_success 'push status output scrubs password' '
	cd "$ROOT_PATH/test_repo_clone" &&
	git push --porcelain \
		"$HTTPD_URL_USER_PASS/smart/test_repo.git" \
		+HEAD:scrub >status &&
	# should have been scrubbed down to vanilla URL
	grep "^To $HTTPD_URL/smart/test_repo.git" status
'

test_expect_success 'colorize errors/hints' '
	cd "$ROOT_PATH"/test_repo_clone &&
	test_must_fail git -c color.transport=always -c color.advice=always \
		-c color.push=always \
		push origin origin/master^:master 2>act &&
	test_decode_color <act >decoded &&
	test_i18ngrep "<RED>.*rejected.*<RESET>" decoded &&
	test_i18ngrep "<RED>error: failed to push some refs" decoded &&
	test_i18ngrep "<YELLOW>hint: " decoded &&
	test_i18ngrep ! "^hint: " decoded
'

test_done


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Mucor exitosus Massee

### Remarks
null

redpajama_set_name: RedPajamaGithub


text:
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var utils = require("tsutils");
var ts = require("typescript");
var Lint = require("../index");
var Rule = (function (_super) {
    __extends(Rule, _super);
    function Rule() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    /* tslint:enable:object-literal-sort-keys */
    Rule.FAILURE_STRING_FACTORY = function (allowed) {
        return allowed === 1
            ? "Consecutive blank lines are forbidden"
            : "Exceeds the " + allowed + " allowed consecutive blank lines";
    };
    /**
     * Disable the rule if the option is provided but non-numeric or less than the minimum.
     */
    Rule.prototype.isEnabled = function () {
        return _super.prototype.isEnabled.call(this) &&
            (!this.ruleArguments[0] ||
                typeof this.ruleArguments[0] === "number" && this.ruleArguments[0] > 0);
    };
    Rule.prototype.apply = function (sourceFile) {
        var limit = this.ruleArguments[0] || Rule.DEFAULT_ALLOWED_BLANKS;
        return this.applyWithFunction(sourceFile, walk, limit);
    };
    return Rule;
}(Lint.Rules.AbstractRule));
Rule.DEFAULT_ALLOWED_BLANKS = 1;
/* tslint:disable:object-literal-sort-keys */
Rule.metadata = {
    ruleName: "no-consecutive-blank-lines",
    description: "Disallows one or more blank lines in a row.",
    hasFix: true,
    rationale: "Helps maintain a readable style in your codebase.",
    optionsDescription: (_a = ["\n            An optional number of maximum allowed sequential blanks can be specified. If no value\n            is provided, a default of $(Rule.DEFAULT_ALLOWED_BLANKS) will be used."], _a.raw = ["\n            An optional number of maximum allowed sequential blanks can be specified. If no value\n            is provided, a default of $(Rule.DEFAULT_ALLOWED_BLANKS) will be used."], Lint.Utils.dedent(_a)),
    options: {
        type: "number",
        minimum: "$(Rule.MINIMUM_ALLOWED_BLANKS)",
    },
    optionExamples: ["true", "[true, 2]"],
    type: "style",
    typescriptOnly: false,
};
exports.Rule = Rule;
function walk(ctx) {
    var sourceText = ctx.sourceFile.text;
    var threshold = ctx.options + 1;
    var possibleFailures = [];
    var consecutiveBlankLines = 0;
    for (var _i = 0, _a = utils.getLineRanges(ctx.sourceFile); _i < _a.length; _i++) {
        var line = _a[_i];
        if (sourceText.substring(line.pos, line.end).search(/\S/) === -1) {
            ++consecutiveBlankLines;
            if (consecutiveBlankLines === threshold) {
                possibleFailures.push({
                    end: line.end,
                    pos: line.pos,
                });
            }
            else if (consecutiveBlankLines > threshold) {
                possibleFailures[possibleFailures.length - 1].end = line.end;
            }
        }
        else {
            consecutiveBlankLines = 0;
        }
    }
    if (possibleFailures.length === 0) {
        return;
    }
    var failureString = Rule.FAILURE_STRING_FACTORY(ctx.options);
    var templateRanges = getTemplateRanges(ctx.sourceFile);
    var _loop_1 = function (possibleFailure) {
        if (!templateRanges.some(function (template) { return template.pos < possibleFailure.pos && possibleFailure.pos < template.end; })) {
            ctx.addFailureAt(possibleFailure.pos, 1, failureString, ctx.createFix(Lint.Replacement.deleteFromTo(
            // special handling for fixing blank lines at the end of the file
            // to fix this we need to cut off the line break of the last allowed blank line, too
            possibleFailure.end === sourceText.length ? getStartOfLineBreak(sourceText, possibleFailure.pos) : possibleFailure.pos, possibleFailure.end)));
        }
    };
    for (var _b = 0, possibleFailures_1 = possibleFailures; _b < possibleFailures_1.length; _b++) {
        var possibleFailure = possibleFailures_1[_b];
        _loop_1(possibleFailure);
    }
}
function getStartOfLineBreak(sourceText, pos) {
    return sourceText[pos - 2] === "\r" ? pos - 1 : pos - 1;
}
function getTemplateRanges(sourceFile) {
    var intervals = [];
    var cb = function (node) {
        if (node.kind >= ts.SyntaxKind.FirstTemplateToken &&
            node.kind <= ts.SyntaxKind.LastTemplateToken) {
            intervals.push({
                end: node.end,
                pos: node.getStart(sourceFile),
            });
        }
        else {
            return ts.forEachChild(node, cb);
        }
    };
    ts.forEachChild(sourceFile, cb);
    return intervals;
}
var _a;


text:
class Setting < ActiveRecord::Base

  validates :name, :presence => true
  validates :name, :uniqueness => true

end


text:
using System;
namespace MyFirstBatchApplicationCore.Business
{
    /// <summary>
    /// FlatFileRecord : business object to store the
    /// read records from the flat file
    /// </summary>
    [Serializable]
    public class FlatFileRecord
    {
        /// <summary>
        /// Property Code.
        /// </summary>
        public int? Code { get; set; }
        /// <summary>
        /// Property Name.
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Property Description.
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// Property Date.
        /// </summary>
        public DateTime? Date { get; set; }
    }
}


text:
import qisrc.svn

def test_commit_all_adds_new_subfolders(svn_server, tmpdir):
    foo_url = svn_server.create_repo("foo")
    work = tmpdir.mkdir("work")
    foo = work.mkdir("foo")
    svn = qisrc.svn.Svn(foo.strpath)
    svn.call("checkout", foo_url, ".")
    foo.ensure("some/sub/folder", dir=True)
    foo.ensure("some/sub/folder/bar.txt")
    svn.commit_all("test message")
    work2 = tmpdir.mkdir("work2")
    foo2 = work2.mkdir("foo2")
    svn = qisrc.svn.Svn(foo2.strpath)
    svn.call("checkout", foo_url, ".")
    assert foo2.join("some", "sub", "folder").check(dir=True)
    assert foo2.join("some", "sub", "folder", "bar.txt").check(file=True)

def test_commit_all_removes_removed_files(svn_server, tmpdir):
    foo_url = svn_server.create_repo("foo")
    svn_server.commit_file("foo", "bar.txt", "this is bar")
    work = tmpdir.mkdir("work")
    foo = work.mkdir("foo")
    svn = qisrc.svn.Svn(foo.strpath)
    svn.call("checkout", foo_url, ".")
    foo.join("bar.txt").remove()
    svn.commit_all("test message")
    work2 = tmpdir.mkdir("work2")
    foo2 = work2.mkdir("foo2")
    svn = qisrc.svn.Svn(foo2.strpath)
    svn.call("checkout", foo_url, ".")
    assert not foo2.join("bar.txt").check(file=True)

def test_files_with_space(svn_server, tmpdir):
    foo_url = svn_server.create_repo("foo")
    svn_server.commit_file("foo", "file with space.txt", "some contents\n")
    work = tmpdir.mkdir("work")
    foo = work.mkdir("foo")
    svn = qisrc.svn.Svn(foo.strpath)
    svn.call("checkout", foo_url, ".")
    foo.join("file with space.txt").remove()
    svn.commit_all("test message")


text:
{% extends "tethys_portal/user/profile.html" %}

{% load django_bootstrap5 %}

{% block edit_button %}
Back
{% endblock %}

{% block title %}{{ block.super }} - User Settings{% endblock %}

{% block styles %}
  {{ block.super }}
  {{ tethys.datatables_bs5.link_tag|safe }}
{% endblock %}

{% block profile_sections %}

          App Name
          Current Usage
          Manage Storage

        {% for app in apps %}

            {{ app.name }}

          {{ app.current_use }}

            Clear Workspace

        {% endfor %}

      Storage Summary:
      {{ current_use }} of {{ quota|default:"∞" }}

{% endblock %}

{% block global_scripts %}
  {{ block.super }}
  {{ tethys.datatables.script_tag|safe }}
  {{ tethys.datatables_bs5.script_tag|safe }}
{% endblock %}

{% block scripts %}
  {{ block.super }}

{% endblock %}


text:
'use strict';

const _ = require('lodash');
const expect = require('chai').expect;
const crudSwagger = require('../lib').swagger;

describe('swagger docs', ()=> {

  let options;

  beforeEach(()=> {
    options = {
      entity: {
        name: 'my-entity'
      }
    };
  });

  it('should generate tags', ()=> {
    const docs = crudSwagger(options).docs;
    expect(docs.tags).to.deep.equal([{ name: 'my-entity', description: 'my-entity' }]);
  });

  ['read', 'write'].forEach(action => {
    it('should generate ' + action + ' tags', ()=> {
      options.tag = {};
      options.tag[action] = { name: 'my-entity-admin', description: 'my-entity administration' };
      const docs = crudSwagger(options).docs;
      expect(docs.tags.length).to.equal(2);
      expect(_.filter(docs.tags, tag => tag.name === 'my-entity-admin')[0]).to.deep.equal(options.tag[action]);
    });
  });

  it('should generate read and write tags', ()=> {
    options.tag = {
      read: { name: 'my-entity-read', description: 'my-entity read' },
      write: { name: 'my-entity-write', description: 'my-entity write' },
    };
    const docs = crudSwagger(options).docs;
    expect(docs.tags.length).to.equal(3);
    ['my-entity','my-entity-read','my-entity-write'].forEach(name => {
      expect(_.filter(docs.tags, tag => tag.name === name).length).to.equal(1);
    });
  });

  ['post','put'].forEach(method => {
    it('should generate docs for ' + method + ' /my-entity', ()=> {
      const docs = crudSwagger(options).docs;
      expect(!!docs.paths['/my-entity'][method]).to.equal(true);
    });
  });

  ['get','delete'].forEach(method => {
    it('should generate docs for ' + method + ' /my-entity/{_id}', ()=> {
      const docs = crudSwagger(options).docs;
      expect(!!docs.paths['/my-entity/{_id}'][method]).to.equal(true);
    });
  });

  ['', '-creating', '-updating', '-finding', '-count'].forEach(suffix => {
    it('should generate definitions for my-entity' + suffix, () => {
      const docs = crudSwagger(options).docs;
      expect(!!docs.definitions['my-entity' + suffix]).to.equal(true);
    });
  });

  ['validation-errors', 'system-error'].forEach(error => {
    it('should include definitions for ' + error, () => {
      const docs = crudSwagger(options).docs;
      expect(!!docs.definitions[error]).to.equal(true);
    });
  });

  ['skip', 'limit'].forEach(control => {
    it('should include the ' + control + ' property in the default find conditions', () => {
      const docs = crudSwagger(options).docs;
      expect(!!docs.definitions['my-entity-finding'].properties[control]).to.equal(true);
    });
  });

  ['get','delete'].forEach(method => {
    it('should allow a different path parameter name for the ' + method + ' operation', ()=> {
      options.reqParamId = 'key';
      const docs = crudSwagger(options).docs;
      expect(!!docs.paths['/my-entity/{key}'][method]).to.equal(true);
    });
  });

  it('should allow a path prefix for the read operations', ()=> {
    options.pathPrefix = { read: '/public' };
    const docs = crudSwagger(options).docs;
    expect(!!docs.paths['/public/my-entity/find'].post).to.equal(true);
    expect(!!docs.paths['/public/my-entity/{_id}'].get).to.equal(true);
  });

  it('should allow a path prefix for the write operations', ()=> {
    options.pathPrefix = { write: '/admin' };
    const docs = crudSwagger(options).docs;
    expect(!!docs.paths['/admin/my-entity'].post).to.equal(true);
    expect(!!docs.paths['/admin/my-entity'].put).to.equal(true);
    expect(!!docs.paths['/admin/my-entity/{_id}'].delete).to.equal(true);
  });

  it('should allow specification of the entity schema', () => {
    options.entity.schema = {
      type: 'object',
      description: 'My entity',
      properties: {
        _id: {
          type: 'string',
          description: 'Unique identifier for my entity'
        },
        myProperty: {
          type: 'string',
          description: 'My property'
        }
      }
    };
    const docs = crudSwagger(options).docs;
    expect(docs.definitions['my-entity']).to.deep.equal(options.entity.schema);
  });

  it('should allow search controls to be specified in the querystring', () => {
    options.useControlsFromQuery = true;
    const docs = crudSwagger(options).docs;
    const parameters = docs.paths['/my-entity/find'].post.parameters;
    expect(parameters.filter(param => param.in === 'query').length).to.equal(2);
  });

  it('should expose the configured options', ()=> {
    expect(!!crudSwagger(options).options).to.equal(true);
  });

  describe('getOperation', () => {

    let cs, defaultValues;
    beforeEach(() => {
      cs = crudSwagger(options);
      defaultValues = {
        tags: ['my-entity'],
        summary: 'my-entity',
        description: 'my-entity',
        parameters: undefined,
        responses: cs.options.getResponses({ entityName: 'my-entity' })
      };
    });

    it('should allow getOperation to be called with no arguments', () => {
      expect(cs.getOperation()).to.deep.equal(defaultValues);
    });

    it('should allow tags to be overridden', () => {
      const tags = ['my-entity', 'my-other-tag'];
      expect(cs.getOperation({ tags })).to.deep.equal(Object.assign(defaultValues, { tags }));
    });

    it('should allow summary to be overridden', () => {
      const summary = 'something else';
      expect(cs.getOperation({ summary })).to.deep.equal(Object.assign(defaultValues, { summary, description: summary }));
    });

    it('should allow description to be overridden', () => {
      const description = 'something else';
      expect(cs.getOperation({ description })).to.deep.equal(Object.assign(defaultValues, { description }));
    });

    it('should allow parameters to be overridden', () => {
      const parameters = [{ name: 'Options',  in: 'body',  schema: { $ref: '#/definitions/overriding-my-thing' } }];
      expect(cs.getOperation({ parameters })).to.deep.equal(Object.assign(defaultValues, { parameters }));
    });

    it('should allow responses to be overridden', () => {
      const responses = cs.options.getResponses({ exclude: '404' });
      expect(cs.getOperation({ responses })).to.deep.equal(Object.assign(defaultValues, { responses }));
    });
  });

});


text:
angular.module('observationManager.observation').controller('omScopesController', [
    '$scope', 'omScopeManager',
    function ($scope, omScopeManager) {
        'use strict';

        $scope.isLoading = true;
        omScopeManager.getAllScopes().then(function (scopes) {
            $scope.isLoading = true;
            $scope.scopes = scopes;
        });

    }
]);


text:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using TUM.CMS.VplControl.Annotations;

namespace TUM.CMS.VplControl.Core
{
    public class BindingPoint : INotifyPropertyChanged
    {
        private Point point;

        public BindingPoint(double x, double y)
        {
            point = new Point(x, y);
        }

        public double X
        {
            get { return point.X; }
            set
            {
                point.X = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }

        public double Y
        {
            get { return point.Y; }
            set
            {
                point.Y = value;
                OnPropertyChanged();
                OnPropertyChanged("Point");
            }
        }

        public Point Point
        {
            get { return point; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}


text:
<?php
namespace Chamilo\Libraries\Protocol\Webservice\Rest\Client\Result;

use Chamilo\Libraries\Protocol\Webservice\Rest\Client\RestResult;

class Json extends RestResult
{

    /**
     *
     * @return stdClass
     */
    public function get_response_content($parse = true)
    {
        if ($parse)
        {
            return json_decode(parent::get_response_content(false));
        }
        else
        {
            parent::get_response_content(false);
        }
    }
}


text:
@interface NSDictionary (SAGExtensions)
- (NSString *) sag_safeStringForKey:(NSString *) key;
- (NSNumber *) sag_safeNumberForKey:(NSString *) key;
- (NSArray *) sag_safeArrayForKey:(NSString *) key;
- (NSDictionary *) sag_safeDictionaryForKey:(NSString *) key;
@end


text:
curl-cmd
========

Generate a curl command line argument list from an http request object

Install
-------

    npm install curl-cmd

Example
-------

Taken from the [Node.JS](http://nodejs.org) example for an HTTP get request

``` js
var http = require('http');
var curl = require('curl-cmd');

var options = {
  hostname: 'ifconfig.me',
  port: 80,
  path: '/ip',
  method: 'GET'
};

console.log('=> %s', curl.cmd(options));

http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
}).end();
```

The line `curl.cmd(options)` is the interesting part as that will generate
the curl command seen in the output

```
=> curl -X GET http://ifconfig.me:80/ip
STATUS: 200
HEADERS: {"date":"Thu, 06 Jun 2013 16:56:30 GMT","server":"Apache","vary":"Accept-Encoding","connection":"close","transfer-encoding":"chunked","content-type":"text/plain"}
BODY: 8.8.8.8
```

### Simple Example

``` js
> var curl = require('curl-cmd')
undefined

> curl.cmd('http://www.daveeddy.com/something')
'curl -X GET http://www.daveeddy.com/something'

> curl.cmd({host: 'daveeddy.com', port: 8080, method: 'DELETE', path: '/data/something'})
'curl -X DELETE http://daveeddy.com:8080/data/something'

> curl.cmd({host: 'daveeddy.com', port: 8080, method: 'DELETE', path: '/data/something', headers: { 'User-Agent': 'Internet Explorer'} })
'curl -X DELETE -H \'User-Agent: Internet Explorer\' http://daveeddy.com:8080/data/something'

> curl.cmd({host: 'daveeddy.com', port: 8080, method: 'DELETE', path: '/data/something', headers: { 'User-Agent': 'Internet Explorer'}, auth: 'dave:secret' })
'curl -X DELETE -u dave:secret -H \'User-Agent: Internet Explorer\' http://daveeddy.com:8080/data/something'

> curl.cmd({host: 'daveeddy.com', port: 8080, method: 'PUT', path: '/data/something', headers: { 'User-Agent': 'Internet Explorer'}, auth: 'dave:secret' }, {ssl: true, verbose: true})
'curl -X PUT -u dave:secret -H \'User-Agent: Internet Explorer\' -v https://daveeddy.com:8080/data/something'
```
Usage
-----

Pass in a URI as a string, a `url.parsed()` object, or an object suitable for
making an HTTP request as the first argument to get the curl command.

### `curl.cmd(options, curlopts={})`

This returns a stringified curl command suitable for running on the shell

### `curl.args(options, curlopts={})`

Same as above, except returns an array of separate arguments to use for the curl command

### `curlopts`

The optional second argument is used to pass options to curl

- `curlopts.ssl`: set to `true` to use HTTPS instead of HTTP, defaults to `false`
- `curlopts.verbose`: set to `true` to add `-v` to the curl command, defaults to `false`
- `curlopts.headers`: set to `true` to add `-i` to the curl command, defaults to `false`
- `curlopts.options`: an optional array of arguments to add to the curl command, defaults to `[]`

License
-------

MIT


text:
#ifndef VMTASKPANEL_H
#define VMTASKPANEL_H

#include "vmlist.h"

#include <QFrame>

class ActionPanelScheme;
class vmActionGroup;
class vmActionLabel;

class QVBoxLayout;

class vmTaskPanel : public QFrame
{

public:
	explicit vmTaskPanel ( const QString& title = nullptr, QWidget* parent = nullptr );
	virtual ~vmTaskPanel ();

	void setTitle ( const QString& new_title );
	/** Adds a widget \a w to the vmTaskPanel's vertical layout.
	  */
	void addWidget ( QWidget* w );

	/** Adds a spacer with width \a s to the vmTaskPanel's vertical layout.
		Normally you should do this after all the vmActionGroups were added, in order to
		maintain some space below.
	  */
	void addStretch ( const int s = 0 );

	/** Creates and adds to the vmTaskPanel's vertical layout an empty vmActionGroup with header's
		text set to \a title, but with no icon.

		If \a expandable set to \a true (default), the group can be expanded/collapsed by the user.
	  */
	vmActionGroup* createGroup ( const QString& title,
								 const bool expandable = true,
								 const bool stretchContents = true,
								 const bool closable = false );

	/** Creates and adds to the vmTaskPanel's vertical layout an empty vmActionGroup with header's
		text set to \a title and icon set to \a icon.

		If \a expandable set to \a true (default), the group can be expanded/collapsed by the user.
	  */
	vmActionGroup* createGroup (const QIcon& icon,
								 const QString& title,
								 const bool expandable = true,
								 const bool stretchContents = true,
								 const bool closable = false );

	void removeGroup ( vmActionGroup* group, const bool bDelete = false );

	/** Sets the scheme of the panel and all the child groups to \a scheme.

		By default, vmTaskPanelScheme::defaultScheme() is used.
	  */
	void setScheme ( const QString& style );

	QSize minimumSizeHint () const;

protected:
	ActionPanelScheme* mScheme;
	vmActionLabel* mTitle;
	QVBoxLayout* mLayout;

private:
	PointersList<vmActionGroup*> mGroups;
};

#endif // VMTASKPANEL_H


text: Log files from running $GS_HOME/bin/todeClient script


text:
import curry from './curry'

// + apply :: ([a] -> b?, [a]) -> b?
export default curry((fn, args) => fn.apply(null, args))


text:
from views import app

app.run(debug=True)


text:
/**
 * @file
 * SimpleMemory declaration
 */

#ifndef __SIMPLE_MEMORY_HH__
#define __SIMPLE_MEMORY_HH__

#include <list>

#include "mem/abstract_mem.hh"
#include "mem/port.hh"
#include "params/SimpleMemory.hh"

/**
 * The simple memory is a basic single-ported memory controller with
 * a configurable throughput and latency.
 *
 * @sa  \ref gem5MemorySystem "gem5 Memory System"
 */
class SimpleMemory : public AbstractMemory
{

  private:

    /**
     * A deferred packet stores a packet along with its scheduled
     * transmission time
     */
    class DeferredPacket
    {

      public:

        const Tick tick;
        const PacketPtr pkt;

        DeferredPacket(PacketPtr _pkt, Tick _tick) : tick(_tick), pkt(_pkt)
        { }
    };

    class MemoryPort : public SlavePort
    {

      private:

        SimpleMemory& memory;

      public:

        MemoryPort(const std::string& _name, SimpleMemory& _memory);

      protected:

        Tick recvAtomic(PacketPtr pkt);

        void recvFunctional(PacketPtr pkt);

        bool recvTimingReq(PacketPtr pkt);

        void recvRespRetry();

        AddrRangeList getAddrRanges() const;

    };

    MemoryPort port;

    /**
     * Latency from that a request is accepted until the response is
     * ready to be sent.
     */
    const Tick latency;

    /**
     * Fudge factor added to the latency.
     */
    const Tick latency_var;

    /**
     * Internal (unbounded) storage to mimic the delay caused by the
     * actual memory access. Note that this is where the packet spends
     * the memory latency.
     */
    std::list<DeferredPacket> packetQueue;

    /**
     * Bandwidth in ticks per byte. The regulation affects the
     * acceptance rate of requests and the queueing takes place after
     * the regulation.
     */
    const double bandwidth;

    /**
     * Track the state of the memory as either idle or busy, no need
     * for an enum with only two states.
     */
    bool isBusy;

    /**
     * Remember if we have to retry an outstanding request that
     * arrived while we were busy.
     */
    bool retryReq;

    /**
     * Remember if we failed to send a response and are awaiting a
     * retry. This is only used as a check.
     */
    bool retryResp;

    /**
     * Release the memory after being busy and send a retry if a
     * request was rejected in the meanwhile.
     */
    void release();

    EventWrapper<SimpleMemory, &SimpleMemory::release> releaseEvent;

    /**
     * Dequeue a packet from our internal packet queue and move it to
     * the port where it will be sent as soon as possible.
     */
    void dequeue();

    EventWrapper<SimpleMemory, &SimpleMemory::dequeue> dequeueEvent;

    /**
     * Detemine the latency.
     *
     * @return the latency seen by the current packet
     */
    Tick getLatency() const;

    /**
     * Upstream caches need this packet until true is returned, so
     * hold it for deletion until a subsequent call
     */
    std::unique_ptr<Packet> pendingDelete;

  public:

    SimpleMemory(const SimpleMemoryParams *p);

    DrainState drain() override;

    BaseSlavePort& getSlavePort(const std::string& if_name,
                                PortID idx = InvalidPortID) override;
    void init() override;

  protected:

    Tick recvAtomic(PacketPtr pkt);

    void recvFunctional(PacketPtr pkt);

    bool recvTimingReq(PacketPtr pkt);

    void recvRespRetry();

};

#endif //__SIMPLE_MEMORY_HH__


text:
---
layout: post
title: Enabling client caching of dynamic content
date: '2009-09-19T19:31:00.001+02:00'
author: Dave Van den Eynde
tags:
modified_time: '2009-09-19T19:31:18.811+02:00'
blogger_id: tag:blogger.com,1999:blog-10546079.post-2332080078256537402
blogger_orig_url: http://www.groovbird.com/2009/09/enabling-client-caching-of-dynamic.html
---

In my last post, I was explaining how I wanted to return pictures from my ASP.NET MVC based application. In short, this is what I did:

[ReplaceMissingPicture(Picture = "~/Content/Images/nopicture.png", MimeType = "image/png")]
public ActionResult Picture(int id)
{
    var item = Service.GetItem(id);

    if (item.Picture != null)
    {
        var picture = item.Picture.ToArray();
        var mime = item.PictureMime;

        return File(picture, mime);
    }
    else
    {
        return null;
    }
}

Please see my last post for more information about what you see here.

This is all nice, but there's a problem. Every time the client requests our "Picture" action method, the picture is returned with a HTTP status code 200. This is what you normally want, but my concern is that this happens every time. If this were a static file hosted by the web server, the web server would be smart enough to return an HTTP status code 304, meaning that the requested resource didn't change since the last time it was requested.

How does this work? That's relatively simple. When the resource is first requested, and the picture is returned, the web application should add a header to the HTTP response named "Etag". This header contains a string that represents the "version" of the resource. This can really be anything.

When the client requests the same resource again, and the client has a cached copy of the resource, it sends a request containing an extra header named "If-None-Match", meaning that if the resource still matches this version, it should return HTTP 304 and no content.

So how do we implement this?

For the version  information, I chose to place a timestamp column in the table containing the picture, and an associated property in the LINQ to SQL business object. The timestamp column type is not related to dates and times. It's just a value that you can check for if you want to know if the record has changed in any way since you last read it. Which is perfect for this example.

So the first thing we need to do is send the version to the client. In order to keep this testable, I decided to implement it in a way that closely resembles this answer to my question on Stack Overflow. First of all, we need an interface that we can call from our Action method that deals with adding the tag and checking for it. This should do fine:

public interface ITagService
{
    string GetRequestTag();
    void SetResponseTag(string value);
}

When we add a property of this interface to our controller and initialize it in the constructor, we can decide what kind of implementation we use at runtime (whether that is the application hosted in IIS, or during testing). So we can use a mock for testing, and we can use the following class in IIS:

public class HttpTagService : ITagService
{
    public string GetRequestTag()
    {
        return HttpContext.Current.Request.Headers["If-None-Match"];
    }

    public void SetResponseTag(string value)
    {
        HttpContext.Current.Response.AppendHeader("ETag", value);
    }
}

So now our Picture action method looks like this:

[ReplaceMissingPicture(Picture = "~/Content/Images/nopicture.png", MimeType = "image/png")]
public ActionResult Picture(int id)
{
    var item = Service.GetItem(id);

    var responseTag = item.Version != null ?
        Convert.ToBase64String(item.Version.ToArray()) :
        string.Empty;

    if (item.Picture != null)
    {
        var picture = item.Picture.ToArray();
        var mime = item.PictureMime;

        TagService.SetResponseTag(responseTag);

        return File(picture, mime);
    }
    else
    {
        return null;
    }
}

A simple ToBase64String() from our version column (which is mapped to a Binary object) should do just fine.

Before we go into how we'll check for the tag (which is pretty trivial) we also need to know how to return the actual HTTP 304 status. The following needs to happen:

Response.SuppressContent must be set to true.

Response.StatusCode needs to be set to 304.

Response.StatusDescription needs a description.

Response needs a header "Content-Length" set to "0".

This last one is important, as it will allow the client to keep the connection open for the next request while not expecting any more output from the current request.

In order to keep this testable, I chose to create a custom ActionResult called NotModifiedResult. Here's the implementation:

public class NotModifiedResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;

        response.SuppressContent = true;
        response.StatusCode = 304;
        response.StatusDescription = "Not Modified";
        response.AddHeader("Content-Length", "0");
    }
}

This is exactly what we need, and ASP.NET MVC makes it easy again to keep this all neat and tidy. Our tests can simply check for the type of result returned, and ExecuteResult() never needs to be executed in a test environment.

So finally, our Picture action method looks like this:

[ReplaceMissingPicture(Picture = "~/Content/Images/nopicture.png", MimeType = "image/png")]
public ActionResult Picture(int id)
{
    var item = Service.GetItem(id);

    var requestTag = TagService.GetRequestTag() ?? string.Empty;
    var responseTag = item.Version != null ?
        Convert.ToBase64String(item.Version.ToArray()) :
        string.Empty;

    if (responseTag == requestTag)
    {
        return new NotModifiedResult();
    }

    if (item.Picture != null)
    {
        var picture = item.Picture.ToArray();
        var mime = item.PictureMime;

        TagService.SetResponseTag(responseTag);

        return File(picture, mime);
    }
    else
    {
        return null;
    }
}

I'm sure this doesn't need any explanation.

Two more things I'd like to mention. First of all, I decided to turn the Picture column into a delay loaded column by setting its Delay Loaded property to true in the LINQ to SQL designer. This way, when the table is queried, the column is not selected by default. Only when you access the picture column a new query is started specifically for the picture. This way, when you don't need the picture (like in a table overview of the business objects) it's not queried for and retrieved from the database. Also, this means that our action method requires two queries: one for the Item and one for the Picture column. Except that in the case of a client cached picture, the second query doesn't need to be executed.

Second, I want you to know that this technique here doesn't just apply to pictures, it applies to any sort of content that can be accessed as a resource. If the client can cache it, you can enable the web application to support that caching method.

Now all I need to do, is apply the same to my ReplaceMissingPicture filter that I talked about last time.


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Configuration;
using System.Data.SqlClient;
using Bets.Data.Models;
using System.IO;
using System.Text;
using System.Web.Mvc;
using System.Diagnostics;

namespace Bets.Data
{
	public enum SqlExceptionCode { PrimaryKeyViolation = 2627, Deadlock = 1205, UniqueKeyViolation = 2601 };

	/// <summary>
	/// A generic repository for working with data in the database
	/// </summary>
	/// <typeparam name="TEntity">A POCO that represents an Entity Framework entity</typeparam>
    /// <typeparam name="M">Model</typeparam>
	public class Repository<TEntity, M> : IRepository<TEntity, M> where TEntity : class where M : Model
	{
		private int saveRetryCount = 0;
		private static int MAX_RETRY_COUNT = 5;

		public int UserID { get; set; }
		public bool IsAdmin { get; set; }
		//logs queries generated by Linq2SQL
		private StringBuilder logger = new StringBuilder();

		/// <summary>
		/// The context object for the database
		/// </summary>
		public BetsDataContext Context { get; set; }

		#region "Virtual"

		public virtual M GetItem(string id, M model)
		{
			return this.GetItem(Convert.ToInt32(id), model);
		}

		public virtual M GetItem(int id, M model)
		{
			return this.GetItem(id.ToString());
		}

		public virtual M GetItem(string id)
		{
			return this.GetItem(Convert.ToInt32(id));
		}

		public virtual M GetItem(int id)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Returns data for listing
		/// </summary>
		public virtual IQueryable<IModel> GetListingItems(ListingParams<M> listingDataModel)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Returns listing data for lookup
		/// </summary>
		public virtual IQueryable<IModel> GetLookupItems(ListingParams<M> listingDataModel)
		{
			throw new NotImplementedException();
		}

		public virtual ActionStatus SaveItem(M model, DBActionType action)
		{
			throw new NotImplementedException();
		}

		public virtual ActionStatus DeleteItem(M model)
		{
			throw new NotImplementedException();
		}

		#endregion

		public Repository()
		{
            if (DataConfig.IsLiveMode())
            {
                this.Context = this.GetDataContext();
            }
            else
            {
                //profile sql queries
                SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["Bets"].ConnectionString);

                // wrap the connection with a profiling connection that tracks timings
                this.Context = new BetsDataContext(sqlConn);
            }

            if (DataConfig.EnableTracing())
            {
                this.Context.Log = new TextToTraceWriter { Category = "DatabaseQuery" };
            }
            this.Context.CommandTimeout = Convert.ToInt32(ConfigurationManager.AppSettings["CommandTimeout"]);
		}

		public Repository(int userID) : this()
		{
			this.UserID = userID;
		}

		public Repository(Repository<TEntity, M> repo)
		{
			this.Context = repo.Context;
			this.UserID = repo.UserID;
			this.IsAdmin = repo.IsAdmin;
		}

		public Repository(BetsDataContext context, int? userID = null)
		{
			this.Context = context;

			if (userID != null)
				this.UserID = userID.Value;
		}

		public BetsDataContext GetDataContext()
		{
			return new BetsDataContext(ConfigurationManager.ConnectionStrings["Bets"].ConnectionString);
		}

		/// <summary>
		/// Gets all records as an IQueryable
		/// </summary>
		/// <returns>An IQueryable object containing the results of the query</returns>
		public IQueryable<TEntity> GetQuery()
		{
			return this.Context.GetTable<TEntity>();
		}

		/// <summary>
		/// Gets all records as an IQueryable
		/// </summary>
		/// <returns>An IEnumberable object containing the results of the query</returns>
		public IQueryable<TEntity> GetAll()
		{
			return GetQuery().AsQueryable();
		}

		public bool DeleteWithAttach(TEntity entity, bool save = true)
		{
			this.Context.GetTable<TEntity>().Attach(entity);
			this.Context.GetTable<TEntity>().DeleteOnSubmit(entity);

			if (save)
				return (this.Save() == StoredProcResult.Success);

			return true;
		}

		/// <summary>
		/// Adds the specified entity
		/// </summary>
		/// <param name="entity">Entity to add</param>
        /// <param name="save">Whethere to save changes</param>
		public bool Add(TEntity entity, bool save = false)
		{
			this.Context.GetTable<TEntity>().InsertOnSubmit(entity);

			if (save)
				return (this.Save() == StoredProcResult.Success);
			else
				return true;
		}

		/// <summary>
		/// Attaches the specified entity
		/// </summary>
		/// <param name="entity">Entity to attach</param>
		public void Attach<T>(T entity) where T : class
		{
			this.Context.GetTable<T>().Attach(entity);
			this.Context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, entity);
		}

		public void Attach(TEntity entity)
		{
			this.Attach<TEntity>(entity);
		}

		public bool Update(TEntity entity, Action<TEntity> action, bool save = true)
		{
			this.Attach<TEntity>(entity);

			if (action != null)
				action.Invoke(entity);

			if (save)
				return (this.Save() == StoredProcResult.Success);
			return true;
		}

		public bool SaveContext()
		{
			return this.Save() == StoredProcResult.Success;
		}

		///<summary>Saves all context changes</summary>
		public StoredProcResult Save()
		{
			try
			{
				this.Context.SubmitChanges();
			}
			//handle primary key violation by removing already existing records and trying to insert the other models
			//so that if there are multiple models received, the correct ones will still be added to database
			catch (System.Data.SqlClient.SqlException sqlEx)
			{
				SqlExceptionCode exceptionCode = (SqlExceptionCode)Enum.ToObject(typeof(SqlExceptionCode), sqlEx.Number);

				switch (exceptionCode)
				{
					case SqlExceptionCode.Deadlock:
					{
						//avoid infinite recursion if retry count has reached limit
						if (saveRetryCount >= MAX_RETRY_COUNT)
							return StoredProcResult.Error;

						System.Threading.Thread.Sleep(500);
						saveRetryCount++;

                        Logger.Log(sqlEx);

						return this.Save();
					}

					default:
					{
						Logger.Log(sqlEx);
						return StoredProcResult.Error;
					}
				}
			}
			//handle concurrency exceptions
			catch (ChangeConflictException changeConflictEx)
			{
				//avoid infinite recursion if retry count has reached limit
				if (saveRetryCount >= MAX_RETRY_COUNT)
					return StoredProcResult.ErrChanged;

                Logger.Log(changeConflictEx);

				//resolve concurrency issue by retrieving only changed fields into conflicting entities
				//and try saving again
				foreach (ObjectChangeConflict changeConflict in this.Context.ChangeConflicts)
					changeConflict.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);

				this.saveRetryCount += 1;

				//retry saving changes
				this.Save();
			}
			catch (Exception ex)
			{
                Logger.Log(ex);
				return StoredProcResult.Error;
			}

			return StoredProcResult.Success;
		}

		protected ActionStatus GetDBResult(StoredProcResult spResult, string spError, DBActionType DBActionType)
		{
			var dbResult = new ActionStatus();
			string action = DBActionType.ToString().ToLower();

			switch (spResult)
			{
				case StoredProcResult.ErrChanged        :   dbResult.Message = "Failed to " + action + " because records have been changed since last view. Please reload the page."; break;
				case StoredProcResult.ErrNoRecord       :   dbResult.Message = "Failed to " + action + " because record doesn't exist."; break;
				case StoredProcResult.ErrRecExist       :   dbResult.Message = "Failed to " + action + " because the record already exists."; break;
				case StoredProcResult.ErrRecHasLink     :   dbResult.Message = "Failed to " + action + " because there are records that depend on this one."; break;
				case StoredProcResult.ErrUnknown		:	dbResult.Message = "Failed to " + action + "."; break;
				case StoredProcResult.InvalidPassword	:	dbResult.Message = "Failed to " + action + " because the password is invalid!"; break;
				case StoredProcResult.Success			:	dbResult.Message = "The data was saved successfully!"; dbResult.Success = true; break;
                default                                 :   dbResult.Message = "Failed to " + action + "."; break;
			}

			if (!String.IsNullOrWhiteSpace(spError))
				dbResult.Message += " " + spError;

			return dbResult;
		}

		protected IQueryable<M> GetListingItemsSorted(IQueryable<M> items, ListingSortModel sort)
		{
			if (!String.IsNullOrEmpty(sort.Column))
				items = sort.Asc ? items.OrderBy(sort.Column) : items.OrderByDescending(sort.Column);

			return items;
		}

		#region "Generic Methods"

		public ActionStatus AddMultipleIDs<T>(List<int> ids, Func<int, T> getEntity) where T : class
		{
			if (ids == null)
				return new ActionStatus { Success = true };

			Table<T> table = this.Context.GetTable<T>();

			foreach (var id in ids)
				table.InsertOnSubmit(getEntity(id));

			return this.GetDBResult(this.Save(), null, DBActionType.Insert);
		}

		public ActionStatus AddMultipleIDs<T>(List<string> ids, Func<string, T> getEntity) where T : class
		{
			if (ids == null)
				return new ActionStatus { Success = true };

			Table<T> table = this.Context.GetTable<T>();

			foreach (var id in ids)
				table.InsertOnSubmit(getEntity(id));

			return this.GetDBResult(this.Save(), null, DBActionType.Insert);
		}

		protected ActionStatus CallStoredProcedure(DBActionType DBActionType, Func<SPResult> save, Action afterSave = null)
		{
			StoredProcResult spResult;
			string spError = null;

			try
			{
				var dbResult = save.Invoke();
				spError = dbResult.Error;

				if (afterSave != null)
					afterSave.Invoke();

				spResult = (StoredProcResult)Enum.ToObject(typeof(StoredProcResult), dbResult.Result.Value);
			}
			catch (Exception ex)
			{
                Logger.Log(ex);

                spResult = StoredProcResult.ErrUnknown;
			}

			return this.GetDBResult(spResult, spError, DBActionType);
		}

		#endregion

		#region "Utils"

		/// <summary>
		/// Converts char into bool. Use only if the result of the query is a single entity
		/// </summary>
		protected Func<char?, bool?> CharToBool = value => value == null ? (bool?)null : value.Value.ToString().ToUpper() == "Y";

		#endregion

	}
}