Ejemplo n.º 1
0
 public void Visit(InsertIntoStatement statement, CommonTree tree)
 {
     Parent(tree).Children.Add(statement);
     SetLine(statement, tree);
     Visit(tree.GetChild(0));
     Visit(tree.GetChild(1));
 }
        private void DoInsert(InsertIntoStatement statement)
        {
            var variableArgs = VisitChild(statement.Variable);
            var domArg       = VisitChild(statement.Select);

            CodeMemberMethod method = new CodeMemberMethod();

            method.Name       = "Insert_" + domArg.MethodIdentifier;
            method.Attributes = MemberAttributes.Private;
            GenerateCallStatement(method.Statements, statement.Line.Line);

            ((Action)domArg.Tag)(); //remove call to OnSelect

            method.Statements.Add(new CodeVariableDeclarationStatement(domArg.Scope.CodeDomReference,
                                                                       "resultRows",
                                                                       domArg.CodeExpression));

            method.Statements.Add(new CodeMethodInvokeExpression(
                                      new CodeMethodReferenceExpression(variableArgs.CodeExpression, "BeforeInsert"), new CodePrimitiveExpression(statement.Overwrite)));

            var identityArgs = VisitChild(new IdentityVariable()
            {
                Id = "@@identity"
            });

            method.Statements.Add(new CodeAssignStatement(identityArgs.CodeExpression,
                                                          new CodePropertyReferenceExpression(variableArgs.CodeExpression, "RowCount")
                                                          ));

            method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", new CodeTypeReference("ResultRow")),
                                                                       "x",
                                                                       new CodeMethodInvokeExpression(
                                                                           new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("resultRows"), "GetEnumerator",
                                                                                                             null))));


            var loop = new CodeIterationStatement();

            loop.InitStatement      = new CodeSnippetStatement();
            loop.IncrementStatement = new CodeSnippetStatement();
            loop.TestExpression     = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("x"), "MoveNext",
                                                  null));


            loop.Statements.Add(new CodeAssignStatement(identityArgs.CodeExpression,
                                                        new CodeBinaryOperatorExpression(identityArgs.CodeExpression,
                                                                                         CodeBinaryOperatorType.Add,
                                                                                         new CodePrimitiveExpression(1))
                                                        ));


            loop.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("ResultRow"),
                                                                     "row",
                                                                     new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("x"), "Current")));

            loop.Statements.Add(new CodeVariableDeclarationStatement(
                                    new CodeTypeReference(statement.Variable.Id),
                                    "tableRow",
                                    new CodeObjectCreateExpression(new CodeTypeReference(statement.Variable.Id))));

            ScopeData <TableDescriptor> descriptor = Scope.EmptyTableDescriptor;

            if (Scope.Current.IsTableRegistered(statement.Variable.Id))
            {
                descriptor = Scope.Current.GetTableDescriptor(statement.Variable.Id);
            }

            int insertCount = descriptor.Type.Variables.Where(x => !x.Primitive.IsIdentity).Count();

            if (insertCount != statement.Select.Args.Length) //lengths don't match for insert. Need to remove identities
            {
                Errors.Add(new InsertSelectArgsNotEqual(new Semantic.LineInfo(statement.Line.Line, statement.Line.CharacterPosition)));
            }

            int indexer = 0;

            for (int x = 0; x < descriptor.Type.Variables.Count; x++)
            {
                var            left  = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("tableRow"), descriptor.Type.Variables[x].Variable);
                CodeExpression right = null;
                if (descriptor.Type.Variables[x].Primitive.IsIdentity)
                {
                    right = identityArgs.CodeExpression;
                    loop.Statements.Add(new CodeAssignStatement(left, right));
                }
                else
                {
                    var indexExpression = new CodeIndexerExpression(new CodeTypeReferenceExpression("row"), new CodeSnippetExpression(indexer.ToString()));
                    right = descriptor.Type.Variables[x].Primitive.ToNative(indexExpression);

                    loop.Statements.Add(new CodeAssignStatement(left, new CodePrimitiveExpression(null)));
                    var assignCondition = new CodeConditionStatement(
                        new CodeBinaryOperatorExpression(indexExpression,
                                                         CodeBinaryOperatorType.IdentityInequality,
                                                         new CodePrimitiveExpression(null)), new CodeAssignStatement(left, right));

                    loop.Statements.Add(assignCondition);
                    indexer++;
                }
            }


            loop.Statements.Add(new CodeMethodInvokeExpression(
                                    new CodeMethodReferenceExpression(variableArgs.CodeExpression, "Add"),
                                    new CodeVariableReferenceExpression("tableRow")));


            method.Statements.Add(loop);
            _mainType.Type.Members.Add(method);

            var methodcall = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(null, method.Name));

            method.Statements.Add(new CodeMethodInvokeExpression(
                                      new CodeMethodReferenceExpression(variableArgs.CodeExpression, "AfterInsert")));

            _codeStack.Peek().ParentStatements.Add(methodcall);
            _codeStack.Peek().CodeExpression = methodcall;
        }
 public void Visit(InsertIntoStatement statement)
 {
     DoInsert(statement);
 }