fcf.module({
  name: "fcf:tests/memoryConnection.js",
  dependencies: ["fcf:NTest/uniTest.js", "fcf:NFSQL/Storage.js", "fcf:NFSQL/Projections.js", "fcf:NFSQL/NTests/NDB/NDB.js", "fcf:NFSQL/NDetails/NConnections/MemoryConnection.js"],
  module: function(uniTest, Storage, Projections, NDB, MemoryConnection) {
    uniTest.add("002 DB" , "MemoryConnection", function(a_tester) {
      var projections = new Projections();
      projections.appendProjectionStruct({
        alias:  "test",
        table:  "test",
        key:    "id",
        fields:[
          {
            alias: 'id',
            field: 'id',
            type: 'int',
            autoincrement: true,
            notAdd: true,
            notEdit: true,
          },
          {
            alias: 'name',
            field: 'name',
            type:  'string',
          },
          {
            alias: 'value',
            field: 'value',
            type:  'int',
          },
          {
            alias: 'ref',
            field: 'ref',
            type:  'int',
          },

        ]
      });
      projections.appendProjectionStruct({
        alias:  "refs",
        table:  "refs",
        key:    "id",
        fields:[
          {
            alias: 'id',
            field: 'id',
            type: 'int',
            autoincrement: true,
            notAdd: true,
            notEdit: true,
          },
          {
            alias: 'name',
            field: 'name',
            type:  'string',
          },
        ]
      });

      var tables = {
        test: [
          { id: 1,  name: "first",  value: 12, ref: 2 },
          { id: 2,  name: "second", value: 1234, ref: 4  },
          { id: 3,  name: "ball",   value: 84, ref: 1 },
          { id: 4,  name: "star",   value: 85, ref: 3 },
          { id: 5,  name: "earth",  value: 527, ref: 2 },
          { id: 6,  name: "001",    value: 487, ref: 4 },
          { id: 7,  name: "map",    value: 83, ref: 1 },
          { id: 8,  name: "cat",    value: 837, ref: 3 },
          { id: 9,  name: "test",   value: 72905, ref: 5 },
          { id: 10, name: "some",   value: 4856, ref: 1 },
        ],
        refs: [
          { id: 1, name: "link_earth" },
          { id: 2, name: "link_moon" },
          { id: 3, name: "link_tree" },
          { id: 4, name: "link_doom" },
          { id: 5, name: "link_word" },
        ]
      };

      var mc = new MemoryConnection({
                projections: projections,
                tables:      tables});



      var storage = new Storage({
        projections: projections,
        defaultConnection: "default",
        connections: {
          default: {
            type: "memory",
            projections: projections,
            tables:      tables }
          }
        },
      );

      mc.query({
        query: { type: "select", from: "test", fields: [{field: "name"}, {field: "value"}, {field: "id"}],
          where: [ {type: "=", args: [{field: "id"}, {value: 2}] } ],
          },
        },
        function(a_error, a_data){
          uniTest.equal(a_data, [ { "id": 2, "name": "second", "value": 1234 } ]);
        }
      );

      mc.query({
        query: { type: "select", from: "test", fields: [{field: "name"}, {field: "value"}, {field: "id"}],
          where: [
                   {logic: "and", type: "=", args: [{field: "value"}, {value: 1234}] },
                   {logic: "or", type: "block", args: [
                      {logic: "and", type: ">=", args: [{field: "value"}, {value: 12}] },
                      {logic: "and", type: "<=", args: [{field: "value"}, {value: 85}] },
                   ]}
                 ],
          offset: 1, limit: 2,
          },
        },
        function(a_error, a_data){
          uniTest.equal(a_data, [ { "id": 2, "name": "second", "value": 1234 },
                                   { "id": 3, "name": "ball", "value": 84 } ]);
        }
      );

      mc.query({
        query: { type: "select",
            from: "test",
            fields: [{field: "name"}, {field: "value"}, {field: "id"}],
            order: [ {field: "id", order: "desc" },  ],
            limit: 2,
          },
        },
        function(a_error, a_data){
          uniTest.equal(a_data, [ { "id": 2, "name": "second", "value": 1234 },
                                   { "id": 1, "name": "first", "value": 12 } ]);
        }
      );

      mc.query({
        query: { type: "select",
          from: "test",
          fields: [{field: "name", as: "nm"}, {field: "value", as: "n"}],
          limit: 2,
          },
        },
        function(a_error, a_data) {
          uniTest.equal(a_data, [ { "nm": "first", "n": 12 }, { "nm": "second", "n": 1234 }]);
        }
      );

      mc.query({
        query: {
          type: "select",
          from: "test",
          fields: [{field: "name", as: "nm"}, {field: "value"}, {field: "name", from: "refs"}],
          join: [{
            join: "left",
            from: "refs",
            on: [ { logic: "and", type: "=", args: [ {from: "refs", field: "id"}, {from: "test", field: "ref"} ] }, ],
          }],
          limit: 2,
          },
        },
        function(a_error, a_data) {
          uniTest.equal(
            a_data,
            [
              { "nm": "first", "value": 12, "refs.name": "link_moon" },
              { "nm": "second", "value": 1234, "refs.name": "link_doom" }
            ]
          );
        }
      );

      mc.query({
        query: { type: "select",
          from: "test",
          fields: [{field: "name", as: "nm"}, {field: "value"}, {field: "name", from: "refs"}],
          join: [{
            join: "left",
            from: "refs",
            on: [ { logic: "and", type: "=", args: [ {from: "refs", field: "id"}, {from: "test", field: "ref"} ] }, ],
          }],
          where: [{ type: "=", args: [{field: "name", from: "refs"}, {value: "link_word"}] }]
          },
        },
        function(a_error, a_data) {
          uniTest.equal(
            a_data,
            [ {
              "nm": "test",
              "value": 72905,
              "refs.name": "link_word"
            } ]
          );
        }
      );

      mc.query({
        query: { type: "select",
          from: "test",
          fields: [{field: "name", as: "nm"}, {field: "value"}, {field: "name", from: "join", as: "joinfield"}],
          join: [{
            join: "left",
            from: "refs",
            as:   "join",
            on: [ { logic: "and", type: "=", args: [ {from: "join", field: "id"}, {field: "ref"} ] }, ],
          }],
          limit: 2,
          },
        },
        function(a_error, a_data) {
          uniTest.equal(
            a_data,
            [ {
                "nm": "first",
                "value": 12,
                "joinfield": "link_moon"
              },
              {
                "nm": "second",
                "value": 1234,
                "joinfield": "link_doom"
              }]
          );
        }
      );

      mc.query({
        query: { type: "select",
          from: "test",
          fields: [{field: "name", as: "nm"}, {function: "concat", args: [{value: "-"}, {field: "name"},{value: "+"}]}],
          join: [{
            join: "left",
            from: "refs",
            as:   "join",
            on: [ { logic: "and", type: "=", args: [ {from: "join", field: "id"}, {field: "ref"} ] }, ],
          }],
          limit: 2,
          },
        },
        function(a_error, a_data) {
          uniTest.equal(a_data, [ { "nm": "first", "concat()": "-first+" }, { "nm": "second", "concat()": "-second+" } ]);
        }
      );

      mc.query({
        query: { type: "select",
          from: "test",
          fields: [{function: "count", args: [{field: "*"}], as: "size"}],
          join: [{
            join: "left",
            from: "refs",
            as:   "join",
            on: [ { logic: "and", type: "=", args: [ {from: "join", field: "id"}, {field: "ref"} ] }, ],
          }],
          limit: 2,
          },
        },
        function(a_error, a_data) {
          uniTest.equal(a_data, [ { "size": 2 } ]);
        }
      );

      storage.query({ query: "SELECT name FROM test WHERE name=${1}", args: ["second"] }, function(a_error, a_data){
        uniTest.equal(a_data, [ [ { "name": "second" } ] ] );
      });

      storage.query({ query: "SELECT name FROM test LIMIT ${2} OFFSET ${1}", args: [1, 2]}, function(a_error, a_data){
        uniTest.equal(a_data, [ [ { "name": "second" }, { "name": "ball" } ] ] );
      });

    });
  }
});
