private static CodeCompileUnit GenerateContextFile(string prefix, string nameSpace, DbSyncScopeDescription desc, string serviceUri) { CodeCompileUnit contextCC = new CodeCompileUnit(); CodeNamespace ctxScopeNs = new CodeNamespace(nameSpace); // Generate the outer most entity CodeTypeDeclaration wrapperEntity = new CodeTypeDeclaration( string.Format(Constants.ClientContextClassNameFormat, string.IsNullOrEmpty(prefix) ? desc.ScopeName : prefix) ); // Add SQLiteContext base type wrapperEntity.BaseTypes.Add(Constants.SQLiteContextBaseType); #region Generate the GetSchema method CodeMemberMethod getSchemaMethod = new CodeMemberMethod(); getSchemaMethod.Name = Constants.ClientIsolatedStoreGetSchemaMethodName; getSchemaMethod.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static; getSchemaMethod.ReturnType = new CodeTypeReference(Constants.SQLiteSchemaBaseType); // Add the line 'OfflineSchema schema = new OfflineSchema ()' CodeVariableDeclarationStatement initSchemaStmt = new CodeVariableDeclarationStatement(Constants.SQLiteSchemaBaseType, "schema"); initSchemaStmt.InitExpression = new CodeObjectCreateExpression(Constants.SQLiteSchemaBaseType); getSchemaMethod.Statements.Add(initSchemaStmt); #endregion // Generate the entities foreach (DbSyncTableDescription table in desc.Tables) { string tableName = CodeDomUtility.SanitizeName(table.UnquotedGlobalName); CodeTypeReference icollReference = new CodeTypeReference(typeof(IEnumerable <>)); // Generate the private field CodeTypeReference entityReference = new CodeTypeReference(tableName); icollReference.TypeArguments.Clear(); icollReference.TypeArguments.Add(entityReference); #region Add this entity to the GetSchema method CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression(); expr.Method = new CodeMethodReferenceExpression(); expr.Method.TargetObject = new CodeVariableReferenceExpression("schema"); expr.Method.MethodName = "AddCollection"; expr.Method.TypeArguments.Add(tableName); getSchemaMethod.Statements.Add(expr); #endregion } #region Add a const for the scopeName and default URL CodeMemberField scopeField = new CodeMemberField(typeof(string), "SyncScopeName"); scopeField.Attributes = MemberAttributes.Const | MemberAttributes.Private; scopeField.InitExpression = new CodePrimitiveExpression(desc.ScopeName); wrapperEntity.Members.Add(scopeField); if (serviceUri != null) { CodeMemberField urlField = new CodeMemberField(typeof(Uri), "SyncScopeUri"); urlField.Attributes = MemberAttributes.Static | MemberAttributes.Private; urlField.InitExpression = new CodeObjectCreateExpression(typeof(Uri), new CodePrimitiveExpression(serviceUri)); wrapperEntity.Members.Add(urlField); } #endregion #region Add Constructor if (serviceUri != null) { // If serviceUri is present then add constructors with just the cachePath and // cachePath with encryption algorithm specified // Add the constructor with just the cachepath CodeConstructor ctor1 = new CodeConstructor(); ctor1.Attributes = MemberAttributes.Public; ctor1.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); ctor1.ChainedConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreCallCtorWithUri)); wrapperEntity.Members.Add(ctor1); } // Add the constructor with no encryption CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Uri), Constants.ClientServiceUriArgName)); // add the optional CookieContainer parameter var cpdeCookieContainer = new CodeParameterDeclarationExpression(typeof(CookieContainer), Constants.ClientServiceCookieContainerArgName); cpdeCookieContainer.CustomAttributes.Add(new CodeAttributeDeclaration(Constants.ClientServiceCookieContainerArgAttrOptional)); cpdeCookieContainer.CustomAttributes.Add(new CodeAttributeDeclaration(Constants.ClientServiceCookieContainerArgAttrDefaultParam, new CodeAttributeArgument(new CodePrimitiveExpression(null)))); ctor.Parameters.Add(cpdeCookieContainer); ctor.BaseConstructorArgs.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeSnippetExpression(wrapperEntity.Name), Constants.ClientIsolatedStoreGetSchemaMethodName), new CodeParameterDeclarationExpression[] { })); ctor.BaseConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreBaseCtor)); wrapperEntity.Members.Add(ctor); #endregion getSchemaMethod.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression("schema"))); wrapperEntity.Members.Add(getSchemaMethod); ctxScopeNs.Types.Add(wrapperEntity); contextCC.Namespaces.Add(ctxScopeNs); return(contextCC); }
private static CodeCompileUnit GenerateEntitiesCompileUnit(string prefix, string nameSpace, DbSyncScopeDescription desc, Dictionary <string, Dictionary <string, string> > colsMappingInfo) { var cc = new CodeCompileUnit(); var scopeNs = new CodeNamespace(nameSpace); // Generate the outer most entity var wrapperEntity = new CodeTypeDeclaration( string.Format(Constants.ServiceOuterEntityNameFormat, string.IsNullOrEmpty(prefix) ? desc.ScopeName : prefix) ); wrapperEntity.CustomAttributes.Add( new CodeAttributeDeclaration(Constants.ServiceSyncScopeAttributeDefinition)); // Generate the base class for all the entities which will implement IOfflineEntity var baseEntity = CodeDomUtility.CreateIOfflineEntityCustomBaseClass( string.IsNullOrEmpty(prefix) ? desc.ScopeName : prefix, true /*isServer*/); // Set the base type // VB uses different keywords for class and interface inheritence. For it to emit the // right keyword it must inherit from object first before the actual interface. baseEntity.BaseTypes.Add(new CodeTypeReference(typeof(object))); baseEntity.BaseTypes.Add(new CodeTypeReference(Constants.ServiceIOfflineEntity)); scopeNs.Types.Add(baseEntity); // Generate the entities foreach (var table in desc.Tables) { Dictionary <string, string> curTableMapping = null; colsMappingInfo.TryGetValue(table.UnquotedGlobalName, out curTableMapping); var tableName = CodeDomUtility.SanitizeName(table.UnquotedGlobalName); var icollReference = new CodeTypeReference(typeof(ICollection <>)); // Generate the private field var entityReference = new CodeTypeReference(tableName); icollReference.TypeArguments.Clear(); icollReference.TypeArguments.Add(entityReference); var itemCollectionField = new CodeMemberField(icollReference, string.Format(Constants.EntityFieldNameFormat, tableName)); itemCollectionField.Attributes = MemberAttributes.Private; wrapperEntity.Members.Add(itemCollectionField); // Generate the actual entity var entityDecl = CodeDomUtility.GetEntityForTableDescription(table, false /*addKeyAttributes*/, curTableMapping); entityDecl.BaseTypes.Add(baseEntity.Name); var syncEntityAttributeDeclaration = new CodeAttributeDeclaration(Constants.ServiceSyncEntityAttribute, new CodeAttributeArgument("TableGlobalName", new CodeSnippetExpression("\"" + CodeDomUtility.SanitizeName(table.UnquotedGlobalName) + "\"")), // table.LocalName is quoted and contains the schema name. new CodeAttributeArgument("TableLocalName", new CodeSnippetExpression("\"" + table.LocalName + "\"")), new CodeAttributeArgument("KeyFields", new CodeSnippetExpression("\"" + String.Join(",", table.PkColumns. Select( e => CodeDomUtility.SanitizeName( GetKeyColumnName(e.UnquotedName, curTableMapping))) .ToArray()) + "\""))); // Use the PkColumns property to generate the column list for the KeyFields property. // This is important as it is used later to generate SyncId's for rows and ordering is important. entityDecl.CustomAttributes.Add(syncEntityAttributeDeclaration); scopeNs.Types.Add(entityDecl); } scopeNs.Types.Add(wrapperEntity); cc.Namespaces.Add(scopeNs); return(cc); }
private static CodeCompileUnit GenerateContextFile(string prefix, string nameSpace, DbSyncScopeDescription desc, string serviceUri) { CodeCompileUnit contextCC = new CodeCompileUnit(); CodeNamespace ctxScopeNs = new CodeNamespace(nameSpace); // Generate the outer most entity CodeTypeDeclaration wrapperEntity = new CodeTypeDeclaration( string.Format(Constants.ClientContextClassNameFormat, string.IsNullOrEmpty(prefix) ? desc.ScopeName : prefix) ); wrapperEntity.BaseTypes.Add(Constants.ClientContextBaseType); #region Generate the GetSchema method CodeMemberMethod getSchemaMethod = new CodeMemberMethod(); getSchemaMethod.Name = Constants.ClientIsolatedStoreGetSchemaMethodName; getSchemaMethod.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static; getSchemaMethod.ReturnType = new CodeTypeReference(Constants.ClientSchemaBaseType); // Add the line 'IsolatedStoreSchema schema = new IsolatedStoreSchema()' CodeVariableDeclarationStatement initSchemaStmt = new CodeVariableDeclarationStatement(Constants.ClientSchemaBaseType, "schema"); initSchemaStmt.InitExpression = new CodeObjectCreateExpression(Constants.ClientSchemaBaseType); getSchemaMethod.Statements.Add(initSchemaStmt); #endregion // Generate the entities foreach (DbSyncTableDescription table in desc.Tables) { string tableName = CodeDomUtility.SanitizeName(table.UnquotedGlobalName); CodeTypeReference icollReference = new CodeTypeReference(typeof(IEnumerable <>)); // Generate the private field CodeTypeReference entityReference = new CodeTypeReference(tableName); icollReference.TypeArguments.Clear(); icollReference.TypeArguments.Add(entityReference); #region Generate the AddXXX method. // Define the method signature as 'public void Add[Entity]([Entity] entity)' CodeMemberMethod addMethod = new CodeMemberMethod(); addMethod.Name = string.Format(Constants.ClientContextAddMethodFormat, tableName); addMethod.Parameters.Add(new CodeParameterDeclarationExpression(tableName, "entity")); addMethod.ReturnType = new CodeTypeReference(typeof(void)); addMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; //Generate the base.Add method CodeMethodInvokeExpression baseAddExpr = new CodeMethodInvokeExpression(); baseAddExpr.Method = new CodeMethodReferenceExpression(); baseAddExpr.Method.TargetObject = new CodeBaseReferenceExpression(); baseAddExpr.Method.MethodName = Constants.ClientAddMethodBodyFormat; baseAddExpr.Method.TypeArguments.Add(tableName); baseAddExpr.Parameters.Add(new CodeSnippetExpression(Constants.ClientEntityVariableName)); addMethod.Statements.Add(baseAddExpr); #endregion wrapperEntity.Members.Add(addMethod); #region Generate the DeleteXXX method. // Define the method signature as 'public void Add[Entity]([Entity] entity)' CodeMemberMethod delMethod = new CodeMemberMethod(); delMethod.Name = string.Format(Constants.ClientContextDeleteMethodFormat, tableName); delMethod.Parameters.Add(new CodeParameterDeclarationExpression(tableName, Constants.ClientEntityVariableName)); delMethod.ReturnType = new CodeTypeReference(typeof(void)); delMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; //Generate the base.Add method CodeMethodInvokeExpression baseDelExpr = new CodeMethodInvokeExpression(); baseDelExpr.Method = new CodeMethodReferenceExpression(); baseDelExpr.Method.TargetObject = new CodeBaseReferenceExpression(); baseDelExpr.Method.MethodName = Constants.ClientDeleteMethodBodyFormat; baseDelExpr.Method.TypeArguments.Add(tableName); baseDelExpr.Parameters.Add(new CodeSnippetExpression(Constants.ClientEntityVariableName)); delMethod.Statements.Add(baseDelExpr); #endregion wrapperEntity.Members.Add(delMethod); #region Generate the [Entities] property CodeMethodInvokeExpression getCollectionExpr = new CodeMethodInvokeExpression(); getCollectionExpr.Method = new CodeMethodReferenceExpression(); getCollectionExpr.Method.TargetObject = new CodeBaseReferenceExpression(); getCollectionExpr.Method.MethodName = Constants.ClientGetCollectionMethodBodyFormat; getCollectionExpr.Method.TypeArguments.Add(tableName); CodeMemberProperty getProperty = new CodeMemberProperty(); getProperty.Name = string.Format(Constants.EntityGetCollectionFormat, tableName); getProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final; getProperty.Type = icollReference; getProperty.GetStatements.Add(new CodeMethodReturnStatement(getCollectionExpr)); #endregion wrapperEntity.Members.Add(getProperty); #region Add this entity to the GetSchema method CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression(); expr.Method = new CodeMethodReferenceExpression(); expr.Method.TargetObject = new CodeVariableReferenceExpression("schema"); expr.Method.MethodName = "AddCollection"; expr.Method.TypeArguments.Add(tableName); getSchemaMethod.Statements.Add(expr); #endregion } #region Add a const for the scopeName and default URL CodeMemberField scopeField = new CodeMemberField(typeof(string), "SyncScopeName"); scopeField.Attributes = MemberAttributes.Const | MemberAttributes.Private; scopeField.InitExpression = new CodePrimitiveExpression(desc.ScopeName); wrapperEntity.Members.Add(scopeField); if (serviceUri != null) { CodeMemberField urlField = new CodeMemberField(typeof(Uri), "SyncScopeUri"); urlField.Attributes = MemberAttributes.Static | MemberAttributes.Private; urlField.InitExpression = new CodeObjectCreateExpression(typeof(Uri), new CodePrimitiveExpression(serviceUri)); wrapperEntity.Members.Add(urlField); } #endregion #region Add Constructor if (serviceUri != null) { // If serviceUri is present then add constructors with just the cachePath and // cachePath with encryption algorithm specified // Add the constructor with just the cachepath CodeConstructor ctor1 = new CodeConstructor(); ctor1.Attributes = MemberAttributes.Public; ctor1.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); ctor1.ChainedConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreCallCtorWithUri)); wrapperEntity.Members.Add(ctor1); // Add the constructor with just cache path and encryption overload CodeConstructor eCtor1 = new CodeConstructor(); eCtor1.Attributes = MemberAttributes.Public; eCtor1.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); eCtor1.Parameters.Add(new CodeParameterDeclarationExpression(Type.GetType(Constants.SymmetricAlgorithmTypeName), Constants.ClientSymmetricAlgorithmArgName)); eCtor1.ChainedConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreCallEncryptedCtorWithUri)); wrapperEntity.Members.Add(eCtor1); } // Add the constructor with no encryption CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Public; ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Uri), Constants.ClientServiceUriArgName)); ctor.BaseConstructorArgs.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeSnippetExpression(wrapperEntity.Name), Constants.ClientIsolatedStoreGetSchemaMethodName), new CodeParameterDeclarationExpression[] {})); ctor.BaseConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreBaseCtor)); wrapperEntity.Members.Add(ctor); // Add the constructor with encryption overload CodeConstructor eCtor = new CodeConstructor(); eCtor.Attributes = MemberAttributes.Public; eCtor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), Constants.ClientCachePathArgName)); eCtor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Uri), Constants.ClientServiceUriArgName)); eCtor.Parameters.Add(new CodeParameterDeclarationExpression(Type.GetType(Constants.SymmetricAlgorithmTypeName), Constants.ClientSymmetricAlgorithmArgName)); eCtor.BaseConstructorArgs.Add( new CodeMethodInvokeExpression( new CodeMethodReferenceExpression( new CodeSnippetExpression(wrapperEntity.Name), Constants.ClientIsolatedStoreGetSchemaMethodName), new CodeParameterDeclarationExpression[] { })); eCtor.BaseConstructorArgs.Add(new CodeSnippetExpression(Constants.ClientIsolatedStoreEncryptedBaseCtor)); wrapperEntity.Members.Add(eCtor); #endregion getSchemaMethod.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression("schema"))); wrapperEntity.Members.Add(getSchemaMethod); ctxScopeNs.Types.Add(wrapperEntity); contextCC.Namespaces.Add(ctxScopeNs); return(contextCC); }