Beispiel #1
0
        public Object SetScopeDatabase(String type, String id)
        {
            var t = Type.GetType(type);

            if (t == null)
            {
                t = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType(typeof(IdentifiedData).Assembly.FullName, type);
            }
            if (t == null)
            {
                t = typeof(Int32).Assembly.ExportedTypes.FirstOrDefault(o => o.Namespace == "System" && o.Name == type);
                if (t == null)
                {
                    throw new MissingMethodException(type, (string)null);
                }
            }

            var idp = typeof(IDataPersistenceService <>).MakeGenericType(t);
            var ids = ApplicationContext.Current.GetService(idp) as IDataPersistenceService;

            if (ids == null)
            {
                throw new InvalidOperationException($"Persistence service for {type} not found");
            }

            Guid gd = Guid.Parse(id);

            return(ids.Get(gd));
        }
Beispiel #2
0
        public object SetScopeXmlFile(String type, String file)
        {
            var filePath = file;

            if (!Path.IsPathRooted(filePath))
            {
                filePath = Path.Combine(this.m_workingDirectory, file);
            }

            var t = Type.GetType(type);

            if (t == null)
            {
                t = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType(typeof(IdentifiedData).Assembly.FullName, type);
            }
            if (t == null)
            {
                t = typeof(Int32).Assembly.ExportedTypes.FirstOrDefault(o => o.Namespace == "System" && o.Name == type);
                if (t == null)
                {
                    throw new MissingMethodException(type, (string)null);
                }
            }

            XmlSerializer xsz = new XmlSerializer(t);

            using (var fs = File.OpenRead(filePath))
                return(xsz.Deserialize(fs));
        }
Beispiel #3
0
        public virtual object SetScope(String type, String data)
        {
            var t = Type.GetType(type);

            if (t == null)
            {
                t = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType(typeof(IdentifiedData).Assembly.FullName, type);
            }
            if (t == null)
            {
                t = typeof(Int32).Assembly.ExportedTypes.FirstOrDefault(o => o.Namespace == "System" && o.Name == type);
                if (t == null)
                {
                    throw new MissingMethodException(type, (string)null);
                }
                object res = null;
                if (!MapUtil.TryConvert(data, t, out res))
                {
                    throw new ArgumentOutOfRangeException(nameof(data));
                }
                return(res);
            }
            else
            {
                return(JsonConvert.DeserializeObject(data, t, new JsonSerializerSettings()
                {
                    Binder = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder(),
                    TypeNameAssemblyFormat = 0,
                    TypeNameHandling = TypeNameHandling.All
                }));
            }
        }
Beispiel #4
0
        public void ExecuteStepRule(String @event, string cast)
        {
            var t = Type.GetType(cast);

            if (t == null)
            {
                t = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType(typeof(IdentifiedData).Assembly.FullName, cast);
            }
            if (t == null)
            {
                throw new ArgumentOutOfRangeException(nameof(cast));
            }
            this.ExecuteRule(@event, false, t);
        }
Beispiel #5
0
        /// <summary>
        /// Invoke raw
        /// </summary>
        public object InvokeRaw(String action, Object data)
        {
            lock (s_syncLock)
                try
                {
                    var binder = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder();

                    var sdata = data as IDictionary <String, Object>;
                    if (sdata == null || !sdata.ContainsKey("$type"))
                    {
                        return(data);
                    }

                    var callList = this.GetCallList(binder.BindToType("OpenIZ.Core.Model, Version=1.0.0.0", sdata["$type"].ToString()), action);
                    var retVal   = data;

                    if (callList.Count > 0)
                    {
                        foreach (var c in callList)
                        {
                            data = c(data);
                        }
                    }

                    return(data);
                }
                catch (JavaScriptException e)
                {
                    this.m_tracer.TraceError("JAVASCRIPT ERROR RUNNING {0} OBJECT :::::> {3}@{2}\r\n{1}", action, this.ProduceLiteral(data), e.LineNumber, e);
                    throw new DetectedIssueException(new List <DetectedIssue>()
                    {
                        new DetectedIssue()
                        {
                            Priority = DetectedIssuePriorityType.Error,
                            Text     = $"{e.Error.ToString()} @ {e.Location.Start.Line} - {e.Location.End.Line}"
                        }
                    });
                }
            catch (Exception e)
            {
                this.m_tracer.TraceError("Error running {0} for {1} : {2}", action, this.ProduceLiteral(data), e);
                throw new BusinessRulesExecutionException($"Error running business rule {action} for {this.ProduceLiteral(data)} - {e.Message}", e);
            }
        }
Beispiel #6
0
        public Object SetScopeDatabaseQuery(String type, String qry, String skip, String take)
        {
            var t = Type.GetType(type);

            if (t == null)
            {
                t = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType(typeof(IdentifiedData).Assembly.FullName, type);
            }
            if (t == null)
            {
                t = typeof(Int32).Assembly.ExportedTypes.FirstOrDefault(tr => tr.Namespace == "System" && tr.Name == type);
                if (t == null)
                {
                    throw new MissingMethodException(type, (string)null);
                }
            }

            var idp = typeof(IDataPersistenceService <>).MakeGenericType(t);
            var ids = ApplicationContext.Current.GetService(idp) as IDataPersistenceService;

            if (ids == null)
            {
                throw new InvalidOperationException($"Persistence service for {type} not found");
            }

            var mi = typeof(QueryExpressionParser).GetGenericMethod("BuildLinqExpression", new Type[] { t }, new Type[] { typeof(NameValueCollection) });
            var qd = mi.Invoke(null, new object[] { NameValueCollection.ParseQueryString(qry) }) as Expression;

            int?o = String.IsNullOrEmpty(skip) ? 0 : Int32.Parse(skip),
               c  = String.IsNullOrEmpty(take) ? (int?)null : Int32.Parse(take);

            Console.WriteLine("INF: {0} where {1} ({2}..{3})", type, qd, o, c);
            int tc     = 0;
            var retVal = ids.Query(qd, o.Value, c, out tc);

            Console.WriteLine("INF: {0} set to scope", tc);
            return(retVal);
        }
Beispiel #7
0
        /// <summary>
        /// Query query
        /// </summary>
        /// <param name="query"></param>
        public SqlStatement CreateQuery <TModel>(IEnumerable <KeyValuePair <String, Object> > query, String tablePrefix, params ColumnMapping[] selector)
        {
            var tableType = m_mapper.MapModelType(typeof(TModel));
            var tableMap  = TableMapping.Get(tableType);
            List <TableMapping> scopedTables = new List <TableMapping>()
            {
                tableMap
            };

            bool         skipParentJoin  = true;
            SqlStatement selectStatement = null;
            KeyValuePair <SqlStatement, List <TableMapping> > cacheHit;

            if (!s_joinCache.TryGetValue($"{tablePrefix}.{typeof(TModel).Name}", out cacheHit))
            {
                selectStatement = new SqlStatement(this.m_provider, $" FROM {tableMap.TableName} AS {tablePrefix}{tableMap.TableName} ");

                Stack <TableMapping> fkStack = new Stack <TableMapping>();
                fkStack.Push(tableMap);

                List <JoinFilterAttribute> joinFilters = new List <JoinFilterAttribute>();

                // Always join tables?
                do
                {
                    var dt = fkStack.Pop();
                    foreach (var jt in dt.Columns.Where(o => o.IsAlwaysJoin))
                    {
                        var fkTbl = TableMapping.Get(jt.ForeignKey.Table);
                        var fkAtt = fkTbl.GetColumn(jt.ForeignKey.Column);
                        selectStatement.Append($"INNER JOIN {fkAtt.Table.TableName} AS {tablePrefix}{fkAtt.Table.TableName} ON ({tablePrefix}{jt.Table.TableName}.{jt.Name} = {tablePrefix}{fkAtt.Table.TableName}.{fkAtt.Name} ");

                        foreach (var flt in jt.JoinFilters.Union(joinFilters).GroupBy(o => o.PropertyName).ToArray())
                        {
                            var fltCol = fkTbl.GetColumn(flt.Key);
                            if (fltCol == null)
                            {
                                joinFilters.AddRange(flt);
                            }
                            else
                            {
                                selectStatement.And($"({String.Join(" OR ", flt.Select(o => $"{tablePrefix}{fltCol.Table.TableName}.{fltCol.Name} = '{o.Value}'"))})");
                                joinFilters.RemoveAll(o => flt.Contains(o));
                            }
                        }

                        selectStatement.Append(")");
                        if (!scopedTables.Contains(fkTbl))
                        {
                            fkStack.Push(fkTbl);
                        }
                        scopedTables.Add(fkAtt.Table);
                    }
                } while (fkStack.Count > 0);

                // Add the heavy work to the cache
                lock (s_joinCache)
                    if (!s_joinCache.ContainsKey($"{tablePrefix}.{typeof(TModel).Name}"))
                    {
                        s_joinCache.Add($"{tablePrefix}.{typeof(TModel).Name}", new KeyValuePair <SqlStatement, List <TableMapping> >(selectStatement.Build(), scopedTables));
                    }
            }
            else
            {
                selectStatement = cacheHit.Key.Build();
                scopedTables    = cacheHit.Value;
            }

            // Column definitions
            var columnSelector = selector;

            if (selector == null || selector.Length == 0)
            {
                selectStatement = new SqlStatement(this.m_provider, $"SELECT * ").Append(selectStatement);
                // columnSelector = scopedTables.SelectMany(o => o.Columns).ToArray();
            }
            else
            {
                var columnList = String.Join(",", columnSelector.Select(o =>
                {
                    var rootCol     = tableMap.GetColumn(o.SourceProperty);
                    skipParentJoin &= rootCol != null;
                    if (skipParentJoin)
                    {
                        return($"{tablePrefix}{rootCol.Table.TableName}.{rootCol.Name}");
                    }
                    else
                    {
                        return($"{tablePrefix}{o.Table.TableName}.{o.Name}");
                    }
                }));
                selectStatement = new SqlStatement(this.m_provider, $"SELECT {columnList} ").Append(selectStatement);
            }

            // We want to process each query and build WHERE clauses - these where clauses are based off of the JSON / XML names
            // on the model, so we have to use those for the time being before translating to SQL
            List <KeyValuePair <String, Object> > workingParameters = new List <KeyValuePair <string, object> >(query);

            // Where clause
            SqlStatement        whereClause   = new SqlStatement(this.m_provider);
            List <SqlStatement> cteStatements = new List <SqlStatement>();

            // Construct
            while (workingParameters.Count > 0)
            {
                var parm = workingParameters.First();
                workingParameters.RemoveAt(0);

                // Match the regex and process
                var propertyPredicate = QueryPredicate.Parse(parm.Key);
                if (propertyPredicate == null)
                {
                    throw new ArgumentOutOfRangeException(parm.Key);
                }

                // Next, we want to construct the other parms
                var otherParms = workingParameters.Where(o => QueryPredicate.Parse(o.Key).Path == propertyPredicate.Path).ToArray();

                // Remove the working parameters if the column is FK then all parameters
                if (otherParms.Any() || !String.IsNullOrEmpty(propertyPredicate.Guard) || !String.IsNullOrEmpty(propertyPredicate.SubPath))
                {
                    foreach (var o in otherParms)
                    {
                        workingParameters.Remove(o);
                    }

                    // We need to do a sub query

                    IEnumerable <KeyValuePair <String, Object> > queryParms = new List <KeyValuePair <String, Object> >()
                    {
                        parm
                    }.Union(otherParms);

                    // Grab the appropriate builder
                    var subProp = typeof(TModel).GetXmlProperty(propertyPredicate.Path, true);
                    if (subProp == null)
                    {
                        throw new MissingMemberException(propertyPredicate.Path);
                    }

                    // Link to this table in the other?
                    // Is this a collection?
                    if (typeof(IList).IsAssignableFrom(subProp.PropertyType)) // Other table points at this on
                    {
                        var propertyType = subProp.PropertyType.StripGeneric();
                        // map and get ORM def'n
                        var subTableType = m_mapper.MapModelType(propertyType);
                        var subTableMap  = TableMapping.Get(subTableType);
                        var linkColumns  = subTableMap.Columns.Where(o => scopedTables.Any(s => s.OrmType == o.ForeignKey?.Table));
                        //var linkColumn = linkColumns.Count() > 1 ? linkColumns.FirstOrDefault(o=>o.SourceProperty.Name == "SourceKey") : linkColumns.FirstOrDefault();
                        var linkColumn = linkColumns.Count() > 1 ? linkColumns.FirstOrDefault(o => propertyPredicate.SubPath.StartsWith("source") ? o.SourceProperty.Name != "SourceKey" : o.SourceProperty.Name == "SourceKey") : linkColumns.FirstOrDefault();

                        // Link column is null, is there an assoc attrib?
                        SqlStatement subQueryStatement = new SqlStatement(this.m_provider);

                        var    subTableColumn = linkColumn;
                        string existsClause   = String.Empty;

                        if (linkColumn == null)
                        {
                            var tableWithJoin = scopedTables.Select(o => o.AssociationWith(subTableMap)).FirstOrDefault(o => o != null);
                            linkColumn = tableWithJoin.Columns.SingleOrDefault(o => scopedTables.Any(s => s.OrmType == o.ForeignKey?.Table));
                            var targetColumn = tableWithJoin.Columns.SingleOrDefault(o => o.ForeignKey.Table == subTableMap.OrmType);
                            subTableColumn = subTableMap.GetColumn(targetColumn.ForeignKey.Column);
                            // The sub-query statement needs to be joined as well
                            var lnkPfx = IncrementSubQueryAlias(tablePrefix);
                            subQueryStatement.Append($"SELECT {lnkPfx}{tableWithJoin.TableName}.{linkColumn.Name} FROM {tableWithJoin.TableName} AS {lnkPfx}{tableWithJoin.TableName} WHERE ");
                            existsClause = $"{lnkPfx}{tableWithJoin.TableName}.{targetColumn.Name}";
                            //throw new InvalidOperationException($"Cannot find foreign key reference to table {tableMap.TableName} in {subTableMap.TableName}");
                        }

                        var localTable = scopedTables.Where(o => o.GetColumn(linkColumn.ForeignKey.Column) != null).FirstOrDefault();

                        if (String.IsNullOrEmpty(existsClause))
                        {
                            existsClause = $"{tablePrefix}{localTable.TableName}.{localTable.GetColumn(linkColumn.ForeignKey.Column).Name}";
                        }

                        var guardConditions = queryParms.GroupBy(o => QueryPredicate.Parse(o.Key).Guard);

                        int nGuards = 0;
                        foreach (var guardClause in guardConditions)
                        {
                            var subQuery = guardClause.Select(o => new KeyValuePair <String, Object>(QueryPredicate.Parse(o.Key).SubPath, o.Value)).ToList();

                            // TODO: GUARD CONDITION HERE!!!!
                            if (!String.IsNullOrEmpty(guardClause.Key))
                            {
                                StringBuilder guardCondition = new StringBuilder();
                                var           clsModel       = propertyType;
                                while (clsModel.GetCustomAttribute <ClassifierAttribute>() != null)
                                {
                                    var clsProperty = clsModel.GetRuntimeProperty(clsModel.GetCustomAttribute <ClassifierAttribute>().ClassifierProperty);
                                    clsModel = clsProperty.PropertyType.StripGeneric();
                                    var redirectProperty = clsProperty.GetCustomAttribute <SerializationReferenceAttribute>()?.RedirectProperty;
                                    if (redirectProperty != null)
                                    {
                                        clsProperty = clsProperty.DeclaringType.GetRuntimeProperty(redirectProperty);
                                    }

                                    guardCondition.Append(clsProperty.GetCustomAttributes <XmlElementAttribute>().First().ElementName);
                                    if (typeof(IdentifiedData).IsAssignableFrom(clsModel))
                                    {
                                        guardCondition.Append(".");
                                    }
                                }
                                subQuery.Add(new KeyValuePair <string, object>(guardCondition.ToString(), guardClause.Key.Split('|')));

                                // Filter by effective version
                                if (typeof(IVersionedAssociation).IsAssignableFrom(clsModel))
                                {
                                    subQuery.Add(new KeyValuePair <string, object>("obsoleteVersionSequence", new String[] { "null" }));
                                }
                            }

                            // Generate method
                            var prefix    = IncrementSubQueryAlias(tablePrefix);
                            var genMethod = typeof(QueryBuilder).GetGenericMethod("CreateQuery", new Type[] { propertyType }, new Type[] { subQuery.GetType(), typeof(String), typeof(ColumnMapping[]) });
                            subQueryStatement.And($" {existsClause} IN (");
                            nGuards++;
                            existsClause = $"{prefix}{subTableColumn.Table.TableName}.{subTableColumn.Name}";
                            subQueryStatement.Append(genMethod.Invoke(this, new Object[] { subQuery, prefix, new ColumnMapping[] { subTableColumn } }) as SqlStatement);
                        }

                        // Unwind guards
                        while (nGuards-- > 0)
                        {
                            subQueryStatement.Append(")");
                        }

                        if (subTableColumn != linkColumn)
                        {
                            whereClause.And($"{tablePrefix}{localTable.TableName}.{localTable.GetColumn(linkColumn.ForeignKey.Column).Name} IN (").Append(subQueryStatement).Append(")");
                        }
                        else
                        {
                            whereClause.And(subQueryStatement);
                        }
                    }
                    else if (!this.m_hacks.Any(o => o.HackQuery(this, selectStatement, whereClause, subProp, tablePrefix, propertyPredicate, parm.Value, scopedTables))) // this table points at other
                    {
                        var subQuery = queryParms.Select(o => new KeyValuePair <String, Object>(QueryPredicate.Parse(o.Key).SubPath, o.Value)).ToList();

                        if (!subQuery.Any(o => o.Key == "obsoletionTime") && typeof(IBaseEntityData).IsAssignableFrom(subProp.PropertyType))
                        {
                            subQuery.Add(new KeyValuePair <string, object>("obsoletionTime", "null"));
                        }

                        TableMapping tableMapping = null;
                        var          subPropKey   = typeof(TModel).GetXmlProperty(propertyPredicate.Path);

                        // Get column info
                        PropertyInfo  domainProperty = scopedTables.Select(o => { tableMapping = o; return(m_mapper.MapModelProperty(typeof(TModel), o.OrmType, subPropKey)); })?.FirstOrDefault(o => o != null);
                        ColumnMapping linkColumn     = null;
                        // If the domain property is not set, we may have to infer the link
                        if (domainProperty == null)
                        {
                            var subPropType = m_mapper.MapModelType(subProp.PropertyType);
                            // We find the first column with a foreign key that points to the other !!!
                            linkColumn = scopedTables.SelectMany(o => o.Columns).FirstOrDefault(o => o.ForeignKey?.Table == subPropType);
                        }
                        else
                        {
                            linkColumn = tableMapping.GetColumn(domainProperty);
                        }

                        var fkTableDef  = TableMapping.Get(linkColumn.ForeignKey.Table);
                        var fkColumnDef = fkTableDef.GetColumn(linkColumn.ForeignKey.Column);

                        // Create the sub-query
                        //var genMethod = typeof(QueryBuilder).GetGenericMethod("CreateQuery", new Type[] { subProp.PropertyType }, new Type[] { subQuery.GetType(), typeof(ColumnMapping[]) });
                        //SqlStatement subQueryStatement = genMethod.Invoke(this, new Object[] { subQuery, new ColumnMapping[] { fkColumnDef } }) as SqlStatement;
                        SqlStatement subQueryStatement = null;
                        if (String.IsNullOrEmpty(propertyPredicate.CastAs))
                        {
                            var genMethod = typeof(QueryBuilder).GetGenericMethod("CreateQuery", new Type[] { subProp.PropertyType }, new Type[] { subQuery.GetType(), typeof(ColumnMapping[]) });
                            subQueryStatement = genMethod.Invoke(this, new Object[] { subQuery, new ColumnMapping[] { fkColumnDef } }) as SqlStatement;
                        }
                        else // we need to cast!
                        {
                            var castAsType = new OpenIZ.Core.Model.Serialization.ModelSerializationBinder().BindToType("OpenIZ.Core.Model", propertyPredicate.CastAs);

                            var genMethod = typeof(QueryBuilder).GetGenericMethod("CreateQuery", new Type[] { castAsType }, new Type[] { subQuery.GetType(), typeof(ColumnMapping[]) });
                            subQueryStatement = genMethod.Invoke(this, new Object[] { subQuery, new ColumnMapping[] { fkColumnDef } }) as SqlStatement;
                        }
                        cteStatements.Add(new SqlStatement(this.m_provider, $"{tablePrefix}cte{cteStatements.Count} AS (").Append(subQueryStatement).Append(")"));
                        //subQueryStatement.And($"{tablePrefix}{tableMapping.TableName}.{linkColumn.Name} = {sqName}{fkTableDef.TableName}.{fkColumnDef.Name} ");

                        whereClause.And($"{tablePrefix}{tableMapping.TableName}.{linkColumn.Name} IN (SELECT {tablePrefix}cte{cteStatements.Count - 1}.{fkColumnDef.Name} FROM {tablePrefix}cte{cteStatements.Count - 1})");
                    }
                }
                else
                {
                    whereClause.And(CreateWhereCondition(typeof(TModel), propertyPredicate.Path, parm.Value, tablePrefix, scopedTables));
                }
            }

            // Return statement
            SqlStatement retVal = new SqlStatement(this.m_provider);

            if (cteStatements.Count > 0)
            {
                retVal.Append("WITH ");
                foreach (var c in cteStatements)
                {
                    retVal.Append(c);
                    if (c != cteStatements.Last())
                    {
                        retVal.Append(",");
                    }
                }
            }
            retVal.Append(selectStatement.Where(whereClause));

            return(retVal);
        }